Merge pull request #500 from basecamp/considering-bubble

Considering bubble
This commit is contained in:
Mike Dalessio
2025-05-16 10:26:50 -04:00
committed by GitHub
7 changed files with 88 additions and 63 deletions
+63
View File
@@ -0,0 +1,63 @@
@layer components {
.bubble {
--bubble-color: var(--card-color, oklch(var(--lch-blue-medium)));
--bubble-shape: 54% 46% 61% 39% / 57% 49% 51% 43%;
--bubble-rotate: 0deg;
--bubble-size-default: 4rem;
block-size: var(--bubble-size, var(--bubble-size-default));
color: var(--color-ink);
container-type: inline-size;
font-size: 1.7rem;
font-weight: bold;
inline-size: var(--bubble-size, var(--bubble-size-default));
padding: 0.5cqi;
position: absolute;
inset-block-start: 50%;
&:before {
background: radial-gradient(
color-mix(in srgb, var(--bubble-color) 8%, var(--color-canvas)) 50%,
color-mix(in srgb, var(--bubble-color) 48%, var(--color-canvas)) 100%
);
border-radius: var(--bubble-shape);
content: "";
inset: 0;
position: absolute;
transform: rotate(var(--bubble-rotate));
z-index: -1;
}
@media (any-hover: hover) {
&:hover:before {
animation: wobble 1200ms;
}
}
svg {
display: block;
letter-spacing: 0.1ch;
text-transform: uppercase;
}
}
.bubble__number {
display: grid;
font-size: 40cqi;
font-weight: 900;
inset: 0;
place-content: center;
position: absolute;
text-align: center;
}
}
.bubble--closing {
inset-inline-start: calc(-1 * var(--bubble-gap));
translate: -100% -50%;
}
.bubble--considering {
inset-inline-end: calc(-1 * var(--bubble-gap));
translate: 100% -50%;
}
+4 -1
View File
@@ -10,10 +10,13 @@
}
.card-columns {
--bubble-size: 4rem;
--bubble-gap: 0.5rem;
display: grid;
grid-template-columns: repeat(2, 50%);
margin: auto;
max-inline-size: 1080px;
max-inline-size: calc(100% - (var(--bubble-size) + var(--bubble-gap)) * 2);
position: relative;
&:before {
+2 -57
View File
@@ -25,7 +25,6 @@
}
.card--golden.card--doing {
/* --lch-golden: var(--lch-yellow-medium); */
--lch-golden: 89.1% 0.178 95.7;
background-color: var(--color-canvas);
@@ -290,60 +289,6 @@
border-block-end: 1px dashed currentcolor;
}
.card__bubble {
--bubble-color: radial-gradient(oklch(var(--lch-blue-medium) / 10%) 50%, oklch(var(--lch-blue-medium) / 50%) 100%);
--bubble-shape: 54% 46% 61% 39% / 57% 49% 51% 43%;
--bubble-rotate: 0deg;
--size: 5cqi;
block-size: var(--size);
container-type: inline-size;
font-size: 1.75rem;
font-weight: bold;
inline-size: var(--size);
inset: 50% auto auto -0.5ch;
padding: 0.5cqi;
position: absolute;
translate: -100% -50%;
&:before {
background: var(--bubble-color);
border-radius: var(--bubble-shape);
content: "";
inset: 0;
position: absolute;
transform: rotate(var(--bubble-rotate));
}
@media (any-hover: hover) {
&:hover:before {
animation: wobble 1200ms;
}
}
span {
display: grid;
font-size: 40cqi;
font-weight: 900;
inset: 0;
place-content: center;
position: absolute;
text-align: center;
}
svg {
display: block;
letter-spacing: 0.125ch;
text-transform: uppercase;
}
.card:nth-child(2n+1) & { --bubble-rotate: -90deg; }
.card:nth-child(3n+1) & { --bubble-rotate: 45deg; }
}
.card__bubble--today {
span {
font-size: 30cqi;
}
}
.card:nth-child(2n+1) .bubble { --bubble-rotate: -90deg; }
.card:nth-child(3n+1) .bubble { --bubble-rotate: 45deg; }
}
+9
View File
@@ -2,6 +2,7 @@ module Card::Engageable
extend ActiveSupport::Concern
STAGNATED_AFTER = 30.days
AUTO_RECONSIDER_REMINDER_BEFORE = 7.days
included do
has_one :engagement, dependent: :destroy, class_name: "Card::Engagement"
@@ -28,6 +29,10 @@ module Card::Engageable
last_active_at + STAGNATED_AFTER if last_active_at
end
def days_until_reconsider
(auto_reconsider_at.to_date - Date.current).to_i if auto_reconsider_at
end
def doing?
open? && published? && engagement.present?
end
@@ -36,6 +41,10 @@ module Card::Engageable
open? && published? && engagement.blank?
end
def reconsidering_soon?
doing? && Time.current >= auto_reconsider_at - AUTO_RECONSIDER_REMINDER_BEFORE
end
def engage
unless doing?
transaction do
+1 -1
View File
@@ -23,7 +23,7 @@
<span class="card-perma__closure-message">
<% if card.doing? %>
Returns to <em>Considering</em> if no activity <%= local_datetime_tag(card.auto_reconsider_at, style: :indays) -%>.
Falls back to <em>Considering</em> if no activity <%= local_datetime_tag(card.auto_reconsider_at, style: :indays) -%>.
<% elsif card.auto_closing? %>
Auto-closes if no activity <%= local_datetime_tag(card.auto_close_at, style: :indays) -%>.
<% end %>
+5 -1
View File
@@ -30,7 +30,11 @@
<%= render "cards/display/common/background", card: card %>
<% if card.closing_soon? %>
<%= render "cards/display/preview/bubble", days: card.days_until_close %>
<%= render "cards/display/preview/bubble", label: "Closes", days: card.days_until_close, class: "bubble--closing" %>
<% end %>
<% if card.reconsidering_soon? %>
<%= render "cards/display/preview/bubble", label: "Falls Back", days: card.days_until_close, class: "bubble--considering" %>
<% end %>
<% end %>
<% end %>
@@ -1,14 +1,15 @@
<div class="card__bubble">
<div class="bubble <%= local_assigns[:class] %>">
<svg viewBox="0 0 200 100">
<path id="top-half" fill="transparent" d="M 20,100 A 80,80 0 0,1 180,100" />
<text text-anchor="middle" fill="currentColor">
<textPath href="#top-half" startOffset="50%" dominant-baseline="middle">
<%= days < 1 ? "Closes" : "Closes in" %>
<%= local_assigns[:label] %>
<%= " in" if days > 1 %>
</textPath>
</text>
</svg>
<span class="circle-bubble__number">
<span class="bubble__number">
<%= days < 1 ? "!" : days %>
</span>