diff --git a/app/assets/stylesheets/_global.css b/app/assets/stylesheets/_global.css
index 561d78640..24e5b8727 100644
--- a/app/assets/stylesheets/_global.css
+++ b/app/assets/stylesheets/_global.css
@@ -10,7 +10,7 @@
--block-space-double: calc(var(--block-space) * 2);
/* Text */
- --font-sans: "Adwaita Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
+ --font-sans: "Adwaita Sans", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Fizzy", "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
--font-serif: ui-serif, serif;
--font-mono: ui-monospace, monospace;
diff --git a/app/assets/stylesheets/comments.css b/app/assets/stylesheets/comments.css
index c8453bc14..2ae664dcd 100644
--- a/app/assets/stylesheets/comments.css
+++ b/app/assets/stylesheets/comments.css
@@ -4,7 +4,7 @@
--comment-padding-block: var(--block-space-half);
--comment-padding-inline: var(--inline-space-double);
--comment-max: 70ch;
- --reaction-size: 1.6875rem;
+ --reaction-size: 2rem;
display: flex;
flex-direction: column;
@@ -15,6 +15,10 @@
@media (min-width: 160ch) {
padding-inline: var(--tray-size);
}
+
+ @media (min-width: 640px) {
+ --reaction-size: 1.6875rem;
+ }
}
.comments__subscribers {
diff --git a/app/assets/stylesheets/filters.css b/app/assets/stylesheets/filters.css
index 082fcf2fc..efc04e21d 100644
--- a/app/assets/stylesheets/filters.css
+++ b/app/assets/stylesheets/filters.css
@@ -19,6 +19,7 @@
--input-background: var(--color-canvas);
}
+ &:has(dialog[open]),
&:has([data-controller~="tooltip"]:hover) {
z-index: calc(var(--z-nav) + 1);
}
diff --git a/app/assets/stylesheets/font-face.css b/app/assets/stylesheets/font-face.css
new file mode 100644
index 000000000..086111ed4
--- /dev/null
+++ b/app/assets/stylesheets/font-face.css
@@ -0,0 +1,41 @@
+@layer base {
+ /*
+ Segoe UI Variable Fizzy font face configuration.
+
+ 1. Segoe UI Variable (Weights 100-700):
+ Leverages variable font features to:
+ - Automatically adjust Weight (wght) dynamically within the 100-700 range.
+ - Automatically manage Optical Size (opsz) based on font-size.
+
+ 2. Segoe UI Black (Weights 800-900):
+ Used as a fallback because Segoe UI Variable does not natively support 900 weight.
+ This ensures a consistent bold experience across all weights.
+ */
+ @font-face {
+ font-family: "Segoe UI Variable Fizzy";
+ src: local("Segoe UI Variable");
+ font-weight: 100 700;
+ font-style: normal;
+ }
+
+ @font-face {
+ font-family: "Segoe UI Variable Fizzy";
+ src: local("Segoe UI Variable");
+ font-weight: 100 700;
+ font-style: italic;
+ }
+
+ @font-face {
+ font-family: "Segoe UI Variable Fizzy";
+ src: local("Segoe UI Black");
+ font-weight: 800 900;
+ font-style: normal;
+ }
+
+ @font-face {
+ font-family: "Segoe UI Variable Fizzy";
+ src: local("Segoe UI Black Italic");
+ font-weight: 800 900;
+ font-style: italic;
+ }
+}
diff --git a/app/assets/stylesheets/popup.css b/app/assets/stylesheets/popup.css
index 189cfef5b..02ae8969e 100644
--- a/app/assets/stylesheets/popup.css
+++ b/app/assets/stylesheets/popup.css
@@ -155,6 +155,10 @@
max-inline-size: 100%;
padding: var(--inline-space-half) var(--popup-item-padding-inline);
text-align: start;
+
+ &:focus-visible {
+ z-index: 1;
+ }
}
.popup__icon {
diff --git a/app/assets/stylesheets/reactions.css b/app/assets/stylesheets/reactions.css
index 5dea448cc..d1cd0a03f 100644
--- a/app/assets/stylesheets/reactions.css
+++ b/app/assets/stylesheets/reactions.css
@@ -10,7 +10,7 @@
flex-wrap: wrap;
gap: var(--inline-space-half);
inline-size: 100%;
- margin-block-start: calc(var(--block-space-half) / 2);
+ margin-block-start: var(--block-space-half);
margin-inline: calc(var(--column-gap) / -1);
&:has([open]) {
@@ -44,6 +44,7 @@
}
.reactions__trigger {
+ --btn-size: var(--reaction-size);
--btn-border-color: var(--reaction-border-color);
img {
@@ -115,11 +116,13 @@
/* Make the avatar and delete buttons fit nicely within the reaction */
.reaction__avatar,
+ .reaction__avatar .avatar,
.reaction__form-label,
.reaction form {
- block-size: var(--btn-size);
+ block-size: 100%;
}
+
.reaction__delete {
display: none;
diff --git a/app/controllers/cards/drafts_controller.rb b/app/controllers/cards/drafts_controller.rb
new file mode 100644
index 000000000..a4e9388de
--- /dev/null
+++ b/app/controllers/cards/drafts_controller.rb
@@ -0,0 +1,13 @@
+class Cards::DraftsController < ApplicationController
+ include CardScoped
+
+ before_action :redirect_if_published
+
+ def show
+ end
+
+ private
+ def redirect_if_published
+ redirect_to @card unless @card.drafted?
+ end
+end
diff --git a/app/controllers/cards/publishes_controller.rb b/app/controllers/cards/publishes_controller.rb
index 641f728cd..a0378eec3 100644
--- a/app/controllers/cards/publishes_controller.rb
+++ b/app/controllers/cards/publishes_controller.rb
@@ -5,7 +5,8 @@ class Cards::PublishesController < ApplicationController
@card.publish
if add_another_param?
- redirect_to @board.cards.create!, notice: "Card added"
+ card = @board.cards.create!(status: :drafted)
+ redirect_to card_draft_path(card), notice: "Card added"
else
redirect_to @card.board
end
diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb
index e79eeb22b..e007527b8 100644
--- a/app/controllers/cards_controller.rb
+++ b/app/controllers/cards_controller.rb
@@ -3,6 +3,7 @@ class CardsController < ApplicationController
before_action :set_board, only: %i[ create ]
before_action :set_card, only: %i[ show edit update destroy ]
+ before_action :redirect_if_drafted, only: :show
before_action :ensure_permission_to_administer_card, only: %i[ destroy ]
def index
@@ -13,7 +14,7 @@ class CardsController < ApplicationController
respond_to do |format|
format.html do
card = Current.user.draft_new_card_in(@board)
- redirect_to card
+ redirect_to card_draft_path(card)
end
format.json do
@@ -56,6 +57,10 @@ class CardsController < ApplicationController
@card = Current.user.accessible_cards.find_by!(number: params[:id])
end
+ def redirect_if_drafted
+ redirect_to card_draft_path(@card) if @card.drafted?
+ end
+
def ensure_permission_to_administer_card
head :forbidden unless Current.user.can_administer_card?(@card)
end
diff --git a/app/models/search.rb b/app/models/search.rb
index 3b8127ef1..f81b9a9d8 100644
--- a/app/models/search.rb
+++ b/app/models/search.rb
@@ -1,6 +1,4 @@
module Search
- CJK_PATTERN = /\p{Han}|\p{Hiragana}|\p{Katakana}|\p{Hangul}/
-
def self.table_name_prefix
"search_"
end
diff --git a/app/models/search/highlighter.rb b/app/models/search/highlighter.rb
index 8672ed3c8..d2b53d772 100644
--- a/app/models/search/highlighter.rb
+++ b/app/models/search/highlighter.rb
@@ -13,14 +13,8 @@ class Search::Highlighter
result = text.dup
terms.each do |term|
- if term.match?(Search::CJK_PATTERN)
- result.gsub!(/(#{Regexp.escape(term)})/i) do |match|
- "#{OPENING_MARK}#{match}#{CLOSING_MARK}"
- end
- else
- result.gsub!(/\b(#{Regexp.escape(term)}\w*)\b/i) do |match|
- "#{OPENING_MARK}#{match}#{CLOSING_MARK}"
- end
+ result.gsub!(/\b(#{Regexp.escape(term)}\w*)\b/i) do |match|
+ "#{OPENING_MARK}#{match}#{CLOSING_MARK}"
end
end
diff --git a/app/models/search/query.rb b/app/models/search/query.rb
index 6bf06ef42..5fe0829e4 100644
--- a/app/models/search/query.rb
+++ b/app/models/search/query.rb
@@ -33,7 +33,7 @@ class Search::Query < ApplicationRecord
end
def remove_invalid_search_characters(terms)
- terms.gsub(/[^\p{L}\p{N}_"]/, " ")
+ terms.gsub(/[^\w"]/, " ")
end
def remove_unbalanced_quotes(terms)
diff --git a/app/models/search/record/sqlite.rb b/app/models/search/record/sqlite.rb
index 73b3b675f..ae0d34281 100644
--- a/app/models/search/record/sqlite.rb
+++ b/app/models/search/record/sqlite.rb
@@ -8,10 +8,9 @@ module Search::Record::SQLite
has_one :search_records_fts, -> { with_rowid },
class_name: "Search::Record::SQLite::Fts", foreign_key: :rowid, primary_key: :id, dependent: :destroy
- before_save :stem_content
after_save :upsert_to_fts5_table
- scope :matching, ->(query, account_id) { joins(:search_records_fts).where("search_records_fts MATCH ?", Search::Stemmer.stem(query.to_s)) }
+ scope :matching, ->(query, account_id) { joins(:search_records_fts).where("search_records_fts MATCH ?", query) }
end
class_methods do
@@ -43,11 +42,6 @@ module Search::Record::SQLite
end
private
- def stem_content
- self.title = Search::Stemmer.stem(title) if title_changed?
- self.content = Search::Stemmer.stem(content) if content_changed?
- end
-
def escape_fts_highlight(html)
return nil unless html.present?
diff --git a/app/models/search/stemmer.rb b/app/models/search/stemmer.rb
index 2ae0e1bf1..f6a6c56d4 100644
--- a/app/models/search/stemmer.rb
+++ b/app/models/search/stemmer.rb
@@ -5,43 +5,9 @@ module Search::Stemmer
def stem(value)
if value.present?
- tokenize(value).join(" ")
+ value.gsub(/[^\w\s]/, "").split(/\s+/).map { |word| STEMMER.stem(word.downcase) }.join(" ")
else
value
end
end
-
- private
- def tokenize(value)
- tokens = []
- current_word = +""
-
- value.each_char do |char|
- if cjk_character?(char)
- if current_word.present?
- tokens << stem_word(current_word)
- current_word = +""
- end
- tokens << char
- elsif char =~ /[\p{L}\p{N}_]/
- current_word << char
- else
- if current_word.present?
- tokens << stem_word(current_word)
- current_word = +""
- end
- end
- end
-
- tokens << stem_word(current_word) if current_word.present?
- tokens
- end
-
- def cjk_character?(char)
- char.match?(Search::CJK_PATTERN)
- end
-
- def stem_word(word)
- STEMMER.stem(word.downcase)
- end
end
diff --git a/app/views/cards/_container.html.erb b/app/views/cards/_container.html.erb
index c85236683..d66996f96 100644
--- a/app/views/cards/_container.html.erb
+++ b/app/views/cards/_container.html.erb
@@ -37,11 +37,5 @@
<% if card.published? %>
<%= render "cards/container/footer/published", card: card %>
- <% elsif card.drafted? %>
- <% if Fizzy.saas? %>
- <%= render "cards/container/footer/saas/create", card: card %>
- <% else %>
- <%= render "cards/container/footer/create", card: card %>
- <% end %>
<% end %>
diff --git a/app/views/cards/drafts/_container.html.erb b/app/views/cards/drafts/_container.html.erb
new file mode 100644
index 000000000..c74326544
--- /dev/null
+++ b/app/views/cards/drafts/_container.html.erb
@@ -0,0 +1,34 @@
+