diff --git a/app/assets/images/golden-ticket.svg b/app/assets/images/golden-ticket.svg
new file mode 100644
index 000000000..99d44fdf8
--- /dev/null
+++ b/app/assets/images/golden-ticket.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/assets/images/star.svg b/app/assets/images/star.svg
deleted file mode 100644
index 281a18051..000000000
--- a/app/assets/images/star.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/assets/stylesheets/_global.css b/app/assets/stylesheets/_global.css
index 8dc17b990..4711ea25d 100644
--- a/app/assets/stylesheets/_global.css
+++ b/app/assets/stylesheets/_global.css
@@ -31,6 +31,7 @@
--lch-blue: 54% 0.15 255;
--lch-blue-light: 95% 0.03 255;
--lch-blue-dark: 80% 0.08 255;
+ --lch-golden: 83% 0.1128 72.43;
--lch-orange: 70% 0.2 44;
--lch-red: 51% 0.2 31;
--lch-green: 65.59% 0.234 142.49;
@@ -58,6 +59,7 @@
--color-always-black: oklch(var(--lch-always-black));
--color-always-white: oklch(var(--lch-always-white));
--color-container: oklch(var(--lch-light-blue));
+ --color-golden: oklch(var(--lch-golden));
@media (prefers-color-scheme: dark) {
--lch-black: 100% 0 0;
diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css
index 1431180c3..1a8325e45 100644
--- a/app/assets/stylesheets/cards.css
+++ b/app/assets/stylesheets/cards.css
@@ -97,6 +97,17 @@
}
}
+ .card--golden {
+ --border-color: var(--color-bg) !important;
+
+ background-color: var(--color-bg);
+ background-image: linear-gradient(90deg, oklch(var(--lch-golden) / 0.5) 0%, oklch(var(--lch-golden) / 0.1) 50%, oklch(var(--lch-golden) / 0.75) 100%);
+ box-shadow:
+ 0 0 0.5em 0.2em var(--color-golden),
+ 0 0 1em 0.4em var(--color-golden) !important;
+ outline: 1px solid var(--color-golden);
+ }
+
.card__actions {
position: absolute;
inset: var(--actions-block-inset) auto auto calc(var(--actions-inline-inset) * -1);
@@ -247,12 +258,6 @@
display: inline-flex;
margin-block: calc(var(--block-space) * -1) calc(var(--block-space) * -0.33);
padding: var(--padding-block) var(--padding-inline);
-
- &:has(.card__star-input:checked) {
- .card {
- outline: 4px solid var(--color-negative);
- }
- }
}
.card__container--pointing {
diff --git a/app/assets/stylesheets/icons.css b/app/assets/stylesheets/icons.css
index 1f3d193dc..987210def 100644
--- a/app/assets/stylesheets/icons.css
+++ b/app/assets/stylesheets/icons.css
@@ -38,6 +38,7 @@
.icon--everyone { --svg: url("everyone.svg "); }
.icon--filter { --svg: url("filter.svg "); }
.icon--globe { --svg: url("globe.svg "); }
+ .icon--golden-ticket { --svg: url("golden-ticket.svg "); }
.icon--home { --svg: url("home.svg "); }
.icon--logout { --svg: url("logout.svg "); }
.icon--menu { --svg: url("menu.svg "); }
@@ -61,7 +62,6 @@
.icon--rename { --svg: url("rename.svg "); }
.icon--settings { --svg: url("settings.svg "); }
.icon--share { --svg: url("share.svg "); }
- .icon--star { --svg: url("star.svg "); }
.icon--tag { --svg: url("tag.svg "); }
.icon--thumb-up { --svg: url("thumb-up.svg "); }
.icon--trash { --svg: url("trash.svg "); }
diff --git a/app/controllers/cards/goldnesses_controller.rb b/app/controllers/cards/goldnesses_controller.rb
new file mode 100644
index 000000000..4be611d14
--- /dev/null
+++ b/app/controllers/cards/goldnesses_controller.rb
@@ -0,0 +1,13 @@
+class Cards::GoldnessesController < ApplicationController
+ include CardScoped
+
+ def create
+ @card.gild
+ redirect_to @card
+ end
+
+ def destroy
+ @card.ungild
+ redirect_to @card
+ end
+end
diff --git a/app/models/card.rb b/app/models/card.rb
index 4c50d6029..8d4411cf4 100644
--- a/app/models/card.rb
+++ b/app/models/card.rb
@@ -1,6 +1,7 @@
class Card < ApplicationRecord
- include Assignable, Boostable, Colored, Commentable, Engageable, Eventable,
- Messages, Notifiable, Pinnable, Closeable, Scorable, Searchable, Staged, Statuses, Taggable, Watchable
+ include Assignable, Boostable, Colored, Commentable, Engageable, Eventable, Golden,
+ Messages, Notifiable, Pinnable, Closeable, Scorable, Searchable, Staged,
+ Statuses, Taggable, Watchable
belongs_to :collection, touch: true
belongs_to :creator, class_name: "User", default: -> { Current.user }
@@ -34,7 +35,7 @@ class Card < ApplicationRecord
scope :by_engagement_status, ->(status) do
case status.to_s
when "considering" then considering
- when "doing" then doing
+ when "doing" then doing.with_golden_first
end
end
diff --git a/app/models/card/golden.rb b/app/models/card/golden.rb
new file mode 100644
index 000000000..759179415
--- /dev/null
+++ b/app/models/card/golden.rb
@@ -0,0 +1,23 @@
+module Card::Golden
+ extend ActiveSupport::Concern
+
+ included do
+ scope :golden, -> { joins(:goldness) }
+
+ has_one :goldness, dependent: :destroy, class_name: "Card::Goldness"
+
+ scope :with_golden_first, -> { left_outer_joins(:goldness).prepend_order("card_goldnesses.id IS NULL") }
+ end
+
+ def golden?
+ goldness.present?
+ end
+
+ def gild
+ create_goldness! unless golden?
+ end
+
+ def ungild
+ goldness&.destroy
+ end
+end
diff --git a/app/models/card/goldness.rb b/app/models/card/goldness.rb
new file mode 100644
index 000000000..fc2697328
--- /dev/null
+++ b/app/models/card/goldness.rb
@@ -0,0 +1,3 @@
+class Card::Goldness < ApplicationRecord
+ belongs_to :card, touch: true
+end
diff --git a/app/views/cards/_golden_toggle.html.erb b/app/views/cards/_golden_toggle.html.erb
new file mode 100644
index 000000000..b3525f351
--- /dev/null
+++ b/app/views/cards/_golden_toggle.html.erb
@@ -0,0 +1,11 @@
+<% if card.golden? %>
+ <%= button_to card_goldness_path(card), method: :delete, class: "btn btn--reversed" do %>
+ <%= icon_tag "golden-ticket" %>
+ Demote to normal
+ <% end %>
+<% else %>
+ <%= button_to card_goldness_path(card), class: "btn" do %>
+ <%= icon_tag "golden-ticket" %>
+ Promote to golden
+ <% end %>
+<% end %>
diff --git a/app/views/cards/display/_perma.html.erb b/app/views/cards/display/_perma.html.erb
index 814387565..bdc1a3c4d 100644
--- a/app/views/cards/display/_perma.html.erb
+++ b/app/views/cards/display/_perma.html.erb
@@ -1,5 +1,5 @@
<% cache card do %>
-