/* ==========================================================
   Scorecard — Cloud Garden theme (light mode)
   Background: soft cumulus photo. Frosted-glass columns.
   Color-filled cards with contrasting type. Helvetica Light.
   ========================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

:root {
  /* ink + chrome */
  --ink:           #1d3a3a;      /* deep teal */
  --ink-soft:      #4a6868;
  --cream:         #fdf2e8;
  --glass-bg:      rgba(255, 253, 247, 0.55);
  --glass-bg-strong: rgba(255, 253, 247, 0.78);
  --glass-border:  rgba(29, 58, 58, 0.14);
  --hairline:      rgba(29, 58, 58, 0.10);

  /* 1BT marker + real-alert badges — Coral. The one color reserved for
     things that genuinely need to shout (1BT tag, completion alerts). Not a
     decorative highlight — see memory/scorecard_named_palette.md. */
  --obt-color:     #ff6230;       /* Coral */
  --obt-text:      #fdf2e8;

  /* Fotocasa category fill. Pool Pass (which used to share this) is retired
     6 Oct 2026 — see Morning Prize below. */
  --klein:         #0a3bb5;       /* Klein Blue */

  /* Morning Prize accents (replaces Pool Pass, 6 Oct 2026) — one solid color
     per rotating prize, no gradient (tried, reverted 7 Oct 2026). Back to the
     exact Pool Pass recipe: solid accent + cream text/icon throughout (see
     .prize-card). Bright variants (7 Oct 2026) swapped in over the pale
     Jade/Cornflower/Posie picks specifically so cream keeps good contrast —
     Jade Green itself stays in the core palette above, just unused here now. */
  --bright-jade:     #209c90;     /* Bright Jade — Walk */
  --bright-lavender: #b13bfb;     /* Bright Lavender — Phone */
  --bright-posie:    #f31c9d;     /* Bright Posie — Book */
  --jade:          #52a39b;       /* Jade Green — status color, progress-bar "on track" fill (7 Oct 2026) */

  /* Toasts — tinted grounds with a saturated left stripe. Grounds are the
     accent pre-blended over --cream (coral ~18%, posie ~22%) rather than an
     alpha, because toasts sit fixed over the photo background and anything
     translucent would pick up the clouds behind them. */
  --midnight:      #10302b;       /* toast body text */
  --posie:         #ee70bc;       /* info stripe */
  --toast-bg:      #fdd8c7;       /* friction ground */
  --toast-info-bg: #fad5de;       /* info ground */

  /* state colors — named per the confirmed palette (10 Sept 2026).
     Warning was retired: cap/alert states now go neutral (--ink-soft). */
  --danger:        #9f1d43;   /* Cherry */
  --success:       #1d4d4d;   /* Evergreen — floor-met text, "good" alert */
  --lime:          #d1d067;   /* Lime — progress-bar low end */

  /* Progress-bar "on track" fill — Jade Green, swapped in for Evergreen
     7 Oct 2026 (her call, scoped to the bar only; floor-met text and the
     "good" alert still use --success/Evergreen, untouched). */
  --progress-success: var(--jade);

  /* Named aliases for colors already defined above under a role name, used
     here under their design-kit name instead (Morning Prize ink/accents,
     7 Oct 2026) — same hex, not a new color. */
  --cherry:        var(--danger);
  --evergreen:     var(--success);
  --cornflower:    #8ba2f0;   /* also Connections category fill */

  /* layout */
  --radius:        4px;
  --radius-sm:     2px;
  --shadow-sm:     0 1px 2px rgba(0,0,0,0.05), 0 3px 8px rgba(0,0,0,0.08);
  --shadow-md:     0 2px 6px rgba(0,0,0,0.10), 0 8px 20px rgba(0,0,0,0.12);
}

html, body {
  margin: 0;
  font-family: "Helvetica Neue", Helvetica, "Inter", Arial, sans-serif;
  font-weight: 300;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  color: var(--ink);
  font-size: 14px;
  line-height: 1.4;
  min-height: 100vh;
}

/* Pinned to the viewport so the rail and columns scroll inside themselves
   rather than growing the page — the .scorecard overflow-y and the .column
   max-height rules below only bite once the page itself is bounded. */
body {
  position: relative;
  height: 100vh;
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(250,247,240,0.18), rgba(250,247,240,0.42)),
    url("assets/light-cumulus.jpg") center/cover no-repeat fixed;
  display: flex;
  flex-direction: column;
}

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 300;
  letter-spacing: -0.01em;
}

button { font: inherit; cursor: pointer; }

/* ============ Topbar (frosted) ============ */
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 24px;
  background: var(--glass-bg-strong);
  backdrop-filter: blur(20px) saturate(1.1);
  -webkit-backdrop-filter: blur(20px) saturate(1.1);
  border-bottom: 1px solid var(--glass-border);
  position: sticky;
  top: 0;
  z-index: 10;
}

.topbar-left {
  display: flex;
  align-items: baseline;
  gap: 14px;
}

.topbar-left h1 {
  font-size: 22px;
  letter-spacing: -0.02em;
  font-weight: 300;
}

.today-date {
  color: var(--ink-soft);
  font-size: 12px;
  letter-spacing: 0.04em;
}

.topbar-right { display: flex; gap: 8px; }

/* ============ Buttons ============ */
.btn {
  border: 1px solid var(--glass-border);
  background: transparent;
  color: var(--ink);
  padding: 7px 14px;
  border-radius: var(--radius);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.04em;
  transition: background 0.12s ease, color 0.12s ease;
}
.btn:hover { background: rgba(29, 58, 58, 0.06); }

.btn-primary {
  background: var(--ink);
  color: var(--cream);
  border-color: var(--ink);
}
.btn-primary:hover { background: #0e2424; }

.btn-ghost { background: transparent; }


.btn-danger {
  background: transparent;
  color: var(--danger);
  border-color: var(--danger);
}
.btn-danger:hover { background: var(--danger); color: #fff; }

/* ============ Layout ============ */
.layout {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 0;
  min-height: 0;
}

/* Collapsed: panel shrinks to a thin tab that just holds the toggle. */
.layout.is-scorecard-collapsed { grid-template-columns: 1fr 52px; }
.layout.is-scorecard-collapsed .scorecard { padding: 18px 0; overflow: hidden; }
.layout.is-scorecard-collapsed .scorecard-inner { display: none; }
.layout.is-scorecard-collapsed .scorecard-title { display: none; }
.layout.is-scorecard-collapsed .scorecard-header { justify-content: center; margin: 0; }

/* Wraps the board so the on-ice strip can sit beneath it without becoming
   another horizontally-scrolling column. */
.board-area {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

.board {
  flex: 1;
  display: flex;
  gap: 14px;
  padding: 18px;
  overflow-x: auto;
  align-items: flex-start;
}


.scorecard {
  position: relative;
  background: var(--glass-bg-strong);
  backdrop-filter: blur(20px) saturate(1.1);
  -webkit-backdrop-filter: blur(20px) saturate(1.1);
  border-left: 1px solid var(--glass-border);
  padding: 22px;
  overflow-y: auto;
}

/* Panel header — toggle button + "Scorecard" title side by side */
.scorecard-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 22px;
}

.scorecard-title {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0;
}

.btn-toggle-scorecard {
  background: transparent;
  border: 1px solid var(--glass-border);
  color: var(--ink);
  padding: 6px 8px;
  border-radius: var(--radius);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.12s ease, color 0.12s ease;
  flex-shrink: 0;
}
.btn-toggle-scorecard:hover { background: rgba(29, 58, 58, 0.06); }
.btn-toggle-scorecard svg { display: block; }

/* ============ Columns (frosted glass) ============ */
.column {
  flex: 0 0 260px;
  background: var(--glass-bg);
  backdrop-filter: blur(18px) saturate(1.1);
  -webkit-backdrop-filter: blur(18px) saturate(1.1);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius);
  padding: 16px 12px;
  display: flex;
  flex-direction: column;
  /* Resolves against the bounded .board rather than the viewport, so the
     on-ice strip below is always in view no matter how tall a column gets. */
  max-height: 100%;
}

.column[data-column="done"] {
  background: var(--glass-bg-strong);
}

.column-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 0 4px 12px;
  border-bottom: 1px solid var(--glass-border);
  margin-bottom: 10px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink);
  user-select: none;
  -webkit-user-select: none;
}

/* Only the 5 category column headers are draggable; Done + Today stay pinned. */
.column.is-reorderable .column-header { cursor: grab; }
.column.is-reorderable .column-header:active { cursor: grabbing; }

.column-header .column-count {
  color: var(--ink-soft);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.18em;
}

.column-cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
  overflow-y: auto;
  min-height: 30px;
  /* Headroom so the 1BT badge (top: -9px on .card.is-obt) isn't clipped
     when a starred card is the top child. Negative margin cancels the
     padding so layout is visually unchanged. */
  padding-top: 12px;
  margin-top: -12px;
}

.column-cards.drag-over {
  outline: 1px dashed var(--ink-soft);
  outline-offset: -4px;
}

/* ============ Cards (color-fill, contrasting type) ============ */
.card {
  position: relative;
  background: var(--cat-color);
  color: var(--cat-text);
  border-radius: var(--radius);
  padding: 12px 14px 14px;
  box-shadow: var(--shadow-sm);
  cursor: grab;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
  /* Cards are draggable UI, not readable text. Prevents drag from selecting
     text in passed-over cards (a side-effect of Sortable's forceFallback mode). */
  user-select: none;
  -webkit-user-select: none;
}

.card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.card:active { cursor: grabbing; }

/* While dragging, suppress hover lift + transform transitions so they don't
   fight SortableJS's own transform-based reorder animation. */
body.dragging .card { transition: box-shadow 0.12s ease; }
body.dragging .card:hover {
  transform: none;
  box-shadow: var(--shadow-sm);
}

/* Top row: project pill (when tagged) + actions. The row is kept on untagged
   cards too — it holds the star/edit buttons, and min-height keeps every card's
   title on the same baseline whether or not it carries a project. */
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
  min-height: 20px;
}

/* Outline pill inheriting the card's text colour, so one rule works on every
   category fill (dark teal through pale blue) with no per-category styling. */
.card-project {
  /* Button reset — buttons don't inherit font/color from their parent like a
     span would, and this pill needs both from the card's --cat-text fill. */
  font: inherit;
  color: inherit;
  background: none;
  cursor: pointer;

  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 2px 8px;
  opacity: 0.85;
  max-width: 72%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background 0.12s ease, opacity 0.12s ease;
}
.card-project:hover { opacity: 1; }

/* Click cue: filtering to this project. Switches to a light fill so it reads
   against every category color rather than trying to darken an already-dark
   outline pill. */
.card-project.is-filtering {
  background: var(--cream);
  color: var(--ink);
  border-color: var(--cream);
  opacity: 1;
  font-weight: 700;
}

/* margin-left:auto keeps the actions hard right even when there's no project
   pill to occupy the left slot — space-between alone would pull a lone child
   back to the start. */
.card-actions {
  display: flex;
  gap: 2px;
  align-items: center;
  margin-left: auto;
  opacity: 0.6;
  transition: opacity 0.12s ease;
}
.card:hover .card-actions { opacity: 1; }

.card-btn {
  background: transparent;
  border: none;
  padding: 2px 5px;
  font-size: 14px;
  color: var(--cat-text);
  border-radius: var(--radius-sm);
  line-height: 1;
  opacity: 0.7;
}
.card-btn:hover { opacity: 1; background: rgba(0,0,0,0.10); }

.card-btn.is-star.active {
  color: var(--cat-text);
  opacity: 1;
}

/* Bottom row: title + points */
.card-footer {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 10px;
}

.card-title {
  font-size: 18px;          /* large for readability */
  font-weight: 300;
  letter-spacing: -0.01em;
  line-height: 1.25;
  word-wrap: break-word;
  flex: 1;
}

.card-points {
  font-size: 26px;
  font-weight: 300;
  letter-spacing: -0.04em;
  line-height: 1;
  flex-shrink: 0;
  opacity: 0.9;
}

/* 1BT marker — coral tag, top-right, NOT rotated */
.card.is-obt::before {
  content: "1BT";
  position: absolute;
  top: -9px;
  right: 14px;
  background: var(--obt-color);
  color: var(--obt-text);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.22em;
  padding: 4px 10px 5px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.18);
  z-index: 3;
  border-radius: var(--radius-sm);
}

/* Done — pure greyscale + line-through */
.card.is-done {
  filter: grayscale(1);
  opacity: 0.7;
  cursor: default;
}
.card.is-done .card-title {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.card.is-done .card-points { opacity: 0.55; }
.card.is-done:hover { transform: none; box-shadow: var(--shadow-sm); }

/* ---- Rail group banners (Today / Week / Projects) ----
   Full-bleed dark bars that break the rail into its three time horizons. The
   negative margin cancels the .scorecard padding so they run edge to edge. */
/* Selector must out-specify `.scorecard h2`, which sets the small 11px
   sub-heading treatment these banners are deliberately breaking away from. */
.scorecard h2.rail-group-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 30px -22px 16px;
  padding: 9px 22px;
  background: var(--ink);
  color: var(--cream);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.scorecard h2.rail-group-title:first-child { margin-top: 0; }
.rail-group-title .projects-count {
  color: var(--cream);
  opacity: 0.7;
  font-size: 12.5px;
  letter-spacing: 0.04em;
  text-transform: none;
  font-weight: 400;
}
.rail-group-title .projects-count.is-over { opacity: 1; font-weight: 500; }

/* Sub-section heads inside a group — the old h2 treatment. */
.scorecard h3 {
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-weight: 500;
  color: var(--ink-soft);
  margin-bottom: 10px;
}

/* ---- Collapsible rail section ----
   The underline + hover fill is what marks this as a control rather than a
   plain sub-heading like "Pool Pass" or "Friday unlock" next to it — those
   read identically otherwise (same h3 treatment) with nothing to say "click
   me". */
.section-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--glass-border);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  margin: 0 -6px 10px;
  padding: 2px 6px 8px;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.section-toggle:hover {
  background: rgba(29, 58, 58, 0.06);
  border-bottom-color: var(--ink-soft);
}
.section-toggle .chev {
  flex-shrink: 0;
  opacity: 0.65;
  transition: transform 0.15s ease, opacity 0.15s ease;
}
.section-toggle:hover .chev { opacity: 1; }
/* Chevron points down (expanded) by default; collapsed rotates it to point
   right. Driven off aria-expanded so the visual state can't drift from the
   a11y state. */
.section-toggle[aria-expanded="false"] .chev { transform: rotate(-90deg); }
.scorecard-section.is-collapsed .section-body { display: none; }

/* ---- Projects section (rail) ---- */

/* project-list is the Sortable-bound container; :first-of-type keying off the
   row itself would fire for the first row of every list, which is what we
   want (active list and on-ice list each start clean). */
.project-list { min-height: 4px; }

.project-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  border-top: 1px solid rgba(0, 0, 0, 0.07);
  cursor: grab;
  /* Same fix as .card — draggable UI, not readable text. Without this, the
     mouse-based drag (forceFallback) sweeps a text selection across every
     row it passes over. */
  user-select: none;
  -webkit-user-select: none;
}
.project-row:active { cursor: grabbing; }
.project-row:first-of-type { border-top: none; }

.project-row.is-iced { opacity: 0.55; }
.project-row.is-iced .project-name { color: var(--ink-soft); }

.project-list-empty {
  padding: 10px 0;
  font-size: 12.5px;
  color: var(--ink-soft);
  opacity: 0.7;
  font-style: italic;
}

/* Shared fallback ghost style for every Sortable list in the app (cards,
   columns, project rows) — none of them had one until now. */
.drag-ghost { opacity: 0.4; }

.project-name { font-size: 15px; color: var(--ink); }
.project-meta {
  font-size: 12.5px;
  color: var(--ink-soft);
  opacity: 0.8;
  margin-top: 2px;
}
/* Stale projects don't get a highlighted row anymore — just the meta text
   and the "Put on ice" button itself flag it, in Coral (real-attention tone,
   not decorative — see design-kit.html §01). */
.project-row.is-stale .project-meta { opacity: 1; font-weight: 500; color: var(--obt-color); }
.project-row.is-stale .btn-ice { border-color: var(--obt-color); color: var(--obt-color); }

.btn-ice {
  background: transparent;
  border: 1px solid rgba(0, 0, 0, 0.22);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--ink);
  white-space: nowrap;
  flex-shrink: 0;
  cursor: pointer;
}
.btn-ice:hover { background: rgba(255, 255, 255, 0.5); }

/* ============ Scorecard sidebar ============ */
.scorecard h2 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  font-weight: 500;
  color: var(--ink-soft);
  margin-bottom: 14px;
}

.scorecard-section { margin-bottom: 26px; }

.score-big {
  font-size: 48px;
  font-weight: 200;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--ink);
}

.score-target {
  color: var(--ink-soft);
  font-size: 14px;
  font-weight: 300;
  margin-left: 4px;
}

.progress {
  height: 4px;
  background: var(--hairline);
  border-radius: 0;
  overflow: hidden;
  margin-top: 10px;
}

.progress-fill {
  height: 100%;
  background: var(--progress-success);
  transition: width 0.25s ease;
}
.progress-fill.is-low { background: var(--lime); }
.progress-fill.is-empty { background: var(--ink-soft); opacity: 0.3; }
.progress-fill.is-prize { background: var(--today-prize-accent, var(--jade)); }

.category-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 7px 0;
  font-size: 15px;
  border-bottom: 1px solid var(--hairline);
}
.category-row:last-child { border-bottom: none; }

.category-row .cat-name {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 300;
}

.category-row .cat-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--cat-color);
}

.category-row .cat-points {
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  font-size: 15px;
}

.category-row.is-capped .cat-points {
  color: var(--ink-soft);
  font-weight: 500;
}
.category-row.is-floor-met .cat-points {
  color: var(--success);
  font-weight: 500;
}

.alerts {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}

.alert {
  font-size: 12px;
  padding: 8px 10px;
  border-radius: var(--radius);
  background: rgba(74, 104, 104, 0.10);
  color: var(--ink-soft);
  border-left: 3px solid var(--ink-soft);
  line-height: 1.35;
}
.alert.is-good {
  background: rgba(29, 77, 77, 0.08);
  color: var(--success);
  border-left-color: var(--success);
}
.alert.is-gold {
  background: rgba(255, 98, 48, 0.10);
  color: var(--obt-color);
  border-left-color: var(--obt-color);
}

/* ============ Modal ============ */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(29, 58, 58, 0.4);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}
.modal[hidden] { display: none; }

.modal-content {
  background: var(--cream);
  border-radius: var(--radius);
  padding: 26px;
  width: 400px;
  max-width: 92vw;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
}

.modal-content h2 {
  margin-bottom: 18px;
  font-size: 20px;
  font-weight: 300;
  color: var(--ink);
}

#card-form label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-bottom: 14px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 500;
}

/* Revealed only when "+ New project…" is picked, so a new project can be
   created without leaving the card you're mid-way through capturing. */
.new-project-fields {
  display: grid;
  grid-template-columns: 1fr 88px;
  gap: 10px;
  margin: -4px 0 14px;
  padding: 12px;
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.04);
}
.new-project-fields[hidden] { display: none; }
.new-project-fields label { margin-bottom: 0; }

#card-form label.checkbox {
  flex-direction: row;
  align-items: center;
  gap: 10px;
  text-transform: none;
  letter-spacing: 0;
  font-size: 13px;
  font-weight: 300;
  color: var(--ink);
}

#card-form input[type="text"],
#card-form select {
  font: inherit;
  font-weight: 300;
  font-size: 15px;
  padding: 9px 11px;
  border: 1px solid var(--glass-border);
  border-radius: var(--radius);
  background: #fff;
  color: var(--ink);
  text-transform: none;
  letter-spacing: 0;
}

#card-form input[type="text"]:focus,
#card-form select:focus {
  outline: none;
  border-color: var(--ink);
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}
.modal-actions .btn-danger { margin-right: auto; }

/* Pool Pass modal retired 6 Oct 2026 — replaced by the Morning Prize modal below. */

/* ============ Morning Prize modal (replaces Pool Pass, 6 Oct 2026) ============ */
.prize-modal {
  position: fixed;
  inset: 0;
  background: rgba(16, 48, 43, 0.45);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 110;
}
.prize-modal[hidden] { display: none; }

.prize-card {
  /* Per-prize accent, set inline by showMorningPrizeModal(); Jade (Walk) is
     the fallback so the card is never unstyled if JS hasn't run yet.
     Back to the exact Pool Pass recipe (7 Oct 2026, reverted off both the
     gradient and the light-fill/dark-ink attempts): solid accent panel,
     cream text/icon throughout, desat-glass chip — only the accent hue
     changes per prize. */
  --prize-accent: var(--bright-jade);

  position: relative;
  width: 100%;
  max-width: 440px;
  background: var(--cream);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(16,48,43,0.22), 0 24px 60px rgba(16,48,43,0.28);
  overflow: hidden;
}

.prize-top {
  background: var(--prize-accent);
  color: var(--cream);
  padding: 22px 108px 20px 28px;
  position: relative;
}
.prize-eyebrow {
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ceramic, #ede3c2);
  margin-bottom: 10px;
}
.prize-headline {
  font-size: 28px;
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -0.01em;
}
.prize-icon {
  position: absolute;
  top: 14px;
  right: 22px;
  width: 76px;
  height: 76px;
  color: var(--cream);
  opacity: 0.95;
}

.prize-body { padding: 24px 28px 26px; }

.prize-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  background: color-mix(in srgb, var(--prize-accent) 18%, white);
  border: 1px solid color-mix(in srgb, var(--prize-accent) 50%, white);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin-bottom: 18px;
}
.prize-chip-num { font-size: 22px; color: var(--prize-accent); }
.prize-chip-lbl { font-size: 12px; letter-spacing: 0.03em; color: var(--ink); opacity: 0.8; }

.prize-copy { font-size: 15px; line-height: 1.5; margin: 0 0 22px; color: var(--ink); }

.prize-actions { display: flex; gap: 10px; }
.prize-btn {
  flex: 1;
  border: 1px solid var(--prize-accent);
  border-radius: var(--radius);
  padding: 11px 14px;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.03em;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
  font-family: inherit;
}
.prize-btn-primary { background: var(--prize-accent); color: var(--cream); }
.prize-btn-primary:hover { background: color-mix(in srgb, var(--prize-accent) 80%, black); }
.prize-btn-ghost { background: transparent; color: var(--prize-accent); }
.prize-btn-ghost:hover { background: color-mix(in srgb, var(--prize-accent) 8%, transparent); }

/* ============ Toast ============ */
/* Two toast meanings, deliberately unalike. Friction (default) blocks and waits
   for an answer, so it shouts in Hot Sauce. Info (.is-info) never blocks and
   auto-dismisses, so it sits in Posie pink with nothing to press. */
.toast {
  position: fixed;
  top: 76px;                /* sits just below the topbar */
  left: 50%;
  transform: translateX(-50%);
  background: var(--toast-bg);
  color: var(--midnight);
  border-left: 5px solid var(--obt-color);
  padding: 16px 24px;
  /* Square on the stripe side, rounded on the other — a single-sided border
     against a rounded corner always reads as a mistake. */
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 15px;
  letter-spacing: 0.02em;
  box-shadow: var(--shadow-md);
  z-index: 200;
  display: flex;
  align-items: center;
  gap: 18px;
  max-width: min(640px, 90vw);
}
.toast[hidden] { display: none; }

.toast .toast-text { flex: 1; }

/* pre-line so the copy can break its own line — the "ask Claudia" nudge reads
   as a separate beat from the count it follows. */
.toast.is-info {
  background: var(--toast-info-bg);
  border-left-color: var(--posie);
  white-space: pre-line;
}

.toast .toast-action {
  background: var(--obt-color);
  color: var(--midnight);
  border: none;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}
.toast .toast-action:hover { filter: brightness(1.05); }

/* ============ Misc ============ */
.empty-state {
  text-align: center;
  color: var(--ink-soft);
  font-size: 12px;
  letter-spacing: 0.06em;
  padding: 24px 8px;
  font-style: normal;
  opacity: 0.7;
}

.storage-banner {
  background: rgba(255, 98, 48, 0.12);
  border-bottom: 1px solid var(--obt-color);
  padding: 10px 24px;
  font-size: 13px;
  color: var(--ink);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* ---------- Sign-in gate (hosted site only, see auth.js) ---------- */
.auth-gate {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: url("assets/light-cumulus.jpg") center / cover, var(--cream);
}
.auth-gate[hidden] { display: none; }
.auth-card {
  width: min(380px, 100%);
  padding: 32px 28px;
  border-radius: 16px;
  background: var(--glass-bg-strong);
  border: 1px solid var(--glass-border);
  backdrop-filter: blur(12px);
  color: var(--ink);
  text-align: center;
}
.auth-card p { color: var(--ink-soft); margin: 16px 0 20px; }

/* ---------- Read-only preview (hosted site until Stage 1, Step 5) ---------- */
.readonly-badge[hidden] { display: none; }
.readonly-badge {
  display: inline-block;
  margin-left: 12px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--glass-border);
  background: var(--glass-bg-strong);
  color: var(--ink-soft);
  font-size: 12px;
  letter-spacing: 0.04em;
}
body.is-readonly #btn-add,
body.is-readonly #btn-archive,
body.is-readonly #btn-storage { display: none; }
/* Hide only the controls that change data; project-pill filtering still works. */
body.is-readonly .card-actions,
body.is-readonly [data-ice],
body.is-readonly [data-thaw] { display: none; }
