/* App home — the native shell's start screen (architecture.md §30). An APP screen, not
   a web landing: safe-area aware, thumb-first, zero marketing copy. First run shows a
   three-pane onboarding that ends in sign-in; every run after lands straight on the
   activity grid. Same design system as everything else: pastel, near-sharp corners,
   pink/blue as the two people. */

html, body { height: 100%; }
body {
  /* Never rubber-band past the paper — feels like an app, not a page. */
  overscroll-behavior-y: none;
  -webkit-tap-highlight-color: transparent;
}

#app {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* ============ auth block ============ */
/* The first-run onboarding itself lives in app/onboarding.css (the typed question +
   paywall flow). What survives here is the shared sign-in stack — used by the flow's
   final screen AND the home screen's account sheet. */
.ob-auth { display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 380px; }
.ob-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 15px;
  font-family: var(--font-display); font-weight: 700; font-size: 16px;
  border-radius: var(--r-card);
  border: 2px solid var(--line);
  background: var(--paper-raised);
  color: var(--ink);
}
.ob-btn:active { transform: scale(0.98); }
.ob-btn--dark { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.ob-btn--apple { background: #000; border-color: #000; color: #fff; }
/* Sign in with Apple / Google: ONE standard for both — Apple's white-with-outline button,
   Google's light theme. White, a 1px grey edge, the brand mark pinned at the left, the
   label centred in the platform's own font (SF on iOS, Roboto on Android, as both brands
   ask). Same size and weight, Apple first (App Store guideline 4.8).
   They used to be two different blacks next to each other. */
.ob-btn--sso {
  position: relative;
  min-height: 54px; padding: 0 56px;
  border: 1px solid #d5d7dc; border-radius: 14px;
  background: #fff; color: #1f1f1f;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", Roboto, "Segoe UI", system-ui, sans-serif;
  font-weight: 600; font-size: 16px; letter-spacing: -0.01em;
  box-shadow: 0 1px 2px rgba(23, 24, 28, 0.05);
  transition: transform 160ms ease, background-color 160ms ease;
}
.ob-btn--sso:active { background-color: #f6f7f9; }
.ob-btn--sso:disabled { opacity: 0.55; }
.ob-btn-mark { position: absolute; left: 20px; top: 50%; transform: translateY(-50%); display: inline-flex; }
.ob-btn--apple.ob-btn--sso { color: #000; }
.ob-or { display: flex; align-items: center; gap: 12px; color: var(--ink-soft); font-size: 12px; }
.ob-or::before, .ob-or::after { content: ''; flex: 1; height: 1px; background: var(--line); }
.ob-email-row { display: flex; gap: 8px; }
.ob-email {
  flex: 1; min-width: 0;
  padding: 13px 14px;
  font: inherit; font-size: 16px;
  border: 2px solid var(--line); border-radius: var(--r-card);
  background: var(--paper-raised);
}
.ob-email:focus { outline: none; border-color: var(--ink); }
.ob-email-row .ob-btn { width: auto; flex: none; padding: 13px 16px; }
.ob-note { min-height: 18px; font-size: 13px; color: var(--ink-soft); }
.ob-note.is-ok { color: #0a7d4d; }

/* ============ home (every run) ============ */
/* Home's ONE card (2026-10-19, the product owner: "too busy — tidy, minimal, like picture 3",
   a pastel habit-tracker kit): every card on Home, and on the pages pushed over it that share
   its parts (the streak page, the moments page), is the same white card — a hairline, a faint
   shadow, 20px corners. One accent (the app's pink), small muted labels, a big number only
   where the number is the point, and pictures (the Higgsfield stickers) used sparingly. No
   gradient on a card; the one soft wash is the page's own ground on a wide screen. */
:root {
  --h-card: #FFFFFF;
  --h-line: #ECEDF2;
  --h-r: 20px;
  --h-shadow: 0 1px 2px rgba(23, 24, 28, 0.04), 0 8px 24px rgba(60, 40, 60, 0.05);
  --h-ink: #17181C;
  --h-muted: #6B6E78;
  --h-pink: #EC5F93;
  --h-deep: #C2416F;
  --h-tint: #FFF3F7;
  --h-tint-2: #FFE6EF;
  --h-blue-tint: #E6F0FF;
  --h-grey: #F1F2F5;
  /* a doodle's paper: light dots, so every pen (the white one too, with its outline) shows */
  --h-paper: radial-gradient(rgba(23, 24, 28, 0.07) 1px, transparent 1.4px) 0 0 / 12px 12px, #FBFAFC;
}
.home {
  display: flex; flex-direction: column;
  gap: var(--s3);
  padding: 0 var(--s2) calc(var(--s4) + env(safe-area-inset-bottom));
  max-width: 560px;
  width: 100%;
  margin: 0 auto;
}

.home-bar {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  padding: calc(14px + env(safe-area-inset-top)) 4px 12px;
  /* Solid --paper so the bar, the status-bar (theme-color #F8F9FB), and the page body
     are all the exact same white — the old translucent + saturate(140%) frost read as a
     slightly different shade and left a visible seam at the notch. */
  background: var(--paper);
}
.home-brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-display); font-weight: 800; font-size: 24px; letter-spacing: -0.03em;
}
.home-brand .dots { display: inline-flex; gap: 4px; }
.home-brand .dots i { width: 9px; height: 9px; border-radius: 50%; display: block; }
.home-brand .dots i.p { background: var(--pink); }
.home-brand .dots i.b { background: var(--blue); }
.home-ava {
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--h-line);
  background: var(--paper-raised);
  color: var(--ink-soft);
  font-family: var(--font-display); font-weight: 800; font-size: 15px;
  text-transform: uppercase;
}
.home-ava.is-in { border-color: var(--pink); color: var(--ink); }
/* the bell (app/notifications.js, 2026-10-14), left of the picture: the same round button,
   a pink count while something is new, one small ring when it arrives */
.home-bar-end { display: inline-flex; align-items: center; gap: 10px; }
.home-bell {
  position: relative; width: 38px; height: 38px; padding: 0;
  display: grid; place-items: center; border-radius: 50%;
  border: 1px solid var(--h-line); background: var(--paper-raised); color: var(--ink);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.home-bell:active { transform: scale(.94); }
.home-bell .icon { display: inline-flex; }
.home-bell-n {
  position: absolute; top: -6px; right: -7px; min-width: 20px; height: 20px; padding: 0 5px;
  display: none; place-items: center; border-radius: 999px; border: 2px solid var(--paper);
  background: #ec5f93; color: #fff; font: 800 11px/1 var(--font-body);
}
.home-bell.has-new { border-color: #F6B8CF; }
.home-bell.has-new .home-bell-n { display: grid; }
.home-bell.has-new .icon { animation: bell-ring 1.1s ease .4s 1; transform-origin: 50% 12%; }
@keyframes bell-ring {
  15% { transform: rotate(14deg); } 30% { transform: rotate(-12deg); } 45% { transform: rotate(8deg); }
  60% { transform: rotate(-5deg); } 75% { transform: rotate(2deg); }
}
@media (prefers-reduced-motion: reduce) { .home-bell.has-new .icon { animation: none; } }

.home-hey {
  display: flex; flex-direction: column; gap: 4px;
  padding: 0 4px;
}
.home-hey h1 {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(26px, 7vw, 34px); letter-spacing: -0.03em; line-height: 1.1;
  margin: 0;
}
.home-hey p { margin: 0; color: var(--ink-soft); font-size: 15px; }

/* featured photobooth card */
/* The Print Studio's info row (architecture.md §43) — mirrors landing/activity.html's
   .studio-info exactly, so the app grid and the web hub carry the identical card. Cream
   register, matching the /shirts product page it links to. */
.studio-info {
  display: grid; grid-template-columns: 78px 1fr auto; align-items: center; gap: 14px;
  padding: 12px 14px 12px 0; overflow: hidden;
  border: 1px solid #E7E1D8; border-radius: 14px; background: #FFFBF6; color: #23242A;
  text-decoration: none; box-shadow: 0 6px 20px rgba(35, 36, 42, 0.07);
}
.studio-info:active { transform: scale(0.98); }
.studio-info .si-art {
  align-self: stretch; min-height: 88px;
  /* 32% 42% lands the crop on the left shirt's printed chest — plain `center` shows the
     gap between the two shirts, which reads as an empty swatch at this width. */
  background: #F6F1EA 32% 42%/cover no-repeat url('/shirts/hero.webp');
  border-right: 1px solid #E7E1D8;
}
.studio-info .si-copy { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.studio-info .si-eyebrow {
  font-family: var(--font-mono); font-size: 10px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: #C9829C;
}
.studio-info .si-title {
  font-family: Georgia, "Times New Roman", serif; font-weight: 400; font-size: 18px;
  line-height: 1.15; letter-spacing: -0.01em;
}
.studio-info .si-note { font-size: 12px; color: #6B6C76; line-height: 1.4; }
.studio-info .si-tags { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 4px; }
.studio-info .si-tags i {
  font-style: normal; font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.08em;
  text-transform: uppercase; color: #23242A; background: #fff; border: 1px solid #E7E1D8;
  padding: 3px 7px; border-radius: 999px;
}
.studio-info .si-go { color: #9B9CA5; font-size: 16px; flex: none; }
@media (max-width: 420px) {
  .studio-info { grid-template-columns: 60px 1fr auto; gap: 11px; }
  .studio-info .si-tags i:nth-child(n+2) { display: none; }
}

/* The meet-up countdown (§23b) — first thing on the home screen when the couple has
   a date set. Reads as a boarding pass rather than a tile: a big D-number, the place,
   and a plain-language line. Turns pink inside the last week. */
.home-meet {
  display: flex; flex-direction: column; gap: 12px;
  padding: 16px;
  border: 1px solid var(--h-line); border-radius: var(--h-r);
  background: var(--h-card); box-shadow: var(--h-shadow);
  text-decoration: none; color: var(--ink);
}
.home-meet:active { transform: scale(0.99); }
.home-meet.is-soon { border-color: #F7C6D8; background: var(--h-tint); }
.hm-d {
  flex: 0 0 auto; font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 22px; font-weight: 700; letter-spacing: -0.02em;
  padding-right: 14px; border-right: 1px dashed var(--line);
}
.home-meet.is-soon .hm-d { color: var(--pink); }
.hm-head { display: flex; align-items: center; gap: 14px; }
.hm-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.hm-t { font-weight: 700; font-size: 15px; letter-spacing: -0.01em; }
.hm-s { font-size: 12.5px; color: var(--ink); opacity: 0.66; }
.hm-go { flex: 0 0 auto; opacity: 0.5; font-size: 13px; }
/* the split-flap countdown (client/core/flipClock.js) sits under the header line, so
   the tiles get their full width on a phone instead of fighting the copy for it */
.hm-clock { display: block; }
.hm-clock .fc { --fc-h: 34px; --fc-label: rgba(23,24,28,.5); }
.home-meet.is-soon .fc { --fc-face: #2A1420; --fc-ink: #FFE4EE; }

/* nothing set yet — the invitation to make one */
.home-meet.is-empty { flex-direction: row; align-items: center; gap: 14px; border-style: dashed; }
.hm-plus {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--pink-tint); color: var(--pink);
  font-size: 19px; font-weight: 700; line-height: 1;
}
.home-meet.is-empty .hm-t { opacity: 0.9; }

.home-feature {
  position: relative;
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--s3);
  border-radius: 14px;
  background: linear-gradient(120deg, var(--pink-tint), var(--blue-tint));
  overflow: hidden;
  text-decoration: none; color: var(--ink);
}
.home-feature:active { transform: scale(0.99); }
.home-feature h2 {
  font-family: var(--font-display); font-weight: 800; font-size: 22px;
  letter-spacing: -0.02em; margin: 0;
}
.home-feature p { margin: 0; color: var(--ink); opacity: 0.72; font-size: 14px; max-width: 30ch; }
.home-feature .go { margin-top: 8px; font-weight: 700; font-size: 15px; }
.home-feature .strip {
  position: absolute; right: -6px; top: 50%;
  transform: translateY(-50%) rotate(6deg);
  display: flex; flex-direction: column; gap: 4px;
  padding: 8px 6px 14px;
  background: var(--paper-raised);
  box-shadow: var(--shadow-soft);
}
.home-feature .strip i {
  display: block; width: 44px; height: 32px;
  background: linear-gradient(120deg, var(--pink), var(--blue));
  opacity: 0.65;
}
.home-feature .strip i:nth-child(2) { opacity: 0.45; }
.home-feature .strip i:nth-child(3) { opacity: 0.55; }
.home-feature .strip i:nth-child(4) { opacity: 0.35; }

/* section label */
.home-label {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0 4px;
}

/* activity grid — the heart of the screen */
.home-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.tile {
  display: flex; flex-direction: column; gap: 10px;
  padding: 18px 16px;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 14px;
  text-decoration: none; color: var(--ink);
  box-shadow: var(--shadow-soft);
  animation: tile-in 420ms cubic-bezier(.2,1,.4,1) both;
}
.tile:active { transform: scale(0.97); }
@keyframes tile-in { from { transform: translateY(10px); opacity: 0; } to { transform: none; opacity: 1; } }
.tile .ic {
  width: 42px; height: 42px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 12px;
  background: var(--paper);
}
.tile h3 {
  font-family: var(--font-display); font-weight: 800; font-size: 16px;
  letter-spacing: -0.01em; line-height: 1.2; margin: 0;
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.tile p { margin: 0; color: var(--ink-soft); font-size: 12.5px; line-height: 1.4; }
.tile-badge {
  font-family: var(--font-mono); font-size: 9px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 4px;
  color: #fff; background: linear-gradient(100deg, var(--pink), var(--blue));
}

/* wide rows (date creator / hub) */
.tile--wide { grid-column: 1 / -1; flex-direction: row; align-items: center; }
.tile--wide .copy { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.tile--wide .arr { margin-left: auto; color: var(--ink-soft); font-size: 18px; flex: none; }

.home-foot {
  text-align: center;
  color: var(--ink-soft);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em;
  padding-top: var(--s2);
}

/* account sheet (avatar tap) */
.sheet-veil {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(23, 24, 28, 0.4);
  animation: veil-in 180ms ease both;
}
@keyframes veil-in { from { opacity: 0; } }
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 301;
  display: flex; flex-direction: column; gap: var(--s2);
  padding: var(--s3) var(--s3) calc(var(--s3) + env(safe-area-inset-bottom));
  background: var(--paper-raised);
  border-radius: 18px 18px 0 0;
  animation: sheet-up 260ms cubic-bezier(.2,1,.4,1) both;
}
@keyframes sheet-up { from { transform: translateY(100%); } }
.sheet-grab { width: 36px; height: 4px; border-radius: 2px; background: var(--line); margin: -8px auto 0; }
.sheet h3 { margin: 0; font-family: var(--font-display); font-weight: 800; font-size: 19px; }
.sheet .who { color: var(--ink-soft); font-size: 14px; word-break: break-all; }
.sheet .ob-auth { max-width: none; }
/* the sheet's way to the profile Settings (language, subscription, purchases) */
.sheet .sheet-link { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 46px; margin-top: 2px; border-radius: 12px; background: #f3f1f7; color: var(--ink); font-weight: 700; font-size: 15px; text-decoration: none; }
.sheet .sheet-link svg { display: block; }

/* the 3D worlds door (architecture.md §55) — the one dark card on a pastel screen,
   because what's behind it is three night-time places (the night register, Design.md
   §15). Its plates ARE the three worlds, so the card shows what it opens. Kept in step
   with the same block in landing/activity.html. */
.home-worlds {
  position: relative;
  display: flex; flex-direction: column; gap: var(--s2);
  padding: 22px 22px 0;
  border-radius: 14px; overflow: hidden;
  background: linear-gradient(150deg, #132630 0%, #1B2233 52%, #13292B 100%);
  /* this page has no global `a` reset — every card class declares its own */
  text-decoration: none; color: #F3EEE4;
}
.home-worlds:active { transform: scale(0.99); }
.hw-copy { display: flex; flex-direction: column; gap: 7px; }
.hw-eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; color: #E9CB92;
}
.home-worlds h2 { font-family: var(--font-display); font-weight: 800; font-size: 22px; letter-spacing: -0.02em; }
.home-worlds p { color: #B4BCC4; font-size: 14px; max-width: 44ch; }
.hw-go { font-weight: 700; font-size: 14px; color: #E9CB92; }
.hw-plates { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.hw-plates img {
  display: block; width: 100%; height: 74px; object-fit: cover;
  border-radius: 6px 6px 0 0;
  opacity: 0.92;
}


/* ---- join with a code + one-phone strip (home) ---- */
.home-quick { display: flex; padding: 0 20px; margin: 4px 0 8px; }
.home-join {
  min-height: 44px; padding: 0 16px; border: 1.5px solid var(--line, #D9DCE3); border-radius: 6px;
  background: #fff; color: var(--ink); font: 700 15px/1 inherit; font-family: inherit;
}
.home-join:active { transform: scale(.98); }

/* ---- Home tab ---- */
.home-space {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; text-decoration: none; color: var(--ink);
  margin: 0 20px 10px; min-height: 64px; padding: 14px 16px; border: 1px solid var(--line, #E3E5EA); border-radius: 8px; background: #fff;
}
.home-space .hs-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.home-space b { font-size: 16px; font-weight: 800; }
.home-space .hs-copy span { color: var(--ink-soft); font-size: 13.5px; }
.home-space .hs-go { color: var(--ink-soft); flex: 0 0 auto; }
.home-space:active { transform: scale(.99); }

/* ---- Home dashboard ---- */
.home-dash { padding-bottom: 28px; }
.home-dash .home-hey { padding-bottom: 4px; }
.home-dash .home-hey p { color: var(--ink-soft); font-size: 14px; margin: 2px 0 0; }
.hd-stats { container: hdstats / inline-size; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; padding: 14px 20px 0; }
/* Home's card material for its plain notes (the strips page's): white with a faint cool
   gradient, a hairline edge, a soft shadow. */
.hs-empty {
  background: linear-gradient(180deg, #ffffff 0%, #f4f5f8 100%);
  border: 1px solid rgba(23, 24, 28, 0.06);
  box-shadow: 0 8px 20px rgba(60, 40, 60, 0.06), inset 0 1px 0 #ffffff;
}
/* the three numbers, in the habit-tracker kit the user pointed at (2026-10-20 — the week's and
   Our story's tiles, .wk-tile, wear the same): Home's white card, the Higgsfield sticker big on
   a soft blob of the tile's own tint (lilac Tried, pink Photo strips, peach Week streak), the
   number big in ink with a small unit beside it, the label under it. Each tile is a link or a
   button, so it carries no link styling (Tried, an <a>, showed underlined purple text). The row
   measures itself: a roomier tile once it has the width, and from ~860px the picture beside
   the number instead of over it, so a wide tile isn't one sticker and empty space. */
.hd-stat {
  --tl-tint: #FFE8F0;
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  min-width: 0; margin: 0; padding: 12px 12px 14px; border-radius: 22px;
  background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
  font: inherit; color: var(--h-ink); text-align: left; text-decoration: none;
  cursor: pointer; -webkit-tap-highlight-color: transparent; transition: transform .12s ease;
}
a.hd-stat, a.hd-stat:visited, a.hd-stat:hover { color: var(--h-ink); text-decoration: none; }
.hd-stat:active { transform: scale(.97); }
.hd-stat:focus-visible { outline: 2px solid var(--h-deep); outline-offset: 2px; }
.hd-stat.is-tried { --tl-tint: #EFE9FF; }
.hd-stat.is-strips { --tl-tint: #FFE8F0; }
.hd-stat.is-streak { --tl-tint: #FFEEDF; }
.hd-stat-ic {
  flex: 0 0 auto; display: grid; place-items: center; width: 52px; height: 52px; margin-bottom: 8px;
  border-radius: 17px; background: var(--tl-tint);
}
.hd-stat-art { display: block; width: 42px; height: 42px; object-fit: contain; filter: drop-shadow(0 3px 4px rgba(60, 40, 60, .12)); }
.hd-num { display: flex; align-items: baseline; column-gap: 4px; flex-wrap: wrap; min-width: 0; }
.hd-num b { font-family: var(--font-display); font-size: 28px; line-height: 1.05; font-weight: 800; letter-spacing: -.03em; color: var(--h-ink); font-variant-numeric: tabular-nums; }
.hd-of { color: var(--h-muted); font-size: 12.5px; font-weight: 700; }
.hd-label { max-width: 100%; font-size: 12.5px; font-weight: 600; line-height: 1.25; color: var(--h-muted); overflow-wrap: break-word; }
@container hdstats (min-width: 560px) {
  .hd-stat { padding: 16px 16px 18px; gap: 4px; }
  .hd-stat-ic { width: 64px; height: 64px; margin-bottom: 10px; border-radius: 20px; }
  .hd-stat-art { width: 52px; height: 52px; }
  .hd-num b { font-size: 32px; }
  .hd-label, .hd-of { font-size: 13.5px; }
}
@container hdstats (min-width: 860px) {
  .hd-stat {
    display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "art num" "art label";
    align-content: center; align-items: center; gap: 2px 16px; padding: 16px 18px;
  }
  .hd-stat-ic { grid-area: art; width: 72px; height: 72px; margin: 0; border-radius: 22px; }
  .hd-stat-art { width: 58px; height: 58px; }
  .hd-num { grid-area: num; align-self: end; }
  .hd-label { grid-area: label; align-self: start; }
  .hd-num b { font-size: 34px; }
}
@media (prefers-reduced-motion: reduce) { .hd-stat { transition: none; } }
/* THE WEEK STREAK tile, the middle one (2026-10-21, the user: "make it like the band, shaped like
   the small widgets"): the small streak widget's look — the mood's solid colour with its soft
   top-left light, the widgets' flame for the run's length and the weeks big in white, the label,
   one short line, and the pink + blue pair at the bottom right, its art 3px past both edges
   (sized and moved inline by homeWidgets.js from shared/widgetArt.js). It keeps its row's
   height; a tap opens Our story. */
.hd-stat.hd-streak {
  --sk-top: #1FBFAE; --sk-deep: #0E9C8F;
  /* a column at every width (the other tiles turn into a grid from ~860px) */
  display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start;
  position: relative; isolation: isolate; overflow: hidden; gap: 2px;
  border: 0; color: #fff; background: linear-gradient(180deg, var(--sk-top) 0%, var(--sk-deep) 100%);
  box-shadow: 0 12px 22px -16px var(--sk-deep);
}
.hd-streak .hds-ground { position: absolute; inset: 0; z-index: -1; background: radial-gradient(120% 80% at 12% 0%, rgba(255, 255, 255, .24), transparent 58%); pointer-events: none; }
.hd-streak[data-mood="calm"] { --sk-top: #1FBFAE; --sk-deep: #0E9C8F; }
.hd-streak[data-mood="nudge"] { --sk-top: #1CB0F6; --sk-deep: #1590D6; }
.hd-streak[data-mood="plead"] { --sk-top: #A36BF2; --sk-deep: #8247E0; }
.hd-streak[data-mood="lastchance"] { --sk-top: #FF5B4F; --sk-deep: #E0392D; }
.hd-streak[data-mood="party"] { --sk-top: #FFB020; --sk-deep: #FF8A00; }
.hd-streak[data-mood="start"] { --sk-top: #5BC51E; --sk-deep: #3FA00C; }
.hd-streak:focus-visible { outline: 3px solid var(--sk-deep); outline-offset: 2px; }
.hds-head { position: relative; z-index: 1; display: flex; align-items: center; gap: 2px; }
.hds-flame { display: block; width: auto; height: 28px; flex: none; filter: drop-shadow(0 2px 3px rgba(60, 20, 10, .2)); }
.hds-n { font-family: var(--font-display); font-size: 28px; font-weight: 900; line-height: 1; letter-spacing: -.03em; color: #fff; font-variant-numeric: tabular-nums; text-shadow: 0 1px 2px rgba(0, 0, 0, .18); }
.hds-label { position: relative; z-index: 1; font-size: 12.5px; font-weight: 800; line-height: 1.2; text-shadow: 0 1px 2px rgba(0, 0, 0, .16); }
.hds-line { position: relative; z-index: 1; max-width: 62%; font-size: 11.5px; font-weight: 650; line-height: 1.25; opacity: .92; text-shadow: 0 1px 2px rgba(0, 0, 0, .16); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hds-art { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.hds-pose { position: absolute; right: 0; bottom: 0; display: block; max-width: none; }
/* a narrow tile (three across a phone or an iPad) keeps the flame, the weeks and the label: the
   line only shows once the tile is wide enough to hold it beside the pair (a ~860px row) */
@container hdstats (max-width: 859px) { .hds-line { display: none; } }
@container hdstats (min-width: 560px) {
  .hds-flame { height: 34px; }
  .hds-n { font-size: 34px; }
  .hds-label { font-size: 13.5px; }
}
@media (prefers-reduced-motion: no-preference) {
  .hds-pose { animation: hw-bob 3.6s ease-in-out infinite; transform-origin: 100% 100%; }
  .hd-streak[data-mood="party"] .hds-pose { animation: hds-hop 1.6s cubic-bezier(.34, 1.45, .5, 1) infinite; }
}
@keyframes hds-hop { 0%, 60%, 100% { transform: translateY(0); } 20% { transform: translateY(-6px); } 40% { transform: translateY(0) scale(1.02, .98); } }

.home-dash .home-meet { margin: 12px 20px 0; }
/* a section's heading: one size, ink; its one quiet action (Edit, Write) at the row's right */
.home-dash .home-label { display: block; margin: 0; padding: 28px 20px 12px; font-size: 17px; font-weight: 700; letter-spacing: -.01em; color: var(--h-ink); }
.hd-quick { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; padding: 0 20px 4px; }
/* Jump in: Home's white card, the game's coin and its name (the chunky 3D tiles came off
   2026-10-19 — "too busy") */
.hd-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center;
  min-height: 108px; padding: 14px 6px 12px; border-radius: 18px; text-decoration: none; color: var(--h-ink);
  background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s ease;
}
.hd-card img { width: 56px; height: 56px; object-fit: contain; }
.hd-card b { font-size: 13px; font-weight: 700; line-height: 1.2; }
.hd-card:active { transform: scale(.97); }
@media (prefers-reduced-motion: no-preference) { .hd-stat, .hd-card { animation: hd-in .4s cubic-bezier(.2, 1, .4, 1) backwards; } .hd-slot:nth-child(2) > .hd-card { animation-delay: 40ms; } .hd-slot:nth-child(3) > .hd-card { animation-delay: 80ms; } .hd-slot:nth-child(4) > .hd-card { animation-delay: 120ms; } .hd-slot:nth-child(5) > .hd-card { animation-delay: 160ms; } .hd-slot:nth-child(6) > .hd-card { animation-delay: 200ms; } .hd-slot:nth-child(n+7) > .hd-card { animation-delay: 240ms; } }
@keyframes hd-in { from { opacity: 0; transform: translateY(10px); } }

/* ---- Jump in, arranged by the user (app/jumpIn.js, architecture.md §35) --------------
   The label row carries Edit. Editing sets every tile jiggling, each slot on its own
   phase like loose icons on an iPhone home screen, with a minus badge on its corner and a
   dashed + tile at the end that opens the game sheet. Only the first paint plays the
   entrance; .is-settled keeps a repaint after an edit from replaying it. */
.home-dash .home-label-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 28px 20px 12px; }
.home-dash .home-label-row .home-label { padding: 0; }
/* Edit: a quiet word at the row's right, like every section's one action; editing, it's the
   pink "Done" pill */
.jump-edit {
  min-height: 32px; margin-right: -4px; padding: 0 8px; border-radius: 999px;
  border: 0; background: none;
  color: var(--h-deep); font: 700 14px/1 var(--font-body); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.jump-edit.is-on { margin-right: 0; padding: 0 14px; background: var(--h-pink); color: #fff; }
.hd-slot { position: relative; display: flex; min-width: 0; }
.hd-slot > .hd-card { flex: 1; min-width: 0; }
.hd-quick.is-settled .hd-card { animation: none; }
.hd-card-x {
  position: absolute; top: -8px; left: -8px; z-index: 2;
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  background: #6b6f76; color: #fff; cursor: pointer;
  box-shadow: 0 2px 6px rgba(23, 24, 28, 0.25);
  -webkit-tap-highlight-color: transparent;
}
.hd-card-x::after { content: ""; position: absolute; inset: -9px; } /* a finger-sized target around a small badge */
.hd-quick.is-editing .hd-card-x { display: inline-flex; animation: hd-badge .18s cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes hd-badge { from { transform: scale(0); } }
.hd-quick.is-editing .hd-slot:not(.is-add) { animation: hd-jiggle .26s ease-in-out var(--jd, 0ms) infinite alternate; transform-origin: 50% 60%; }
.hd-quick.is-editing .hd-card { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.hd-quick.is-editing .hd-card:active { transform: none; }
@keyframes hd-jiggle { from { transform: rotate(-1.6deg); } to { transform: rotate(1.6deg); } }
.hd-slot.is-leaving { animation: hd-leave .17s ease-in forwards !important; }
@keyframes hd-leave { to { transform: scale(0.4); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .hd-quick.is-editing .hd-slot { animation: none; } }
.hd-card-add {
  justify-content: center; font: inherit; cursor: pointer;
  background: transparent; color: var(--h-muted);
  border: 1.5px dashed #D9DBE2;
  box-shadow: none;
}
.hd-card-add:active { transform: none; box-shadow: none; background: #fff; }
.hd-add-ic {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--h-tint); color: var(--h-pink);
}

/* the game sheet: every game in the app, tap to put it on Home or take it off */
.jump-sheet { max-height: 86vh; max-height: 86dvh; gap: 14px; }
.jump-sheet-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.jump-sheet-count { font-size: 13px; font-weight: 700; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
/* the scroller: "Picked for you" (a soft pink panel, the onboarding's three) over every
   other game (2026-10-13 — the picks moved here from a card on Home) */
.jump-sheet-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 16px; padding: 6px 2px 4px;
}
.jump-sheet-sec { display: flex; flex-direction: column; gap: 10px; }
.jump-sheet-sec.is-picked {
  padding: 12px 12px 14px; border-radius: 22px;
  background: linear-gradient(180deg, #FFF3F7 0%, #FFFFFF 100%);
  border: 1px solid rgba(236, 95, 147, 0.2);
}
.jump-sheet-sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 0 2px; }
.jump-sheet-sec-head b { font-size: 15px; font-weight: 800; letter-spacing: -.01em; }
.jump-sheet-sec.is-picked .jump-sheet-sec-head b { color: #c2416f; }
.jump-sheet-sec-head span { font-size: 12.5px; color: var(--ink-soft); text-align: right; }
.jump-sheet-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.jump-pick {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 5px;
  min-height: 108px; padding: 10px 4px 11px; border-radius: 18px;
  border: 2px solid transparent;
  background: linear-gradient(180deg, color-mix(in srgb, var(--tint, #fff) 50%, #fff) 0%, var(--tint, #fff) 100%);
  color: var(--ink); font: inherit; text-align: center; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s ease, border-color .15s ease;
}
.jump-pick:active { transform: scale(0.96); }
.jump-pick img { width: 54px; height: 54px; object-fit: contain; filter: drop-shadow(0 4px 5px rgba(60, 40, 60, 0.16)); }
.jump-pick b { font-size: 12.5px; font-weight: 800; line-height: 1.15; }
.jump-pick-mark {
  position: absolute; top: 7px; right: 7px;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, 0.92); color: var(--ink-soft);
  box-shadow: 0 1px 4px rgba(23, 24, 28, 0.12);
}
.jump-pick.is-on { border-color: #ec5f93; }
.jump-pick.is-on .jump-pick-mark { background: #ec5f93; color: #fff; }
.jump-pick:disabled { opacity: 0.4; cursor: default; }
.jump-sheet-done {
  flex: none; min-height: 50px; border: 0; border-radius: 14px;
  background: var(--ink); color: #fff; font: 800 15px/1 var(--font-body); cursor: pointer;
}

/* ---- Strips | Scrapbook (app/app.js renderHome, architecture.md §35) ----------------
   Two buttons side by side under the memories' slideshow, on Home's white card (.hd-card)
   with the love path's art: Strips pushes the strips page, Scrapbook opens the book. Bigger
   than a Jump-in tile and a line under the name, so they don't read as two more games. */
/* since 2026-10-21 the Scrapbook alone: one wide row on a phone — its coin, the name and its line,
   a chevron — and a centred card beside the slideshow from 1024px */
.home-keep-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; padding: 0 20px 4px; }
.hk-card {
  flex-direction: row; justify-content: flex-start; gap: 14px; min-height: 0; padding: 14px 16px; text-align: left;
  font: inherit; cursor: pointer;
}
.hk-card img { flex: none; width: 64px; height: 64px; }
.hk-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.hk-card b { font-size: 16px; letter-spacing: -.01em; }
.hk-go { flex: none; display: inline-flex; color: #C9CDD5; }
.hk-go .icon svg { display: block; }
.hk-note {
  max-width: 100%; font-size: 12.5px; font-weight: 500; line-height: 1.25; color: var(--h-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---- the strips page (app/homeStrips.js, architecture.md §35) ------------------------
   A print keeps its paper's real shape (2×6 tall, 6×4 wide), centred in a fixed cell, so a
   row of mixed sizes still lines up. A locked strip shows WITH THE WATERMARK (§5c, made by
   client/core/stripWatermark.js) and a small lock in the corner; the blur is only the
   fallback for a strip the device couldn't read. */

.sp-card {
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
  padding: 0; border: 0; background: none;
  color: var(--ink); font: inherit; text-align: left; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sp-card-art {
  position: relative; display: grid; place-items: center; aspect-ratio: 0.78; padding: 12% 11%;
  border-radius: 18px; overflow: hidden;
  background: linear-gradient(180deg, #ffffff 0%, #f1f2f6 100%);
  border: 1px solid rgba(23, 24, 28, 0.06);
  box-shadow: 0 8px 20px rgba(60, 40, 60, 0.06), inset 0 1px 0 #ffffff;
  transition: transform .15s ease;
}
.sp-card:active .sp-card-art { transform: scale(0.97); }
.sp-print {
  position: relative; display: block; height: 100%; aspect-ratio: var(--ar, 0.6667); max-width: 100%;
  overflow: hidden; border-radius: 2px; background: #fff;
  box-shadow: 0 1px 2px rgba(23, 24, 28, 0.1), 0 8px 18px rgba(60, 40, 60, 0.16);
}
.sp-print.is-wide { width: 100%; height: auto; }
.sp-print img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sp-print img.is-blurred { filter: blur(8px) saturate(0.9); transform: scale(1.12); }
/* A free account's strip anywhere on Home (§5c, 2026-10-14): blurred, and a tap opens the paywall. */
img.is-locked-strip { filter: blur(8px) saturate(0.9); }
.hs-lock {
  position: absolute; top: 8px; right: 8px;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(23, 24, 28, 0.55); color: #fff; pointer-events: none;
}
/* a strip still going up from this device (history.js outbox) */
.hs-saving {
  position: absolute; left: 50%; bottom: 8px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 7px 3px 5px; border-radius: 999px;
  background: rgba(23, 24, 28, 0.62); color: #fff;
  font-size: 10px; font-weight: 800; white-space: nowrap; pointer-events: none;
}
.hs-saving i { width: 8px; height: 8px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.35); border-top-color: #fff; animation: hs-spin .8s linear infinite; }
@keyframes hs-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .hs-saving i { animation: none; } }
.sp-card-cap { display: flex; flex-direction: column; gap: 1px; min-width: 0; padding: 0 4px; }
.sp-card-cap b { font-size: 13px; font-weight: 800; }
.sp-card-cap span { font-size: 12px; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.hs-empty { display: flex; align-items: center; gap: 14px; margin: 0 20px 14px; padding: 16px; border-radius: 18px; }
.hs-empty-ic { flex: none; width: 44px; height: 44px; border-radius: 14px; display: grid; place-items: center; background: #ffe4ee; color: #c2416f; }
.hs-empty-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.hs-empty-copy b { font-size: 15px; font-weight: 800; }
.hs-empty-copy span { font-size: 13px; line-height: 1.35; color: var(--ink-soft); }
.hs-empty-go {
  flex: none; min-height: 40px; padding: 0 16px; border: 0; border-radius: 12px;
  display: inline-flex; align-items: center;
  background: #ec5f93; color: #fff; font: 800 14px/1 var(--font-body); text-decoration: none; cursor: pointer;
}
/* "N strips still carry the watermark": the words get the room, the button wraps under them
   when the line is short — full width on a phone, never squeezing the copy to a word a line */
.sp-lockbar { flex-wrap: wrap; row-gap: 12px; }
.sp-lockbar .hs-empty-copy { flex: 1 1 200px; }
.sp-lockbar .hs-empty-go { justify-content: center; white-space: nowrap; }
@media (max-width: 559px) {
  .sp-lockbar { align-items: flex-start; padding: 14px; gap: 12px; }
  .sp-lockbar .hs-empty-ic { width: 40px; height: 40px; border-radius: 12px; }
  .sp-lockbar .hs-empty-go { flex: 1 1 100%; min-height: 46px; border-radius: 14px; font-size: 15px; }
}

/* a page pushed over Home from the right (the strips page, a game's page, the week): it
   covers the tab bar (2026-10-12, the user's call: no navbar on a detail page; its own
   Back is the way out, and the floating bar sat over its last cards) */
.sp-page {
  position: fixed; inset: 0; z-index: 230;
  display: flex; flex-direction: column;
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  background: var(--paper, #F8F9FB);
  padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  animation: sp-push .32s cubic-bezier(.2, 1, .4, 1) both;
}
.sp-page.is-leaving { animation: sp-pop .22s ease-in forwards; }
@keyframes sp-push { from { transform: translateX(100%); } }
@keyframes sp-pop { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .sp-page { animation: none; } .sp-page.is-leaving { animation: none; opacity: 0; } }
.sp-bar {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center;
  padding: calc(6px + env(safe-area-inset-top, 0px)) 8px 6px;
  background: rgba(248, 249, 251, 0.86);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
}
.sp-back {
  display: inline-flex; align-items: center; gap: 0; min-height: 44px; padding: 0 12px 0 2px;
  border: 0; background: none; color: #c2416f; font: 600 16px/1 var(--font-body); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sp-back .icon { display: inline-flex; }
.sp-head { padding: 2px 20px 14px; }
.sp-head h1 { margin: 0; font-size: 30px; font-weight: 800; letter-spacing: -0.03em; }
.sp-sub { margin: 2px 0 0; font-size: 14px; color: var(--ink-soft); }
/* flex: none — the page is a full-height flex column, and a sideways-scrolling row has no
   minimum height there: with a long shelf it was squeezed to half its height and the bar
   under it ran over the chips (2026-10-20) */
.sp-bar, .sp-head { flex-shrink: 0; }
.sp-chips { flex: none; display: flex; gap: 8px; overflow-x: auto; padding: 0 20px 18px; scrollbar-width: none; }
.sp-chips::-webkit-scrollbar { display: none; }
.sp-chips:empty { display: none; }
.sp-chip {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  min-height: 38px; padding: 0 11px 0 14px; border-radius: 999px;
  border: 1px solid rgba(23, 24, 28, 0.08);
  background: linear-gradient(180deg, #ffffff 0%, #f4f5f8 100%);
  color: var(--ink); font: 700 13.5px/1 var(--font-body); cursor: pointer;
  box-shadow: 0 4px 10px rgba(60, 40, 60, 0.05), inset 0 1px 0 #ffffff;
  -webkit-tap-highlight-color: transparent;
}
.sp-chip .icon { display: inline-flex; color: var(--ink-soft); }
.sp-chip.is-set { padding-left: 4px; background: #ffe4ee; border-color: rgba(236, 95, 147, 0.4); color: #b23a66; }
.sp-chip.is-set .icon { color: #b23a66; }
.sp-chip-art {
  flex: none; width: 28px; height: 28px; border-radius: 50%; overflow: hidden;
  display: grid; place-items: center; background: #fff;
}
.sp-chip-clear { padding: 0 14px; color: var(--ink-soft); }
.sp-content { flex: 1 0 auto; display: flex; flex-direction: column; padding: 0 20px; }
.sp-content .hs-empty { margin: 0 0 18px; }
.sp-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px 14px; }
/* the page opens before the strips land: soft placeholder prints (homeStrips.js) */
.sp-skel { display: block; aspect-ratio: 3 / 4; border-radius: 16px; background: linear-gradient(100deg, #EEF0F5 30%, #F7F8FB 50%, #EEF0F5 70%) 0 0 / 200% 100%; animation: sp-skel 1.2s ease-in-out infinite; }
@keyframes sp-skel { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .sp-skel { animation: none; } }
.sp-none { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 56px 0; }
.sp-none b { font-size: 16px; font-weight: 800; }
/* no strips at all: the booth, the line and the button, in the middle of the page's height */
.sp-none.is-empty { flex: 1; justify-content: center; gap: 6px; padding: 24px 0 40px; text-align: center; }
.sp-none-art { height: 150px; width: auto; margin-bottom: 14px; filter: drop-shadow(0 10px 14px rgba(60, 40, 60, 0.16)); }
.sp-none.is-empty b { font-size: 19px; letter-spacing: -.01em; }
.sp-none.is-empty > span { max-width: 260px; font-size: 14px; line-height: 1.4; color: var(--ink-soft); }
.sp-none.is-empty .hs-empty-go { margin-top: 14px; min-height: 48px; padding: 0 28px; border-radius: 14px; font-size: 15.5px;
  box-shadow: 0 8px 18px rgba(236, 95, 147, 0.3); }

/* a chip's sheet: the options as pictures, one tap picks and closes */
.sp-sheet { max-height: 80vh; max-height: 80dvh; gap: 14px; }
.sp-opts {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; padding: 4px 2px 6px;
}
.sp-opt {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 7px 7px 10px; border-radius: 18px; border: 2px solid transparent;
  background: linear-gradient(180deg, #ffffff 0%, #f4f5f8 100%);
  box-shadow: 0 4px 12px rgba(60, 40, 60, 0.06), inset 0 0 0 1px rgba(23, 24, 28, 0.05);
  color: var(--ink); font: inherit; text-align: center; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s ease, border-color .15s ease;
}
.sp-opt:active { transform: scale(0.97); }
.sp-opt-art {
  width: 100%; aspect-ratio: 1; border-radius: 12px; overflow: hidden;
  display: grid; place-items: center; background: #eef0f4;
}
.sp-opt b { font-size: 12.5px; font-weight: 800; line-height: 1.15; }
.sp-opt-n { font-size: 11.5px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.sp-opt-mark {
  position: absolute; top: 11px; right: 11px; width: 20px; height: 20px; border-radius: 50%;
  display: none; place-items: center; background: #ec5f93; color: #fff;
  box-shadow: 0 1px 4px rgba(23, 24, 28, 0.18);
}
.sp-opt.is-on { border-color: #ec5f93; }
.sp-opt.is-on .sp-opt-mark { display: grid; }

/* the option pictures: they fill whatever holds them (a sheet tile or a 28px chip) */
.sp-art-img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sp-opts.is-frame .sp-art-img { object-position: 50% 18%; }
.sp-art-icon { display: grid; place-items: center; color: var(--ink-soft); }
.sp-art-swatch, .sp-art-strip {
  height: 84%; aspect-ratio: 1 / 3; display: grid; grid-template-rows: repeat(4, 1fr); gap: 5%; padding: 6%;
  border-radius: 2px; box-shadow: 0 2px 6px rgba(23, 24, 28, 0.14);
}
.sp-art-swatch { background: var(--bg, #fff); }
.sp-art-swatch i { background: var(--slot, #eef0f4); border-radius: 1px; }
.sp-art-strip { background: #fff; }
.sp-art-strip i { border-radius: 1px; background: #ffd6e4; }
.sp-art-strip i:nth-child(even) { background: #dcebff; }
.sp-paperart {
  display: grid; gap: 5%; padding: 6%; background: #fff; border-radius: 2px;
  box-shadow: 0 2px 8px rgba(23, 24, 28, 0.14);
}
.sp-paperart i { background: linear-gradient(135deg, #ffd6e4 0%, #dcebff 100%); border-radius: 1px; }
.sp-paperart.is-vertical { height: 84%; aspect-ratio: 1 / 3; grid-template-rows: repeat(4, 1fr); }
.sp-paperart.is-grid { width: 80%; aspect-ratio: 3 / 2; grid-template: repeat(2, 1fr) / repeat(2, 1fr); }
.sp-paperart.is-duo { height: 80%; aspect-ratio: 2 / 3; grid-template-rows: repeat(2, 1fr); }
.sp-paperart.is-polaroid { height: 78%; aspect-ratio: 3.5 / 4.25; grid-template-rows: 1fr; padding: 6% 6% 22%; }

/* the strip, big: over everything, the tab bar included */
.hs-viewer {
  position: fixed; inset: 0; z-index: 320;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  padding: calc(64px + env(safe-area-inset-top, 0px)) 20px calc(28px + env(safe-area-inset-bottom, 0px));
  background: rgba(20, 20, 24, 0.88);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  animation: veil-in 180ms ease both;
}
.hs-viewer-img {
  display: block; max-width: 100%; max-height: 60vh; max-height: 60dvh; object-fit: contain;
  border-radius: 3px; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  animation: hs-rise .3s cubic-bezier(.2, 1, .4, 1) both;
}
@keyframes hs-rise { from { opacity: 0; transform: translateY(14px) scale(.98); } }
.hs-viewer-meta { display: flex; flex-direction: column; align-items: center; gap: 3px; color: #fff; text-align: center; }
.hs-viewer-meta b { font-size: 16px; font-weight: 800; }
.hs-viewer-meta span { font-size: 13px; color: rgba(255, 255, 255, 0.72); }
.hs-viewer-note { margin: -6px 0 0; max-width: 32ch; font-size: 13px; line-height: 1.4; color: rgba(255, 255, 255, 0.72); text-align: center; }
.hs-viewer-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.hs-btn {
  min-height: 48px; padding: 0 20px; border: 0; border-radius: 14px;
  display: inline-flex; align-items: center; gap: 8px;
  background: rgba(255, 255, 255, 0.14); color: #fff; font-family: inherit; font-weight: 800; font-size: 15px;
  text-decoration: none; cursor: pointer;
}
.hs-btn:disabled { opacity: 0.6; }
.hs-btn.is-primary { background: #ec5f93; }
.hs-viewer-x {
  position: absolute; top: calc(12px + env(safe-area-inset-top, 0px)); right: 14px;
  width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%;
  display: grid; place-items: center; background: rgba(255, 255, 255, 0.14); color: #fff; cursor: pointer;
}

/* Home dashboard spacing: the shared #app shell pads and centres; this page owns its layout. */
#app:has(.home-dash) { padding: 0; justify-content: flex-start; }
.home-dash { padding-left: 0; padding-right: 0; gap: 0; max-width: 560px; }
.home-dash .home-bar { padding-left: 20px; padding-right: 20px; }
.home-dash .home-hey { padding: 4px 20px 6px; }
.home-dash .home-hey h1 { margin: 0; }

/* the header avatar with a picture in it (client/core/avatar.js) — this page doesn't load
   client/ui/app.css, so the picture's own rules are repeated here */
.avatar-pic { display: block; width: 100%; height: 100%; border-radius: 50%; overflow: hidden; }
.avatar-pic img { display: block; width: 100%; height: 100%; object-fit: cover; }
.avatar-pic.is-default img { transform: translateY(6%) scale(1.06); }
.avatar-pic.is-letter { display: grid; place-items: center; color: #fff;
  background: linear-gradient(135deg, #ff7ba3 0%, #b07cf0 55%, #5fa0ff 100%); }
.home-ava.has-pic { padding: 0; overflow: hidden; }
.home-ava .avatar-pic { width: 100%; height: 100%; }

/* ---- OUR WEEK (2026-10, app/homeWidgets.js) ------------------------------------------------
   Under Up next, on Home's white card (2026-10-19, "too busy" — the gradient, the candy gloss
   and the pair in a speech bubble came off; the pair is the streak card's now): the title,
   the week's number, seven flat bars (pink strips over blue games, a small grey dot for an
   empty day, today's label in pink) and one quiet line on how the week went. */
.hw {
  position: relative; display: flex; flex-direction: column; gap: 8px; min-width: 0;
  padding: 16px; border-radius: var(--h-r);
  background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.hw-week { margin: 12px 20px 0; }
.hw-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.hw-title { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -.01em; color: var(--h-ink); }
.hw-legend { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; color: var(--h-muted); }
.hw-legend i { width: 8px; height: 8px; border-radius: 50%; margin-left: 4px; }
.hw-legend i.is-p { background: #FF8DB0; } .hw-legend i.is-b { background: #7FB0FF; }
.hw-week-sum { display: flex; align-items: baseline; gap: 6px; }
.hw-week-n { font-family: var(--font-display); font-size: 28px; font-weight: 800; letter-spacing: -.03em; line-height: 1; color: var(--h-ink); }
.hw-week-sum span { font-size: 13px; font-weight: 600; color: var(--h-muted); }
.hw-bars { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; align-items: end; height: 96px; padding-top: 4px; }
.hw-bar { display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; min-width: 0; }
.hw-bar-track { flex: 1; width: 100%; max-width: 26px; display: flex; flex-direction: column-reverse; justify-content: flex-start; align-items: center; gap: 3px; }
/* a flat bar per kind, rising one day after another */
.hw-seg {
  display: block; width: 100%; height: var(--h); min-height: 8px; border-radius: 6px;
  transform-origin: bottom; animation: hw-rise .5s cubic-bezier(.2, 1, .4, 1) both; animation-delay: calc(var(--i, 0) * 45ms);
}
.hw-seg.is-p { background: #FF9DBB; }
.hw-seg.is-b { background: #8DB8FF; }
@keyframes hw-rise { from { transform: scaleY(0); } }
/* a day with nothing yet: a small grey dot on the floor */
.hw-seed { display: block; width: 8px; height: 8px; border-radius: 50%; background: #E3E5EA; }
.hw-day { min-width: 18px; text-align: center; font-size: 11.5px; font-weight: 600; line-height: 18px; color: var(--h-muted); }
.hw-bar.is-today .hw-day { padding: 0 6px; border-radius: 999px; color: #fff; background: var(--h-pink); font-weight: 700; }
.hw-bar.is-today .hw-seed { background: #F7B9CF; }
.hw-line { margin: 2px 0 0; font-size: 13px; font-weight: 500; line-height: 1.35; color: var(--h-muted); }
@keyframes hw-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }

/* the card is a button: one laid over the whole of it, under everything else */
.hw-week { transition: transform .12s ease; }
.hw-open {
  position: absolute; inset: 0; z-index: 0; padding: 0; border: 0; border-radius: inherit;
  background: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.hw-open:focus-visible { outline: 2px solid var(--h-deep); outline-offset: 2px; }
.hw-week > :not(.hw-open) { position: relative; pointer-events: none; }
.hw-week:has(.hw-open:active) { transform: scale(.985); }
.hw-head-r { display: inline-flex; align-items: center; gap: 6px; }
.hw-more { display: inline-grid; place-items: center; color: #B9BCC6; }
/* the card's parts sit in one box (.hw-week-in), so a WIDE card can lay them out as a grid —
   a container query measures the card and can only restyle what's inside it */
.hw-week { container: hwweek / inline-size; }
.hw-week-in {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; justify-content: space-between; gap: 8px;
}
/* A wide card (an iPad held upright, the web's full row when Our week has the row to itself,
   2026-10-20 — seven thin bars spread over 1,300px read as an empty card): the total big and
   the line under it on the left, the pair centred against the chart on the right, its bars a
   readable width. (Three small grey number boxes sat under the total for a day; they came off
   again — the user's call — the numbers live on the week's page.) A half-width card beside
   the moments card stays the phone's card. */
@container hwweek (min-width: 620px) {
  .hw-week-in {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr);
    grid-template-areas: "head head" "sum bars" "line bars";
    grid-template-rows: auto 1fr 1fr; gap: 8px 40px;
  }
  .hw-week-in > .hw-head { grid-area: head; margin-bottom: 4px; }
  .hw-week-in > .hw-week-sum { grid-area: sum; align-self: end; flex-wrap: wrap; row-gap: 2px; }
  .hw-week-in > .hw-line { grid-area: line; align-self: start; margin: 0; max-width: 34ch; font-size: 14px; }
  .hw-week .hw-week-in > .hw-bars { grid-area: bars; height: auto; min-height: 136px; align-self: stretch; padding: 8px 4px 0; }
  .hw-week-in .hw-bar-track { max-width: 34px; }
  .hw-week-in .hw-week-n { font-size: 44px; }
  .hw-week-in .hw-week-sum span { font-size: 14px; }
}
@container hwweek (min-width: 1000px) {
  .hw-week-in { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); column-gap: 56px; }
  .hw-week-in .hw-bar-track { max-width: 40px; }
}

/* ---- The week's page (2026-10-12, app/homeWidgets.js openPage) ------------------------------
   Pushed over Home from the OUR WEEK card (the tab bar stays, like the strips page). A
   calendar in the bar picks any day (the page then shows the seven days ending on it); the
   pair and the total against the week before; three tiles; the chart, where a day with
   something in it is a button that narrows the page to that day; then each day that had
   something as a timeline of cards (a strip and what it was made with; a game with whom,
   the score, how it went, how long, its own numbers); how a moment counts; a way to play. */
.wk-bar { justify-content: space-between; }
.wk-calbtn {
  display: grid; place-items: center; width: 44px; height: 44px; margin-right: 6px; padding: 0;
  border: 1px solid rgba(236, 95, 147, .18); border-radius: 14px; background: #fff; color: #c2416f;
  box-shadow: 0 3px 10px rgba(110, 69, 176, .1); cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.wk-calbtn:active { transform: scale(.94); }
.wk-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.wk-now {
  display: inline-flex; align-items: center; gap: 5px; min-height: 30px; margin-top: 2px; padding: 0 11px;
  border: 0; border-radius: 999px; background: #FFE4EE; color: #b23a66; font: 700 12.5px/1 var(--font-body); cursor: pointer;
}
.wk-now[hidden] { display: none; }
/* Both pages — the week's and Our story — share one frame (2026-10-20, "tidy it, especially
   on a computer, and make the difference clear"): the bar, then ONE centred column
   (.wk-wrap: 820px, 1,120px once two columns fit) whose header says what the page is (a line
   under the title) and carries the [Week | All time] switch, then the content in two parts —
   the summary (.wk-aside) and the detail (.wk-main). On a phone the two are one column, in
   the old order (the note and the button last, via display: contents + order); from a 600px
   column the note and the button share a row; from a 900px column the summary is a sticky
   column on the left and the detail runs on the right. The page measures itself (a container
   query), so the sidebar's width is already taken off. The bar's back link lines up with the
   column. */
.sp-page.wk-page:not(.mp-page), .sp-page.st-page:not(.mp-page) {
  container: wkpage / inline-size; padding-left: 0; padding-right: 0;
}
.wk-page, .st-page { --wk-col: 820px; }
.wk-page.is-instant:not(.is-leaving) { animation: none; } /* swapped in from Our story, no slide */
.wk-page > .sp-bar, .st-page > .sp-bar {
  padding-left: max(8px, calc((100% - var(--wk-col)) / 2 + 8px));
  padding-right: max(8px, calc((100% - var(--wk-col)) / 2 + 8px));
}
.wk-wrap { flex: none; width: 100%; max-width: var(--wk-col); margin: 0 auto; }
.st-page.is-empty > * { --wk-col: 640px; }
.wk-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 14px 24px; }
.wk-head-copy { display: flex; flex-direction: column; gap: 2px; flex: 1 1 280px; min-width: 0; }
.wk-what { margin: 2px 0 4px; max-width: 46ch; font-size: 14.5px; font-weight: 500; line-height: 1.4; color: var(--h-muted); }
.wk-head .sp-sub { margin: 0; font-weight: 600; color: var(--h-ink); }
/* the switch: two halves on a grey pill, where you are in white */
.wk-seg {
  flex: 1 1 260px; max-width: 420px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; border-radius: 999px; background: var(--h-grey);
}
.wk-seg-btn {
  min-width: 0; min-height: 40px; padding: 0 16px; border: 0; border-radius: 999px; background: none;
  color: var(--h-muted); font: 700 14px/1 var(--font-body); white-space: nowrap; cursor: pointer;
  -webkit-tap-highlight-color: transparent; transition: background .15s ease, color .15s ease, box-shadow .15s ease;
}
.wk-seg-btn:not(.is-on):hover { color: var(--h-ink); }
.wk-seg-btn:not(.is-on):active { transform: scale(.97); }
.wk-seg-btn.is-on { background: #fff; color: var(--h-deep); cursor: default; box-shadow: 0 1px 2px rgba(23, 24, 28, .06), 0 4px 12px rgba(60, 40, 60, .08); }
.wk-seg-btn:focus-visible { outline: 2px solid var(--h-deep); outline-offset: 2px; }
.wk-content { display: flex; flex-direction: column; gap: 14px; padding: 0 20px; }
/* a phone: the two parts are one column, the note and the button last */
.wk-aside, .wk-main { display: contents; }
.wk-main > * { order: 1; }
.wk-foot { order: 2; display: flex; flex-direction: column; gap: 14px; }
.wk-foot > .wk-note { margin: 0; }
.wk-foot > .wk-cta { margin: 0 0 8px; }
@container wkpage (min-width: 600px) {
  .wk-head { padding-bottom: 18px; }
  .wk-seg { flex: 0 0 auto; min-width: 280px; }
  /* the note beside the button, the button as wide as its words */
  .wk-foot { flex-direction: row; align-items: center; gap: 16px; }
  .wk-foot > .wk-note { flex: 1 1 auto; }
  .wk-foot > .wk-cta { flex: 0 0 auto; margin: 0; padding: 0 26px; }
  .wk-content.is-empty .wk-foot { justify-content: center; }
  .wk-chart .hw-bar-track { max-width: 34px; }
}
@container wkpage (min-width: 900px) {
  .wk-page > *, .st-page > * { --wk-col: 1120px; } /* an empty Our story keeps 640px (above) */
  .wk-head { padding: 8px 24px 22px; }
  .wk-head h1 { font-size: 34px; }
  .wk-content:not(.is-empty) {
    display: grid; grid-template-columns: minmax(300px, 360px) minmax(0, 1fr);
    align-items: start; gap: 24px 28px; padding: 0 24px;
  }
  .wk-content:not(.is-empty) > .wk-aside, .wk-content:not(.is-empty) > .wk-main { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
  /* the summary: the pair stacked over the numbers, as Our story's; the note over the button */
  .wk-aside .wk-hero { flex-direction: column; text-align: center; gap: 10px; padding: 18px 18px 20px; }
  .wk-aside .wk-duo { width: 136px; }
  .wk-aside .wk-hero-copy { align-items: center; }
  .wk-aside .wk-hero .hw-week-sum { justify-content: center; }
  .wk-aside .wk-hero .wk-chips { justify-content: center; }
  .wk-aside .wk-tile { padding: 12px 10px 13px; }
  .wk-aside .wk-tile-art { width: 60px; height: 50px; }
  .wk-aside .wk-foot { flex-direction: column; align-items: stretch; gap: 12px; }
  .wk-aside .wk-foot > .wk-cta { padding: 0 20px; }
  .wk-main > .wk-label:first-child, .wk-main > .wk-list-head:first-child { margin-top: 0; }
  .wk-chart .hw-bars { height: 200px; }
  .wk-chart .hw-bar-track { max-width: 40px; }
  .st-strip { height: 112px; }
  .st-strip img { max-width: 160px; }
  .wk-content.is-empty { padding: 0 24px; }
  /* tall enough to keep the summary in view while the days scroll by */
  @media (min-height: 760px) {
    .wk-content:not(.is-empty) > .wk-aside { position: sticky; top: calc(72px + env(safe-area-inset-top, 0px)); }
  }
}
/* the page's own ground on a wide screen: Home's soft pink and blue wash */
@media (min-width: 768px) {
  .sp-page.wk-page, .sp-page.st-page {
    background:
      radial-gradient(110% 50vh at 0% 0%, rgba(255, 214, 229, .34), transparent 62%),
      radial-gradient(110% 44vh at 100% 100%, rgba(207, 223, 255, .38), transparent 62%),
      var(--paper, #F8F9FB);
  }
}
.wk-hero {
  display: flex; align-items: center; gap: 12px; padding: 16px 16px 16px 10px; border-radius: 24px;
  background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.wk-duo { flex: 0 0 auto; width: 128px; height: auto; animation: hw-bob 3.2s ease-in-out infinite; }
.wk-hero-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; }
.wk-hero .hw-week-n { font-size: 40px; }
.wk-line { margin: 0; font-size: 14.5px; font-weight: 700; line-height: 1.3; color: var(--ink); }
.wk-delta {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px; border-radius: 999px;
  background: #fff; color: var(--ink-soft); font-size: 12.5px; font-weight: 700; box-shadow: 0 1px 3px rgba(60, 40, 90, .1);
}
.wk-delta.is-up { background: #E3F6EC; color: #1F7A4D; }
/* The number tiles, the week's and Our story's (statTile in app/homeWidgets.js; 2026-10-20, the
   user's habit-tracker reference — Home's three wear the same, .hd-stat): Home's white card,
   the Higgsfield sticker on a soft blob of the tile's own tint at the top, the number big with
   its unit small, the label under it (two lines rather than an ellipsis — "Streak terpanjang").
   Pink strips and blue games (the chart's own colours), lilac days together, peach for the
   longest streak's flame; "N of 7" adds seven little bars, the days that had something lit.
   Since 2026-10-21 each tile is its colour all over (a soft gradient, the number in its deep
   shade) with the widgets' art big on it, the pair, the calendar, the flame by length — the
   user: "make the icons clearer and the colours nicer".
   The row measures itself: three across a phone and in the wide page's summary column, a
   roomier tile on a tablet. */
.wk-tiles { container: wktiles / inline-size; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.wk-tile {
  --tl-bg: linear-gradient(160deg, #FFF3F8 0%, #FFDCE8 100%); --tl-deep: #C2416F; --tl-soft: #9C5A72;
  --tl-on: #FF8DB0; --tl-off: rgba(255, 255, 255, .7); --tl-glow: rgba(255, 110, 160, .35);
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px; min-width: 0;
  padding: 12px 12px 14px; border-radius: 22px;
  background: var(--tl-bg); border: 0;
  box-shadow: 0 12px 22px -16px var(--tl-glow), inset 0 0 0 1px rgba(255, 255, 255, .7);
}
.wk-tile.is-games { --tl-bg: linear-gradient(160deg, #F1F6FF 0%, #D8E5FF 100%); --tl-deep: #3D63C4; --tl-soft: #5A6E9C; --tl-on: #7FB0FF; --tl-glow: rgba(90, 140, 255, .32); }
.wk-tile.is-days { --tl-bg: linear-gradient(160deg, #F7F2FF 0%, #E4DAFF 100%); --tl-deep: #6B4CC9; --tl-soft: #6E6290; --tl-on: #A88DF6; --tl-glow: rgba(140, 110, 240, .32); }
.wk-tile.is-streak { --tl-bg: linear-gradient(160deg, #FFF6EC 0%, #FFDDBE 100%); --tl-deep: #C25A1C; --tl-soft: #956548; --tl-on: #F5A060; --tl-glow: rgba(255, 140, 60, .34); }
/* a soft light in the top corner, the art standing in it */
.wk-tile::before { content: ""; position: absolute; z-index: -1; right: -30px; top: -34px; width: 120px; height: 120px; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 255, 255, .85), rgba(255, 255, 255, 0)); pointer-events: none; }
.wk-tile-art { flex: 0 0 auto; display: grid; place-items: center; width: 64px; height: 52px; margin: -2px 0 6px -4px; }
.wk-tile-art img { display: block; width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 4px 6px rgba(60, 40, 60, .18)); }
.wk-tile.is-streak .wk-tile-art img, .wk-tile.is-days .wk-tile-art img { width: 88%; height: 100%; }
.wk-tile-v { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 4px; min-width: 0; }
.wk-tile-v b { font-family: var(--font-display); font-size: 28px; font-weight: 800; line-height: 1.05; letter-spacing: -.03em; color: var(--tl-deep); font-variant-numeric: tabular-nums; }
.wk-tile-v span { font-size: 12.5px; font-weight: 700; color: var(--tl-soft); }
.wk-tile-l { max-width: 100%; font-size: 12.5px; font-weight: 650; line-height: 1.25; color: var(--tl-soft); overflow-wrap: break-word; }
.wk-tile-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; width: 100%; margin-top: auto; padding-top: 9px; }
.wk-tile-week i { display: block; height: 6px; border-radius: 999px; background: var(--tl-off); }
.wk-tile-week i.is-on { background: var(--tl-on); }
@container wktiles (min-width: 480px) {
  .wk-tile { gap: 4px; padding: 16px 16px 18px; }
  .wk-tile-art { width: 84px; height: 66px; margin-bottom: 8px; }
  .wk-tile-v b { font-size: 34px; }
  .wk-tile-v span, .wk-tile-l { font-size: 13.5px; }
  .wk-tile-week { gap: 4px; padding-top: 12px; }
  .wk-tile-week i { height: 8px; }
}
/* the chart: every day is a button (an empty one too), all seven the same box so bars,
   seeds, letters and dates share one line; the picked one is ringed in pink */
.wk-chart .hw-bars { height: 178px; gap: 6px; }
.wk-chart .hw-bar.is-pick {
  margin: 0; padding: 4px 0 6px; border: 0; border-radius: 14px; background: none; color: inherit;
  font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background .15s ease, transform .12s ease;
}
.wk-chart .hw-bar.is-pick:active { transform: scale(.95); }
.wk-chart .hw-bar.is-sel { background: rgba(236, 95, 147, .1); box-shadow: inset 0 0 0 2px rgba(236, 95, 147, .4); }
.wk-chart .hw-bar.is-sel .hw-seed { border-color: #ec5f93; }
.wk-chart .hw-bar.is-sel:not(.is-today) .hw-day { padding: 0 6px; border-radius: 999px; background: var(--ink); color: #fff; }
.wk-chart .hw-bar.is-pick:focus-visible { outline: 3px solid #ec5f93; outline-offset: 1px; }
.wk-count { margin-bottom: 2px; font-size: 12px; font-weight: 800; line-height: 1; color: var(--ink); }
.wk-date { margin-top: -4px; font-size: 11px; font-weight: 600; color: var(--ink-soft); }
.wk-hint { margin: 0; font-size: 12.5px; font-weight: 600; color: var(--ink-soft); text-align: center; }
.wk-list-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; }
.wk-label { margin: 0; font-size: 18px; font-weight: 800; letter-spacing: -.01em; }
.wk-all {
  min-height: 34px; padding: 0 14px; border: 1px solid rgba(23, 24, 28, .1); border-radius: 999px;
  background: #fff; color: var(--ink); font: 700 13px/1 var(--font-body); cursor: pointer;
}
/* a day: its name and what it held, then a timeline — the time, a dot on the love path's
   dotted trail (pink for a strip, blue for a game), the card */
.wk-days { display: flex; flex-direction: column; gap: 22px; }
.wk-daysec { display: flex; flex-direction: column; gap: 10px; }
.wk-day-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 0 2px; }
.wk-day-head b { font-size: 15.5px; font-weight: 800; }
.wk-daysec.is-today .wk-day-head b { color: #c2416f; }
.wk-day-head span { font-size: 13px; font-weight: 600; text-align: right; color: var(--ink-soft); }
.wk-tl { position: relative; display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; }
.wk-tl::before { content: ""; position: absolute; left: 73px; top: 18px; bottom: 18px; border-left: 2px dotted #E7B8CC; }
.wk-tl-item { position: relative; display: grid; grid-template-columns: 62px 20px minmax(0, 1fr); align-items: start; gap: 0 2px; }
.wk-tl-time { padding-top: 15px; font-size: 11.5px; font-weight: 700; line-height: 1.2; text-align: right; white-space: nowrap; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.wk-tl-dot {
  position: relative; z-index: 1; justify-self: center; width: 12px; height: 12px; margin-top: 17px; border-radius: 50%;
  background: #FF8DB0; box-shadow: 0 0 0 3px var(--paper, #F8F9FB);
}
.wk-tl-item.is-game .wk-tl-dot { background: #7FB0FF; }
.wk-act {
  display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 12px; border-radius: 18px; background: #fff;
  border: 1px solid rgba(23, 24, 28, .06); box-shadow: 0 6px 16px rgba(60, 40, 60, .05);
}
.wk-act-top { display: flex; align-items: center; gap: 10px; }
.wk-coin { flex: 0 0 auto; width: 40px; height: 40px; object-fit: contain; }
.wk-coin.is-icon { display: grid; place-items: center; border-radius: 50%; background: var(--blue-tint); color: #2F64B8; }
.wk-act-title { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.wk-act-title b { font-size: 15px; font-weight: 800; line-height: 1.2; }
.wk-act-title > span { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.wk-out { flex: 0 0 auto; align-self: flex-start; padding: 4px 10px; border-radius: 999px; background: #F1F2F6; color: var(--ink-soft); font-size: 12px; font-weight: 800; }
.wk-out.is-won { background: #E3F6EC; color: #1F7A4D; }
.wk-out.is-lost { background: #FFECEF; color: #A8325F; }
.wk-out.is-team { background: #F1E9FF; color: #6E45B0; }
/* who played: the scoreboard (you pink, your partner blue, the winner's score in green),
   or the two of you when the game keeps no score */
.wk-score, .wk-people { display: flex; align-items: center; gap: 8px; padding: 9px 12px; border-radius: 14px; background: #F7F8FB; }
.wk-side { display: inline-flex; align-items: center; gap: 7px; min-width: 0; font-size: 13.5px; font-weight: 700; color: var(--ink); }
.wk-score .wk-side { flex: 1; }
.wk-score .wk-side.is-them { flex-direction: row-reverse; }
.wk-side span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.wk-side i { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; background: #FF8DB0; }
.wk-side.is-them i { background: #7FB0FF; }
.wk-side b { flex: 0 0 auto; font-family: var(--font-display); font-size: 18px; font-weight: 800; line-height: 1; color: var(--ink-soft); }
.wk-side.is-win b { color: #1F7A4D; }
.wk-vs { flex: 0 0 auto; font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }
.wk-amp { color: var(--ink-soft); font-weight: 700; }
.wk-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.wk-chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; border-radius: 999px;
  background: #F4F0FB; color: #5B4A86; font-size: 12px; font-weight: 700; line-height: 1;
}
.wk-act.is-strip { flex-direction: row; align-items: center; gap: 12px; }
.wk-act.is-strip .wk-act-title { gap: 4px; }
.wk-act-strip { flex: 0 0 auto; width: auto; max-width: 110px; height: 88px; border-radius: 6px; object-fit: contain; background: #EEF0F5; box-shadow: 0 4px 10px rgba(60, 40, 60, .12); }
.wk-act-strip.is-blank { width: 30px; }
.wk-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 18px; border-radius: 20px; border: 1.5px dashed #E3D9F2; text-align: center; }
.wk-empty img { width: 120px; height: auto; }
.wk-empty b { font-size: 14.5px; }
.wk-note { margin: 4px 0 0; }
.wk-cta {
  display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 52px; margin: 4px 0 8px;
  border-radius: 16px; background: var(--ink); color: #fff; text-decoration: none; font-size: 16px; font-weight: 800;
  -webkit-tap-highlight-color: transparent;
}
.wk-cta:active { transform: scale(.98); }
/* the calendar sheet: a month, a dot per kind under each day, the seven days on show banded */
.wk-cal { gap: 12px; padding-bottom: calc(18px + env(safe-area-inset-bottom)); }
.wk-cal-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.wk-cal-title { font-family: var(--font-display); font-size: 18px; font-weight: 800; }
.wk-cal-nav {
  display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 12px;
  background: #F4F5F8; color: var(--ink); cursor: pointer;
}
.wk-cal-nav:disabled { opacity: .35; cursor: default; }
.wk-cal-dow, .wk-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.wk-cal-dow span { font-size: 11.5px; font-weight: 700; text-align: center; color: var(--ink-soft); }
.wk-cal-day {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  height: 46px; padding: 0; border: 0; border-radius: 12px; background: none; color: var(--ink);
  font: 700 14.5px/1 var(--font-body); cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.wk-cal-day.is-in { background: #FFF0F5; }
.wk-cal-day.is-end { background: #ec5f93; color: #fff; }
.wk-cal-day.is-today:not(.is-end) { box-shadow: inset 0 0 0 2px #ec5f93; }
.wk-cal-day:disabled { color: #C3C6CF; cursor: default; }
.wk-cal-day:not(:disabled):active { transform: scale(.94); }
.wk-cal-dots { display: flex; gap: 3px; height: 5px; }
.wk-cal-dots i { width: 5px; height: 5px; border-radius: 50%; background: #FF8DB0; }
.wk-cal-dots i.is-b { background: #7FB0FF; }
.wk-cal-day.is-end .wk-cal-dots i { background: #fff; }
.wk-cal-legend { display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--ink-soft); }
.wk-cal-legend i { width: 8px; height: 8px; margin-left: 6px; border-radius: 50%; background: #FF8DB0; }
.wk-cal-legend i.is-b { background: #7FB0FF; }
.wk-cal-now {
  min-height: 48px; border: 0; border-radius: 14px; background: var(--ink); color: #fff;
  font: 800 15px/1 var(--font-body); cursor: pointer;
}

/* ---- A game's own page (2026-10-12, app/gameDetail.js) -------------------------------------
   Pushed over Home from the Up next card, and over the tab bar (it has its own Play at the
   foot): the coin big on the card's pink-to-blue, three facts, the steps down the love
   path's dotted trail, one note, and Play in a sticky bar. */
.gd-page { padding-bottom: 0; }
.gd-hero {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center;
  margin: 4px 20px 0; padding: 22px 20px 24px; border-radius: 28px;
  background: linear-gradient(140deg, var(--pink-tint), #F3ECFF 50%, var(--blue-tint));
  box-shadow: 0 14px 30px rgba(60, 40, 60, .08);
}
.gd-glow {
  position: absolute; left: 50%; top: 10px; width: 240px; height: 240px; margin-left: -120px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, .95) 0%, rgba(255, 255, 255, 0) 68%); pointer-events: none;
}
.gd-coin {
  position: relative; width: 168px; height: 168px; margin-bottom: 6px; object-fit: contain;
  filter: drop-shadow(0 12px 18px rgba(110, 69, 176, .18)); animation: gd-float 4s ease-in-out infinite;
}
@keyframes gd-float { 0%, 100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-6px) rotate(2deg); } }
.gd-eyebrow { position: relative; font: 700 10.5px/1 var(--font-mono, ui-monospace, monospace); letter-spacing: .12em; text-transform: uppercase; color: #b23a66; }
.gd-hero h1 { position: relative; margin: 2px 0 0; font-size: 28px; font-weight: 800; letter-spacing: -.03em; line-height: 1.1; color: var(--ink); }
.gd-hero p { position: relative; max-width: 30ch; margin: 0; font-size: 15px; color: var(--ink-soft); }
.gd-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 14px 20px 0; padding: 0; list-style: none; }
.gd-fact {
  display: flex; flex-direction: column; align-items: center; gap: 7px; text-align: center;
  padding: 12px 6px; border-radius: 18px; background: #fff;
  border: 1px solid rgba(23, 24, 28, .06); box-shadow: 0 6px 16px rgba(60, 40, 60, .05);
  font-size: 12.5px; font-weight: 700; line-height: 1.25; color: var(--ink);
}
.gd-fact-ic { display: grid; place-items: center; width: 38px; height: 38px; border-radius: 12px; background: var(--pink-tint); color: #b23a66; }
.gd-fact:nth-child(2) .gd-fact-ic { background: #F1E9FF; color: #6E45B0; }
.gd-fact:nth-child(3) .gd-fact-ic { background: var(--blue-tint); color: #2F64B8; }
.gd-how { margin: 24px 20px 0; }
.gd-how h2 { margin: 0 0 12px; font-size: 18px; font-weight: 800; letter-spacing: -.01em; }
.gd-steps { position: relative; display: flex; flex-direction: column; gap: 14px; margin: 0; padding: 0; list-style: none; }
.gd-steps::before { /* the love path's dotted trail, pebble to pebble */
  content: ""; position: absolute; left: 17px; top: 20px; bottom: 20px; border-left: 3px dotted #E7B8CC;
}
.gd-step { position: relative; display: flex; align-items: center; gap: 14px; }
.gd-step-n {
  flex: 0 0 auto; display: grid; place-items: center; width: 37px; height: 37px; border-radius: 50%;
  font: 800 15px/1 var(--font-display); color: #fff;
  background: linear-gradient(180deg, #FF9EBB, #EC5F93);
  box-shadow: 0 0 0 4px var(--paper, #F8F9FB), 0 6px 12px rgba(236, 95, 147, .25);
}
.gd-step:nth-child(2) .gd-step-n { background: linear-gradient(180deg, #C9A6F7, #8A5CD6); box-shadow: 0 0 0 4px var(--paper, #F8F9FB), 0 6px 12px rgba(138, 92, 214, .25); }
.gd-step:nth-child(3) .gd-step-n { background: linear-gradient(180deg, #A9CBFF, #5FA0FF); box-shadow: 0 0 0 4px var(--paper, #F8F9FB), 0 6px 12px rgba(95, 160, 255, .25); }
.gd-step-t {
  flex: 1; padding: 12px 14px; border-radius: 16px; background: #fff;
  border: 1px solid rgba(23, 24, 28, .06); box-shadow: 0 6px 14px rgba(60, 40, 60, .04);
  font-size: 14.5px; font-weight: 600; line-height: 1.35; color: var(--ink);
}
.gd-note {
  display: flex; align-items: center; gap: 12px; margin: 18px 20px 0; padding: 14px; border-radius: 18px;
  background: #FFF8EC; border: 1px solid rgba(214, 160, 60, .2);
}
.gd-note-ic { flex: 0 0 auto; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 12px; background: #FFE9BF; color: #8A5A12; }
.gd-note-copy { display: flex; flex-direction: column; gap: 2px; font-size: 13.5px; line-height: 1.35; color: var(--ink-soft); }
.gd-note-copy b { font-size: 14.5px; color: var(--ink); }
.gd-cta {
  position: sticky; bottom: 0; z-index: 2; margin-top: auto;
  padding: 18px 20px calc(14px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(180deg, rgba(248, 249, 251, 0) 0%, var(--paper, #F8F9FB) 38%);
}
.gd-play {
  display: flex; align-items: center; justify-content: center; min-height: 56px; border-radius: 18px;
  background: var(--ink); color: #fff; text-decoration: none; font-size: 17px; font-weight: 800;
  box-shadow: 0 10px 22px rgba(23, 24, 28, .22); -webkit-tap-highlight-color: transparent;
}
.gd-play:active { transform: scale(.98); }

@media (prefers-reduced-motion: reduce) {
  .hw-seg, .gd-coin, .wk-duo { animation: none; }
}

/* ---- The week's page, its chips and the way into Our story (2026-10-12) --------------------- */
.wk-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.wk-streak {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px 3px 4px; border-radius: 999px;
  background: #FFEFE3; color: #A64E1B; font-size: 12.5px; font-weight: 800; box-shadow: 0 1px 3px rgba(166, 78, 27, .12);
}
.wk-streak img { width: 22px; height: 22px; object-fit: contain; }
.wk-story {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 14px 10px 8px; border-radius: var(--h-r);
  border: 1px solid var(--h-line); background: var(--h-card);
  color: var(--ink); text-align: left; font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent;
  box-shadow: var(--h-shadow); transition: transform .12s ease;
}
.wk-story:active { transform: scale(.985); }
.wk-story-art { flex: 0 0 auto; width: 64px; height: 64px; object-fit: contain; }
.wk-story-copy { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.wk-story-copy b { font-size: 15.5px; font-weight: 800; }
.wk-story-copy span { font-size: 13px; font-weight: 500; color: var(--h-muted); }
.wk-story-go { flex: 0 0 auto; display: grid; place-items: center; color: #B9BCC6; }

/* ---- Our story (2026-10-12, app/ourStory.js) ------------------------------------------------
   Every date night, pushed from the week's page: the pair with their album, the count and
   since when, three tiles, the game you play most; then (since 2026-10-21) the charts — month
   by month with the month's calendar, strips and games, who wins, the games you play, your
   favourite night, the milestones (the second-round block below). It wears the week's frame
   (.wk-wrap / .wk-head / .wk-aside / .wk-main above): on a wide screen the summary on the
   left, the cards on the right. */
/* Home's white card, as the week's hero (2026-10-20 — the gradient came off, Home's one-card rule) */
.st-hero {
  display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 16px 18px; border-radius: 24px;
  text-align: center; background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.st-art { width: 168px; height: 168px; object-fit: contain; animation: hw-bob 3.6s ease-in-out infinite; }
.wk-aside .st-art { width: 148px; height: 148px; }
.st-count { display: flex; align-items: baseline; justify-content: center; flex-wrap: wrap; gap: 6px; }
.st-count b { font-family: var(--font-display); font-size: 44px; font-weight: 800; line-height: 1; letter-spacing: -.03em; color: var(--ink); }
.st-count span { font-size: 16px; font-weight: 800; color: var(--ink); }
.st-since { margin: 2px 0 0; font-size: 13.5px; font-weight: 600; color: #6E45B0; }
/* the game you play most, as one of the number tiles laid on its side (2026-10-20): its coin
   on a soft lilac blob, the label small, the game's name big, how often as a lilac pill */
.st-fav {
  display: flex; align-items: center; gap: 14px; padding: 12px 14px 12px 12px; border-radius: 22px;
  background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.st-fav-art { flex: 0 0 auto; display: grid; place-items: center; width: 60px; height: 60px; border-radius: 19px; background: #EFE9FF; }
.st-fav-coin { display: block; width: 50px; height: 50px; object-fit: contain; filter: drop-shadow(0 3px 4px rgba(60, 40, 60, .12)); }
.st-fav-coin.is-icon, .st-coin.is-icon { display: grid; place-items: center; border-radius: 50%; background: var(--blue-tint); color: #2F64B8; }
.st-fav-copy { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.st-fav-copy span { font-size: 12.5px; font-weight: 600; line-height: 1.25; color: var(--h-muted); }
.st-fav-copy b { font-family: var(--font-display); font-size: 18px; font-weight: 800; line-height: 1.2; letter-spacing: -.01em; color: var(--h-ink); }
.st-fav-n { flex: 0 0 auto; padding: 5px 11px; border-radius: 999px; background: #EFE9FF; color: #6E45B0; font-size: 12.5px; font-weight: 800; white-space: nowrap; }
.st-months { display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; }
.st-month {
  display: flex; flex-direction: column; gap: 12px; padding: 16px 16px 16px; border-radius: 22px;
  background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
/* a month: its name and what it held on the left, its date nights as a pill on the right */
.st-month-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.st-month-t { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.st-month-t b { font-family: var(--font-display); font-size: 17px; font-weight: 800; line-height: 1.2; letter-spacing: -.01em; }
.st-month-t span { font-size: 12.5px; font-weight: 600; color: var(--h-muted); }
.st-month-n {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; padding: 5px 11px 5px 9px; border-radius: 999px;
  background: #FFE8F0; color: var(--h-deep); font-size: 12.5px; font-weight: 800; white-space: nowrap;
}
.st-month-n .icon { flex: 0 0 auto; display: inline-flex; color: var(--h-pink); }
.st-strips { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.st-strips::-webkit-scrollbar { display: none; }
.st-strip {
  flex: 0 0 auto; display: block; height: 96px; padding: 0; border: 0; border-radius: 6px; background: #EEF0F5;
  box-shadow: 0 4px 10px rgba(60, 40, 60, .12); overflow: hidden; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.st-strip img { display: block; height: 100%; width: auto; max-width: 140px; object-fit: contain; }
.st-strip:active { transform: scale(.96); }
.st-blank { display: block; width: 32px; height: 100%; }
.st-games { display: flex; flex-wrap: wrap; gap: 6px; }
.st-game {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px 4px 4px; border-radius: 999px;
  background: #F4F0FB; color: #4B366A; font-size: 12.5px; font-weight: 700;
}
.st-game b { color: #6E45B0; font-weight: 800; }
.st-coin { width: 24px; height: 24px; object-fit: contain; }
.st-coin.is-icon { width: 24px; height: 24px; }

/* ---- Our story, second round (2026-10-21, the user: "clear, cute, more detailed — a graph or
   whatever looks good"): the detail is white cards, each with a small Higgsfield sticker by its
   title — month by month (a bar per month, the month on show in the deep lilac, then its
   calendar, strips and games), who wins (pink and blue with the ties between), the games you
   play (a bar each with its coin), your favourite night (the days of the week, the favourite
   lit) and the milestones (on the love path's dotted trail, the next one with its progress).
   Chart colours (validated with the dataviz skill's palette checks): one hue a chart; nights
   lilac (the week page's "days together" tile), games blue, strips pink; the mark carries the
   colour, every value is written beside it in ink. Bars ≤24px, a 6px rounded data-end. */
.st-page {
  --st-night: #B7A3F7; --st-night-top: #8B6AF0; --st-night-soft: #DDD3FB; --st-night-tint: #EFE9FF; --st-night-ink: #6B4CC9;
  --st-strip: #EC6A9A; --st-game: #5B8FEC; --st-tie: #CDD1DA; --st-seed: #E3E5EA;
}
.st-card {
  position: relative; display: flex; flex-direction: column; gap: 12px; min-width: 0; padding: 16px; border-radius: 22px;
  background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.st-card-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.st-sticker { flex: 0 0 auto; width: 38px; height: 38px; object-fit: contain; filter: drop-shadow(0 2px 3px rgba(60, 40, 60, .14)); }
.st-card-t { flex: 1 1 auto; min-width: 0; margin: 0; font-size: 17px; font-weight: 800; line-height: 1.25; letter-spacing: -.01em; color: var(--h-ink); }
.st-card-side { flex: 0 0 auto; font-size: 12.5px; font-weight: 700; color: var(--h-muted); }
.st-card-line { display: flex; flex-direction: column; gap: 2px; margin: -4px 0 0; }
.st-card-line b { font-size: 14.5px; font-weight: 800; line-height: 1.3; color: var(--h-ink); }
.st-card-line span { font-size: 12.5px; font-weight: 600; line-height: 1.35; color: var(--h-muted); }
.st-hint { margin: -4px 0 0; font-size: 12.5px; font-weight: 600; text-align: center; color: var(--h-muted); }
/* a month (or a day of the week) with nothing: a small grey dot on the floor, the week chart's */
.st-seed { display: block; width: 8px; height: 8px; border-radius: 50%; background: var(--st-seed); }
.st-time {
  display: inline-flex; align-items: center; gap: 5px; margin: 10px 0 0; padding: 5px 11px; border-radius: 999px;
  background: #EEF4FF; color: #3D63C4; font-size: 12.5px; font-weight: 700;
}
.st-time .icon { display: inline-flex; }
/* the bars, one a month: the number on its cap, the month under it, the year under January */
.st-bars { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 4px; align-items: end; height: 172px; padding-top: 18px; }
.st-col {
  display: flex; flex-direction: column; align-items: center; gap: 4px; height: 100%; min-width: 0; margin: 0; padding: 0 0 4px;
  border: 0; border-radius: 12px; background: none; color: inherit; font: inherit; cursor: pointer;
  -webkit-tap-highlight-color: transparent; transition: background .15s ease, transform .12s ease;
}
.st-col:active { transform: scale(.95); }
.st-col.is-sel { background: rgba(139, 106, 240, .08); }
.st-col:focus-visible { outline: 2px solid var(--st-night-top); outline-offset: 1px; }
.st-col-track, .st-dow-track { position: relative; flex: 1; display: flex; align-items: flex-end; justify-content: center; width: 100%; }
.st-col-bar, .st-dow-bar {
  position: relative; display: block; width: 100%; max-width: 24px; height: var(--h); min-height: 8px; border-radius: 6px 6px 2px 2px;
  background: var(--st-night); transform-origin: bottom; animation: hw-rise .5s cubic-bezier(.2, 1, .4, 1) both; animation-delay: calc(var(--i, 0) * 40ms);
}
.st-col.is-sel .st-col-bar { background: var(--st-night-top); }
.st-col-n { position: absolute; left: 50%; bottom: 100%; translate: -50% -4px; font-size: 11.5px; font-weight: 800; line-height: 1; color: var(--h-ink); }
.st-col-m { font-size: 10.5px; font-weight: 700; line-height: 1.1; white-space: nowrap; color: var(--h-muted); }
.st-col-y { min-height: 10px; font-size: 9.5px; font-weight: 700; line-height: 1; color: #9FA3AE; }
.st-col.is-sel .st-col-m { color: var(--st-night-ink); }
/* one tooltip a chart card: the value first, then what it is (a computer's hover, keyboard focus) */
.st-tip {
  position: absolute; left: 0; top: 0; z-index: 3; display: flex; flex-direction: column; gap: 2px; padding: 7px 10px;
  border-radius: 10px; background: var(--h-ink); color: #fff; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity .12s ease; box-shadow: 0 8px 18px rgba(23, 24, 28, .18);
}
.st-tip.is-on { opacity: 1; }
.st-tip-v { font-size: 13px; font-weight: 800; line-height: 1.2; }
.st-tip-l { font-size: 12px; font-weight: 600; line-height: 1.2; color: rgba(255, 255, 255, .78); }
/* the month on show: its calendar (every date night on a lilac tint, a dot per kind), arrows to step */
.st-cal { display: flex; flex-direction: column; gap: 8px; }
.st-bars + .st-hint + .st-cal { padding-top: 12px; border-top: 1px solid var(--h-line); }
.st-cal-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.st-cal-title { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 0; text-align: center; }
.st-cal-t { font-family: var(--font-display); font-size: 16px; font-weight: 800; line-height: 1.2; color: var(--h-ink); }
.st-cal-sum { font-size: 12.5px; font-weight: 600; line-height: 1.3; color: var(--h-muted); }
.st-cal-nav {
  flex: 0 0 auto; display: grid; place-items: center; width: 38px; height: 38px; padding: 0; border: 0; border-radius: 12px;
  background: #F4F5F8; color: var(--h-ink); cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.st-cal-nav:disabled { opacity: .35; cursor: default; }
.st-cal-nav:not(:disabled):active { transform: scale(.94); }
.st-cal-nav:focus-visible { outline: 2px solid var(--st-night-top); outline-offset: 2px; }
.st-cal-dow, .st-cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.st-cal-dow span { font-size: 11px; font-weight: 700; text-align: center; color: var(--h-muted); }
.st-cal-day {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; height: 38px; min-width: 0;
  border-radius: 12px; font-size: 13px; font-weight: 600; line-height: 1; color: var(--h-muted);
}
.st-cal-day.is-on { background: var(--st-night-tint); color: var(--st-night-ink); font-weight: 800; }
.st-cal-day.is-today { box-shadow: inset 0 0 0 2px #ec5f93; }
.st-cal-day.is-future { color: #C7CAD3; }
/* a date night is a button (2026-10-22): a tap shows that day's strips and games under the
   calendar, the picked day goes solid; the same tap again, the whole month */
button.st-cal-day {
  width: 100%; padding: 0; border: 0; font-family: inherit;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: transform 140ms ease, background-color 160ms ease, color 160ms ease;
}
button.st-cal-day:active { transform: scale(.94); }
button.st-cal-day:focus-visible { outline: 2px solid var(--st-night-top); outline-offset: 2px; }
.st-cal-day.is-sel { background: var(--st-night-ink); color: #fff; }
.st-cal-day.is-sel .st-cal-dots i { box-shadow: 0 0 0 1.5px #fff; }
.st-cal-hint { margin: 2px 0 0; text-align: center; }
.st-cal-hint[hidden] { display: none; }
.st-day-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0; }
.st-day-head b { min-width: 0; font-size: 14px; font-weight: 800; color: var(--h-ink); }
.st-day-all {
  flex: none; padding: 8px 2px; border: 0; background: none;
  font: 700 13px/1 var(--font-body); color: var(--st-night-ink);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.st-cal-dots { display: flex; gap: 3px; height: 5px; }
.st-cal-dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--st-strip); }
.st-cal-dots i.is-b { background: var(--st-game); }
.st-legend { display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--h-muted); }
.st-legend i { width: 8px; height: 8px; margin-left: 6px; border-radius: 50%; background: var(--st-strip); }
.st-legend i.is-b { background: var(--st-game); }
.st-month-what { display: flex; flex-direction: column; gap: 10px; }
.st-month-what[hidden] { display: none; }
/* who wins and the favourite night: one column on a phone, side by side once there's room */
.st-pair { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.st-pair > .st-card { flex: 1 1 auto; }
/* who wins: one bar, you in pink, the ties grey, your partner blue, 2px of white between */
.st-wins-bar { display: flex; gap: 2px; height: 14px; }
.st-wins-seg { display: block; flex-basis: 0; min-width: 8px; border-radius: 3px; }
.st-wins-seg:first-child { border-radius: 999px 3px 3px 999px; }
.st-wins-seg:last-child { border-radius: 3px 999px 999px 3px; }
.st-wins-seg:only-child { border-radius: 999px; }
.st-wins-seg.is-me { background: var(--st-strip); }
.st-wins-seg.is-tie { background: var(--st-tie); }
.st-wins-seg.is-them { background: var(--st-game); }
.st-wins-key { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.st-wins-side { display: inline-flex; align-items: center; gap: 7px; min-width: 0; font-size: 13.5px; font-weight: 700; color: var(--h-ink); }
.st-wins-side span { min-width: 0; overflow-wrap: anywhere; }
.st-wins-side i { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; background: var(--st-strip); }
.st-wins-side.is-them { justify-content: flex-end; text-align: right; }
.st-wins-side.is-them i { background: var(--st-game); }
.st-wins-side b { flex: 0 0 auto; font-family: var(--font-display); font-size: 20px; font-weight: 800; line-height: 1; }
.st-wins-tie { flex: 0 0 auto; font-size: 12.5px; font-weight: 600; color: var(--h-muted); }
/* the games you play: the coin, the name over its bar, how often */
.st-gbars { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; }
.st-grow { display: grid; grid-template-columns: 32px minmax(0, 1fr) auto; align-items: center; gap: 10px; }
.st-gcoin { display: block; width: 32px; height: 32px; object-fit: contain; }
.st-gcoin.is-icon, .st-gcoin.is-more { display: grid; place-items: center; border-radius: 50%; background: #F1F2F6; color: var(--h-muted); }
.st-grow-mid { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.st-grow-name { font-size: 13.5px; font-weight: 700; line-height: 1.2; color: var(--h-ink); overflow-wrap: anywhere; }
.st-grow-track { display: block; height: 10px; }
.st-grow-bar {
  display: block; width: var(--w); min-width: 10px; height: 100%; border-radius: 2px 6px 6px 2px; background: var(--st-game);
  transform-origin: left; animation: st-grow .55s cubic-bezier(.2, 1, .4, 1) both; animation-delay: calc(var(--i, 0) * 50ms);
}
@keyframes st-grow { from { transform: scaleX(0); } }
.st-grow-n { min-width: 2ch; font-family: var(--font-display); font-size: 17px; font-weight: 800; text-align: right; color: var(--h-ink); }
/* your favourite night: seven bars, the favourite in the deep lilac, the rest soft */
.st-dow { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; align-items: end; height: 132px; padding-top: 18px; }
.st-dow-col { display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; min-width: 0; }
.st-dow-bar { background: var(--st-night-soft); }
.st-dow-col.is-top .st-dow-bar { background: var(--st-night-top); }
.st-dow-d { font-size: 11px; font-weight: 700; line-height: 1.1; white-space: nowrap; color: var(--h-muted); }
.st-dow-col.is-top .st-dow-d { color: var(--st-night-ink); }
/* milestones on the love path's dotted trail: reached ones lilac, the first pink, the next with
   how far along, the ones still to come a dashed ring */
.st-ms { position: relative; display: flex; flex-direction: column; gap: 14px; margin: 0; padding: 0; list-style: none; }
.st-ms::before { content: ""; position: absolute; left: 18px; top: 20px; bottom: 20px; border-left: 2px dotted #D3C8F7; }
.st-ms-item { position: relative; display: grid; grid-template-columns: 38px minmax(0, 1fr); align-items: center; gap: 12px; }
.st-ms-ic {
  position: relative; z-index: 1; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%;
  background: var(--st-night-tint); color: var(--st-night-ink); box-shadow: 0 0 0 4px var(--h-card);
}
.st-ms-ic .icon { display: inline-flex; }
.st-ms-item.is-first .st-ms-ic { background: #FFE4EE; color: #C2416F; }
.st-ms-item.is-next .st-ms-ic { background: var(--st-night-top); color: #fff; }
.st-ms-item.is-todo .st-ms-ic { background: var(--h-card); color: #A6AAB5; box-shadow: inset 0 0 0 2px #DDE0E7, 0 0 0 4px var(--h-card); }
.st-ms-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.st-ms-copy b { font-size: 14px; font-weight: 800; line-height: 1.25; color: var(--h-ink); }
.st-ms-copy > span { font-size: 12.5px; font-weight: 600; line-height: 1.3; color: var(--h-muted); }
.st-ms-item.is-todo .st-ms-copy b { color: var(--h-muted); }
.st-ms-track { display: block; height: 8px; margin-top: 6px; border-radius: 999px; background: var(--st-night-tint); overflow: hidden; }
.st-ms-fill { display: block; width: var(--w); min-width: 8px; height: 100%; border-radius: 999px; background: var(--st-night-top); }
.st-ms-go {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; margin-top: 4px;
  font-size: 12.5px; font-weight: 800; color: #C2416F; text-decoration: none;
}
.st-ms-go .icon { display: inline-flex; }
.st-mscard.is-soon { margin-top: 2px; }
@container wkpage (min-width: 600px) {
  .st-pair.is-two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: stretch; }
  .st-bars { height: 196px; gap: 6px; }
  .st-col-m { font-size: 11.5px; }
  .st-cal-day { height: 44px; font-size: 14px; }
  .st-card { padding: 18px; }
}
@media (prefers-reduced-motion: reduce) { .st-col-bar, .st-dow-bar, .st-grow-bar { animation: none; } }

/* ---- The strips slideshow on Home (2026-10-12, app/homeSlides.js) -------------------------
   Under "Your memories": one white card per strip, in two halves (2026-10-13) — the strip
   like a print taped to pastel paper (its own tint per slide, a little tilt, washi tape),
   and beside it the day, the date, what it was made with and "View"; a dot per slide.
   Before the first strip, the pair holding one and the way into the booth. */
.ss { margin: 0 20px 12px; }
.ss-skel { height: 216px; border-radius: var(--h-r); background: linear-gradient(100deg, #EEF0F5 30%, #F7F8FB 50%, #EEF0F5 70%) 0 0 / 200% 100%; animation: sp-skel 1.2s ease-in-out infinite; }
.ss-track {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  border-radius: var(--h-r); background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow); overscroll-behavior-x: contain;
}
.ss-track::-webkit-scrollbar { display: none; }
.ss-slide { flex: 0 0 100%; scroll-snap-align: center; scroll-snap-stop: always; }
.ss-open {
  display: grid; grid-template-columns: 46% minmax(0, 1fr); gap: 16px; align-items: stretch;
  width: 100%; height: 216px; padding: 12px 16px 12px 12px; border: 0; background: none;
  color: var(--ink); font: inherit; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.ss-art {
  display: grid; place-items: center; min-width: 0; border-radius: 16px; overflow: hidden;
  background: radial-gradient(rgba(255, 255, 255, .6) 1.2px, transparent 1.5px) 0 0 / 14px 14px, var(--tint, #FFE3EC);
}
.ss-print { position: relative; display: inline-flex; max-width: 84%; transform: rotate(-3deg); }
.ss-slide:nth-child(even) .ss-print { transform: rotate(3deg); }
.ss-img {
  display: block; max-width: 100%; max-height: 170px; width: auto; height: auto; object-fit: contain;
  border-radius: 3px; box-shadow: 0 10px 20px rgba(40, 30, 60, .2), 0 2px 4px rgba(40, 30, 60, .1);
}
/* the washi tape holding the print down */
.ss-print::after {
  content: ""; position: absolute; top: -7px; left: 50%; width: 46px; height: 15px; margin-left: -23px;
  background: rgba(255, 255, 255, .74); box-shadow: 0 1px 3px rgba(40, 30, 60, .12); transform: rotate(-5deg);
}
.ss-copy { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 6px; min-width: 0; }
.ss-day { font: 700 11px/1.2 var(--font-mono, ui-monospace, monospace); letter-spacing: .14em; text-transform: uppercase; color: #c2416f; }
.ss-date { font-family: var(--font-display); font-size: 21px; font-weight: 800; line-height: 1.15; letter-spacing: -.02em; color: var(--ink); }
.ss-tags { display: flex; flex-wrap: wrap; gap: 6px; max-width: 100%; }
.ss-tags i {
  max-width: 100%; padding: 4px 9px; border-radius: 999px; background: #F3F4F8; color: var(--ink-soft);
  font-size: 12px; font-style: normal; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ss-view {
  display: inline-flex; align-items: center; gap: 2px; margin-top: 6px; padding: 7px 10px 7px 13px; border-radius: 999px;
  background: #FFE6EE; color: #c2416f; font-size: 13px; font-weight: 800;
}
.ss-view svg { display: block; }
.ss-dots { display: flex; justify-content: center; gap: 6px; margin-top: 10px; }
.ss-dots i { display: block; width: 6px; height: 6px; border-radius: 3px; background: #D9DCE4; transition: width .25s ease, background .25s ease; }
.ss-dots i.is-on { width: 18px; background: #ec5f93; }
.ss-empty {
  display: flex; align-items: center; gap: 12px; padding: 14px 16px 14px 8px; border-radius: var(--h-r);
  background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.ss-empty-art { flex: 0 0 auto; width: 104px; height: 104px; object-fit: contain; }
.ss-empty-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
.ss-empty-copy b { font-size: 15.5px; font-weight: 800; }
.ss-empty-copy span { font-size: 13px; font-weight: 500; color: var(--h-muted); }
.ss-go {
  margin-top: 6px; display: inline-flex; align-items: center; min-height: 38px; padding: 0 14px; border-radius: 999px;
  background: var(--ink); color: #fff; text-decoration: none; font-size: 13.5px; font-weight: 800;
}
@media (prefers-reduced-motion: reduce) { .st-art, .ss-skel { animation: none; } }

/* ---- NOTIFICATIONS (2026-10-14, app/notifications.js) -----------------------------------------
   The page behind the bell: white cards like the week's, the new ones on a blush wash with a
   pink dot on their picture; a Join pill on a partner who is waiting right now. */
.nt-list { display: flex; flex-direction: column; gap: 10px; }
.nt-list .wk-label { margin-top: 6px; }
.nt-group { display: flex; flex-direction: column; gap: 10px; }
.nt-item {
  position: relative; display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; align-items: center; gap: 12px;
  width: 100%; margin: 0; padding: 12px 14px 12px 12px; border-radius: 18px; background: #fff;
  border: 1px solid rgba(23, 24, 28, .06); box-shadow: 0 6px 16px rgba(60, 40, 60, .05);
  color: var(--ink); text-decoration: none; text-align: left; font: inherit;
  -webkit-tap-highlight-color: transparent;
}
a.nt-item, button.nt-item { cursor: pointer; }
a.nt-item:active, button.nt-item:active { transform: scale(.985); }
.nt-item.is-new { background: linear-gradient(160deg, #FFF3F8 0%, #FFFFFF 72%); border-color: rgba(236, 95, 147, .22); }
.nt-art { position: relative; display: grid; place-items: center; width: 52px; height: 52px; }
.nt-art img { display: block; width: 52px; height: 52px; object-fit: contain; }
.nt-art.is-strip img { width: auto; max-width: 40px; height: 52px; border-radius: 4px; background: #EEF0F5; box-shadow: 0 3px 8px rgba(60, 40, 60, .16); }
.nt-art.is-wide img { height: auto; }
.nt-art.is-icon { border-radius: 16px; background: #DFEBFF; color: #2F64B8; }
.nt-art.is-icon.is-pink { background: #FFE4EE; color: #b23a66; }
.nt-art .icon { display: inline-flex; }
.nt-dot { position: absolute; top: -3px; right: -3px; width: 12px; height: 12px; border-radius: 50%; background: #ec5f93; box-shadow: 0 0 0 2px #fff; }
.nt-copy { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.nt-copy b { font-size: 15px; font-weight: 800; line-height: 1.25; }
.nt-copy > span { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--ink-soft); }
.nt-copy time { font-size: 12px; font-weight: 700; color: #A0919E; }
.nt-go { display: inline-flex; color: #B9B2C2; }
.nt-cta {
  display: inline-flex; align-items: center; min-height: 36px; padding: 0 16px; border-radius: 999px;
  background: #ec5f93; color: #fff; font: 800 14px/1 var(--font-body);
}
.nt-empty span { font-size: 13px; line-height: 1.4; color: var(--ink-soft); }
.nt-note { margin-top: 8px; }

/* Fase 4 (architecture.md §71): an invite's Decline | Accept under its words, and the
   turn-on card at the top of the page while the phone can still be asked. */
.nt-copy > .nt-actions { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.nt-actions-row { display: flex; gap: 8px; }
.nt-yes, .nt-no {
  min-height: 36px; padding: 0 16px; border-radius: 999px; font: 800 14px/1 var(--font-body); font-family: inherit;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.nt-yes { border: 0; background: #ec5f93; color: #fff; }
.nt-no { border: 1px solid #E3E5EA; background: #fff; color: var(--ink); }
.nt-yes:disabled, .nt-no:disabled { opacity: .55; }
.nt-err { font-size: 12.5px; font-weight: 700; color: #C2334F; }
.nt-err:empty { display: none; }
.nt-push { margin: 0 0 10px; }
.nt-push .gd-note-copy { flex: 1; min-width: 0; }
.nt-push-btn {
  flex: none; min-height: 36px; padding: 0 14px; border: 0; border-radius: 999px; background: #17181C; color: #fff;
  font: 800 13.5px/1 var(--font-body); font-family: inherit; cursor: pointer;
}
.nt-push-btn:disabled { opacity: .55; }

/* ==== Fase 5 (2026-10-15, architecture.md §73) — the avatar on Home, the games' covers ========
   .avw- = Home's avatar widget (app/avatarWidget.js); .avl- = the layer Home wraps around the
   dress-up studio and the missions page; .gd-hero.has-cover = a game's 16:9 cover
   (app/assets/covers/) on the game's own page. */

/* The widget, under the greeting: a little stage on MY backdrop (its colour, or its picture)
   with me, and my partner once we're linked, standing on it, alive (client/core/avatarRig.js:
   breathing, blinking, a hop with hearts on a tap, asleep late at night); my speech bubble and
   the Dress up pill on the left. Under it, the weekly missions row: the next prize as its
   picture, the week's six steps, the count. */
.avw {
  position: relative; margin: 10px 20px 0; border-radius: 24px; overflow: hidden;
  background: #fff; border: 1px solid rgba(23, 24, 28, .06);
  box-shadow: 0 12px 28px rgba(60, 40, 60, .09);
}
.avw-stage {
  --fh: clamp(172px, 50vw, 208px); /* a figure's height: the stage is as tall as we are */
  position: relative; display: flex; align-items: stretch; height: var(--fh);
  background-color: var(--avw-bg, #F3ECFF);
  background-position: center 72%; background-size: cover; background-repeat: no-repeat;
}
/* a plain colour gets light from above and a soft floor; a picture brings its own, and only a
   little white behind the bubble */
.avw-stage::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(90% 70% at 72% 8%, rgba(255, 255, 255, .7) 0%, rgba(255, 255, 255, 0) 70%),
    linear-gradient(0deg, rgba(255, 255, 255, .55) 0%, rgba(255, 255, 255, 0) 30%);
}
.avw-stage.is-scene::before { background: linear-gradient(90deg, rgba(255, 255, 255, .4) 0%, rgba(255, 255, 255, 0) 50%); }
/* the 3D try (2026-10-17): a pastel stage, the figure drawn live by three.js (app/avatar3dDemo.js) */
.avw-stage.is-3d { background: linear-gradient(160deg, #D9CCFF 0%, #F6D3EA 55%, #C8F1DC 100%); }
.avw-3d { position: relative; display: block; width: 100%; aspect-ratio: 3 / 4; }
.avw-3d-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.avw-copy {
  position: relative; z-index: 2; flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start; gap: 10px;
  padding: 16px 0 14px 14px;
}
/* the bubble may reach over the empty edge of my figure's box, its tail pointing at me */
.avw-say {
  position: relative; max-width: calc(100% + var(--fh) * .12); margin: 0 calc(var(--fh) * -.12) 0 0;
  padding: 10px 12px; border-radius: 16px; background: #fff; color: var(--ink);
  font-size: 13.5px; font-weight: 700; line-height: 1.3;
  box-shadow: 0 6px 16px rgba(60, 40, 60, .12);
  transform-origin: 92% 55%;
}
.avw-say::after {
  content: ""; position: absolute; right: -5px; top: 50%; width: 12px; height: 12px; margin-top: -6px;
  background: #fff; border-radius: 2px; transform: rotate(45deg);
}
.avw-say-n {
  display: inline-block; margin-left: 6px; padding: 2px 7px; border-radius: 999px; vertical-align: 1px;
  background: #FFE4EE; color: #b23a66; font-size: 11.5px; font-weight: 800; line-height: 1.3;
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.avw-say-n[hidden] { display: none; }
.avw-say.is-pop { animation: avw-pop .45s cubic-bezier(.2, 1.5, .4, 1); }
@keyframes avw-pop { 35% { transform: scale(1.06) rotate(-1.5deg); } }
.avw-dress {
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 15px 0 12px;
  border: 0; border-radius: 999px; background: var(--ink); color: #fff;
  font: 800 14px/1 var(--font-body); white-space: nowrap; cursor: pointer;
  box-shadow: 0 8px 16px rgba(23, 24, 28, .2); -webkit-tap-highlight-color: transparent;
}
.avw-dress .icon { display: inline-flex; }
.avw-dress.is-new { background: #ec5f93; box-shadow: 0 8px 18px rgba(236, 95, 147, .35); }
.avw-dress:active { transform: scale(.96); }
.avw-dress:focus-visible { outline: 3px solid #ec5f93; outline-offset: 2px; }
.avw.is-pair .avw-dress { padding: 0 13px 0 11px; font-size: 13.5px; } /* a narrower column beside the two of us */
/* the two of us, side by side on one shadow: each rig is a 3:4 box with the figure in its
   middle half, so the second box tucks in over the first one's empty edge */
.avw-pair { position: relative; z-index: 1; flex: 0 0 auto; display: flex; align-items: flex-end; padding-right: 4px; }
.avw-pair::before {
  content: ""; position: absolute; left: 14%; right: 12%; bottom: 3px; height: 18px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(60, 40, 60, .22), rgba(60, 40, 60, 0));
}
.avw-fig { position: relative; display: block; flex: 0 0 auto; width: calc(var(--fh) * .75); }
.avw.is-pair .avw-fig { width: calc(var(--fh) * .675); }
.avw-fig + .avw-fig { margin-left: calc(var(--fh) * -.3); }
.avw-fig.is-me { z-index: 2; } /* my pet stands between us: in front of my partner */
.avw-pair { cursor: pointer; }
.avw-fig .avr .avr-bg { display: none; } /* we stand on the card's backdrop, not each on our own */
/* we don't breathe in step (a hop keeps its own timing) */
.avw-fig.is-them .avr.is-alive:not(.is-hop) .avr-body { animation-delay: -1.9s; }
.avw-fig.is-them .avr.is-alive:not(.is-hop) .avr-pet { animation-delay: -1.2s; }
/* together, live (the partner is online): we lean in, hearts drift up between us, a chip says it */
.avw-fig { transition: transform .6s cubic-bezier(.3, 1.4, .5, 1); }
.avw.is-together .avw-fig.is-me { transform: translateX(5%) rotate(1.5deg); }
.avw.is-together .avw-fig.is-them { transform: translateX(-5%) rotate(-1.5deg); }
.avw-live {
  position: absolute; z-index: 3; top: 10px; right: 10px; display: inline-flex; align-items: center; gap: 6px;
  max-width: 62%; padding: 6px 11px 6px 9px; border-radius: 999px; background: rgba(255, 255, 255, .92);
  color: var(--ink); font: 800 12.5px/1.2 var(--font-body); text-decoration: none; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; box-shadow: 0 6px 14px rgba(60, 40, 60, .14);
  -webkit-tap-highlight-color: transparent;
}
.avw-live[hidden] { display: none; }
.avw-live span { overflow: hidden; text-overflow: ellipsis; }
.avw-live-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: #22B573; box-shadow: 0 0 0 3px rgba(34, 181, 115, .2); }
.avw-live.is-join { background: #ec5f93; color: #fff; box-shadow: 0 8px 18px rgba(236, 95, 147, .35); cursor: pointer; }
.avw-live.is-join .avw-live-dot { background: #fff; box-shadow: 0 0 0 3px rgba(255, 255, 255, .35); }
.avw-heart { position: absolute; z-index: 3; bottom: 52%; width: 20px; height: 20px; margin-left: -10px; pointer-events: none; animation: avw-heart 2s ease-out forwards; }
.avw-heart svg { display: block; width: 100%; height: 100%; fill: #EC5F93; }
.avw-heart.is-blue svg { fill: #5FA0FF; }
@keyframes avw-heart { 0% { opacity: 0; transform: translateY(0) scale(.4); } 20% { opacity: 1; transform: translateY(-10px) scale(1); } 100% { opacity: 0; transform: translateY(-64px) scale(.85) rotate(12deg); } }
@media (prefers-reduced-motion: no-preference) { .avw-live-dot { animation: avw-dot 1.8s ease-in-out infinite; } }
@keyframes avw-dot { 50% { box-shadow: 0 0 0 6px rgba(34, 181, 115, 0); } }
@media (prefers-reduced-motion: reduce) { .avw-fig { transition: none; } .avw-heart { display: none; } }
.avw-missions {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 12px;
  width: 100%; margin: 0; padding: 12px; border: 0; border-top: 1px solid rgba(23, 24, 28, .06);
  background: #fff; color: var(--ink); font: inherit; text-align: left; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.avw-missions:active { background: #F7F8FB; }
.avw-missions:focus-visible { outline: 3px solid #ec5f93; outline-offset: -3px; }
.avw-prize {
  position: relative; display: grid; place-items: center; width: 42px; height: 42px; border-radius: 13px; overflow: hidden;
  background: linear-gradient(160deg, #FFF3F8, #F1E9FF); color: #6E45B0;
  box-shadow: inset 0 0 0 1px rgba(110, 69, 176, .12);
}
.avw-prize img { display: block; width: 86%; height: 86%; object-fit: contain; filter: drop-shadow(0 2px 3px rgba(60, 40, 60, .18)); }
.avw-prize.is-bg img { width: 100%; height: 100%; object-fit: cover; filter: none; }
.avw-prize .icon { display: inline-flex; }
/* a prize waiting to be claimed: the tile wears a pink ring and breathes */
.avw-missions.has-prize .avw-prize { box-shadow: 0 0 0 2px #ec5f93, 0 4px 12px rgba(236, 95, 147, .35); animation: avw-ready 1.6s ease-in-out infinite; }
@keyframes avw-ready { 50% { transform: scale(1.07); } }
.avw-mt { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.avw-mt b { font-size: 15px; font-weight: 800; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.avw-steps { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; max-width: 168px; }
.avw-steps i { display: block; height: 6px; border-radius: 3px; background: #ECE7F3; }
.avw-steps i.is-on { background: linear-gradient(90deg, #FF8DB0, #EC5F93); }
.avw-count { font-family: var(--font-display); font-size: 17px; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--ink); }
.avw-go { display: inline-flex; color: #B9B2C2; }
@media (prefers-reduced-motion: no-preference) {
  .avw { animation: hd-in .4s cubic-bezier(.2, 1, .4, 1) backwards; }
  .avw-say { animation: avw-say-in .5s cubic-bezier(.2, 1.4, .4, 1) .3s backwards; }
}
@keyframes avw-say-in { from { opacity: 0; transform: translateX(12px) scale(.86); } }
@media (prefers-reduced-motion: reduce) { .avw-say.is-pop, .avw-missions.has-prize .avw-prize { animation: none; } }

/* The dress-up studio and the missions page (client/core/avatarStudio.js, missionsPage.js) are
   whole pages with their own bars; Home wraps each in the pushed-page shell (.sp-page: over the
   tab bar, sliding in from the right), and the page's own sticky foot keeps the safe area. */
.avl-page { padding-bottom: 0; }
.avl-page > * { flex: 1 0 auto; }
/* the missions page brings its own gutter; the studio takes its host's */
.avl-page.is-studio { padding-left: 20px; padding-right: 20px; }

/* the game's own page (app/gameDetail.js): the cover at the top of the hero, slowly drifting,
   its eyebrow on it as a chip */
.gd-cover .gd-chip {
  position: absolute; left: 12px; top: 12px; padding: 7px 10px 6px; border-radius: 999px;
  background: rgba(255, 255, 255, .92); box-shadow: 0 2px 10px rgba(23, 24, 28, .14);
}
.gd-hero.has-cover { padding: 10px 10px 22px; gap: 4px; }
.gd-cover {
  position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; margin-bottom: 12px;
  border-radius: 20px; overflow: hidden; background: #fff;
  box-shadow: 0 12px 24px rgba(60, 40, 60, .14);
}
.gd-cover img { display: block; width: 100%; height: 100%; object-fit: cover; transform-origin: 50% 60%; }
@media (prefers-reduced-motion: no-preference) { .gd-cover img { animation: gd-drift 16s ease-in-out infinite alternate; } }
@keyframes gd-drift { to { transform: scale(1.07); } }

/* ---- Letters to the Future on Home (2026-10-15, app/homeLetters.js) -------------------
   Under Your memories: the newest three letters, each the ONE letter card the letters page
   lists too (letter/cards.css, .lc-* — 2026-10-20), "See all" to that page. No letters yet:
   one inviting card. */
/* Write: the section's one quiet action, like every heading's */
.home-letters .hl-write {
  display: inline-flex; align-items: center; gap: 4px; min-height: 32px; margin-right: -4px; padding: 0 4px 0 8px;
  border-radius: 999px; background: none; color: var(--h-deep); text-decoration: none;
  font: 700 14px/1 var(--font-body); -webkit-tap-highlight-color: transparent;
}
.hl-write .icon svg { display: block; }
.hl-list { padding: 0 20px; }
.hl-more {
  width: max-content; margin: 10px auto 0; display: flex; align-items: center; min-height: 34px; padding: 0 16px; border-radius: 999px;
  border: 1px solid rgba(23, 24, 28, 0.08); background: #fff; color: var(--ink); font: 700 13px/1 var(--font-body);
  text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.hl-more[hidden] { display: none; }
/* no letters yet: one card that invites the first */
.hl-empty {
  display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 4px 12px; align-items: center;
  padding: 14px; border-radius: var(--h-r); text-decoration: none; color: var(--ink);
  background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
  animation: hd-in .45s cubic-bezier(.2, .9, .3, 1) both; -webkit-tap-highlight-color: transparent;
}
.hl-empty img { grid-row: span 2; width: 72px; height: 72px; object-fit: contain; }
.hl-empty-copy { display: grid; gap: 3px; min-width: 0; }
.hl-empty-copy b { font: 800 15px/1.25 var(--font-display); }
.hl-empty-copy span { font-size: 12.5px; line-height: 1.35; color: var(--h-muted); }
.hl-empty-go {
  justify-self: start; display: inline-flex; align-items: center; gap: 4px; margin-top: 6px; padding: 7px 12px;
  border-radius: 999px; background: #ec5f93; color: #fff; font: 800 13px/1 var(--font-body);
}
.hl-empty-go .icon svg { display: block; }
@media (prefers-reduced-motion: reduce) {
  .hl-empty { animation: none; }
}

/* ---- Which game next (client/core/ideasBoard.js injects .ih): Home's white card ----------- */
.home-dash > .ih { background: var(--h-card); border: 1px solid var(--h-line); border-radius: var(--h-r); box-shadow: var(--h-shadow); }
.home-dash > .ih .ih-sub { color: var(--h-muted); font-weight: 500; }
.home-dash > .ih .ih-title { font-size: 15px; font-weight: 700; }

/* ---- Our moments on Home (2026-10-19, app/homeMoments.js; second look 2026-10-20) ---------------
   ONE card where Up next stood. It's the couple's, so it wears their two colours (the user,
   2026-10-20: "nicer colours, the pink and blue identity, not childish"): white, with a faint pink
   wash from the top left and a faint blue one from the top right, and the brand's two dots by the
   title. Linked: the title row carries the streak as a chip (the flame by level, app/streak.js)
   and a chevron; the newest moment as one line, "Your turn" as a small pink tag, their picture
   beside it; THIS WEEK's seven days (streak.js weekRow, styled with the streak's) with "4 of 7
   days" — or the time left today, in amber, while the streak waits; and the pink "I miss you".
   The whole card is a button to the moments page (laid under everything, the Our week card's
   pattern); the picture, the streak and the pill are their own buttons above it.
   Connected to no one (.is-solo): the connect card (client/ui/momentsPage.css .mpc-*) and, under
   a hairline, the people from before (.mph-*, .hmc-past) — every part its own button. */
.home-moments { min-width: 0; }
.home-dash > .home-moments[hidden] { display: none; }
.hmc {
  position: relative; display: flex; flex-direction: column; gap: 14px; min-width: 0;
  margin: 12px 20px 0; padding: 16px;
  border-radius: var(--h-r); border: 1px solid #F2E6EE; box-shadow: var(--h-shadow);
  background:
    radial-gradient(110% 80px at 0% 0%, rgba(255, 214, 230, .5), rgba(255, 214, 230, 0) 100%),
    radial-gradient(110% 80px at 100% 0%, rgba(214, 228, 255, .55), rgba(214, 228, 255, 0) 100%),
    var(--h-card);
  color: var(--h-ink); transition: transform .12s ease;
}
.hmc-open {
  position: absolute; inset: 0; z-index: 0; padding: 0; border: 0; border-radius: inherit;
  background: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.hmc-open:focus-visible { outline: 2px solid var(--h-deep); outline-offset: 2px; }
.hmc.is-linked > :not(.hmc-open) { position: relative; pointer-events: none; }
.hmc-pic, .hmc-streak, .hmc-miss { pointer-events: auto; }
.hmc:has(.hmc-open:active) { transform: scale(.985); }
.hmc-head { display: flex; align-items: center; gap: 8px; min-height: 30px; }
/* not connected: the way into the page and its history (homeMoments.js soloCard) */
.hmc-hist {
  flex: none; display: inline-flex; align-items: center; gap: 2px; min-height: 32px; margin-right: -6px; padding: 0 4px 0 10px;
  border: 0; border-radius: 999px; background: none; color: var(--h-deep);
  font: 700 13px/1 var(--font-body); cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.hmc-hist[hidden] { display: none; }
.hmc-hist .icon { display: inline-flex; }
.hmc-hist:active { background: var(--h-tint); }
.hmc-hist:focus-visible { outline: 2px solid var(--h-deep); outline-offset: 1px; }
.hmc-title {
  flex: 1 1 auto; min-width: 0; margin: 0; display: inline-flex; align-items: center; gap: 8px;
  font-size: 15px; font-weight: 750; letter-spacing: -.01em; color: var(--h-ink);
}
.hmc-dots { flex: none; display: inline-flex; gap: 3px; }
.hmc-dots i { display: block; width: 7px; height: 7px; border-radius: 50%; background: #FF8DB5; }
.hmc-dots i.b { background: #8DB8FF; }
.hmc-go { flex: none; display: inline-grid; place-items: center; margin-right: -4px; color: #B9BCC6; }
/* the streak: a chip — pink once today counts, grey otherwise: with none, and while today still has
   to count (its flame grey, the hourglass on it — the user, 2026-10-23: an amber chip read as a
   streak already earned today) */
.hmc-streak {
  flex: none; display: inline-flex; align-items: center; gap: 4px; min-height: 30px; padding: 0 11px 0 5px;
  border: 0; border-radius: 999px; background: rgba(255, 255, 255, .8); box-shadow: inset 0 0 0 1px var(--h-line);
  color: var(--h-muted); font: 700 12.5px/1 var(--font-body); white-space: nowrap;
  cursor: pointer; -webkit-tap-highlight-color: transparent; transition: transform .12s ease;
}
.hmc-streak .sk-flame { --skf: 22px; }
.hmc-streak .sk-badge { width: 13px; height: 13px; right: -4px; bottom: -3px; box-shadow: 0 0 0 1px #E4E2EA; }
.hmc-streak.is-on { background: #FFF0F5; box-shadow: inset 0 0 0 1px #FFD6E4; color: var(--h-deep); }
.hmc-streak.is-risk { color: #57545F; }
.hmc-streak:active { transform: scale(.96); }
.hmc-streak:focus-visible { outline: 2px solid var(--h-deep); outline-offset: 1px; }
.hmc-top { display: flex; align-items: center; gap: 12px; min-width: 0; }
.hmc-ava-wrap { position: relative; flex: none; display: block; }
.hmc-ava { display: block; width: 48px; height: 48px; border-radius: 50%; overflow: hidden; box-shadow: 0 0 0 2px #fff, 0 0 0 4px #FFD0E0; }
.hmc-ava.is-blue { box-shadow: 0 0 0 2px #fff, 0 0 0 4px #C9DDFF; }
.hmc-ava .avatar-pic { width: 100%; height: 100%; font-size: 18px; font-weight: 800; }
.hmc-dot { position: absolute; right: -2px; bottom: -2px; width: 13px; height: 13px; border-radius: 50%; background: #34C77B; box-shadow: 0 0 0 2.5px #fff; }
.hmc-dot[hidden] { display: none; }
.hmc-copy { flex: 1 1 auto; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.hmc-t { font-size: 16px; font-weight: 750; line-height: 1.25; letter-spacing: -.015em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hmc-s { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 13px; font-weight: 500; line-height: 1.3; color: var(--h-muted); }
.hmc-when { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hmc-turn {
  flex: none; padding: 3px 8px; border-radius: 999px; background: #FFE6EF; color: var(--h-deep);
  font-style: normal; font-size: 11.5px; font-weight: 750; line-height: 1.2; white-space: nowrap;
}
.hmc-turn[hidden] { display: none; }
.hmc-pic {
  flex: none; position: relative; width: 52px; height: 52px; padding: 0; border: 0; border-radius: 14px;
  overflow: hidden; background: var(--h-grey); cursor: zoom-in; -webkit-tap-highlight-color: transparent;
  box-shadow: 0 0 0 2px #fff, 0 4px 12px -2px rgba(60, 40, 60, .16);
}
.hmc-pic[hidden] { display: none; }
.hmc-pic img { display: block; width: 100%; height: 100%; object-fit: cover; }
.hmc-pic.is-doodle { background: var(--h-paper); }
.hmc-pic.is-doodle img { object-fit: contain; filter: drop-shadow(0 0 .6px rgba(23, 24, 28, .55)); }
.hmc-pic.is-broken img { visibility: hidden; }
.hmc-pic:focus-visible { outline: 2px solid var(--h-deep); outline-offset: 2px; }
/* this week: the label and how many (or the time left), then the seven days */
.hmc-week { display: flex; flex-direction: column; gap: 8px; }
.hmc-week-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.hmc-week-l { font-size: 12.5px; font-weight: 650; color: var(--h-muted); }
.hmc-week-n { font-size: 12.5px; font-weight: 700; color: var(--h-deep); white-space: nowrap; }
.hmc-week-n.is-risk { color: #8A5300; }
.hmc-miss {
  display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 50px;
  margin: 2px 0 0; border: 0; border-radius: 999px; color: #fff;
  background: linear-gradient(135deg, #FF86B2 0%, #EC5F93 55%, #E0508A 100%);
  font: 700 16px/1 var(--font-body); cursor: pointer; -webkit-tap-highlight-color: transparent;
  box-shadow: 0 10px 20px -12px rgba(236, 95, 147, .8);
  transition: transform .12s ease;
}
.hmc-miss:active { transform: scale(.98); }
.hmc-miss:focus-visible { outline: 3px solid #FFC2D8; outline-offset: 2px; }
/* connected to no one: the connect card, then the people from before under a hairline */
.hmc.is-solo { gap: 12px; }
.hmc-past { padding-top: 12px; border-top: 1px solid var(--h-line); }
@media (prefers-reduced-motion: no-preference) {
  .home-moments .hmc { animation: hd-in .4s cubic-bezier(.2, 1, .4, 1) backwards; }
  .home-moments.is-settled .hmc { animation: none; }
}

/* ---- The streak card (2026-10-19, app/streak.js) — the moments page's (off Home the same day:
   the product owner took the widget off and kept its page) ----------------------------------------
   The reference's streak card, made TikTok-like (2026-10-20): the flame and the number lead —
   the flame coloured by the streak's level, dimmed with an hourglass while today still has to
   count — then one muted line, this week's seven days (done ones filled pink with a white check,
   a day the week's freeze covered ice blue with a snowflake, joined by a soft band; today
   ringed; the rest grey), "4 of 7 days this week" and the freeze. The whole card is a button. */
.sk-card {
  position: relative; display: flex; flex-direction: column; gap: 14px; min-width: 0; padding: 16px;
  border-radius: var(--h-r); background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
  color: var(--h-ink); transition: transform .12s ease;
}
.sk-open {
  position: absolute; inset: 0; z-index: 0; padding: 0; border: 0; border-radius: inherit;
  background: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.sk-open:focus-visible { outline: 2px solid var(--h-deep); outline-offset: 2px; }
.sk-card > :not(.sk-open) { position: relative; pointer-events: none; }
.sk-card:has(.sk-open:active) { transform: scale(.985); }
.sk-top { display: flex; align-items: center; gap: 12px; min-width: 0; }
.sk-copy { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.sk-head { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; min-width: 0; }
.sk-title { display: inline-flex; align-items: baseline; gap: 5px; font-size: 20px; font-weight: 800; line-height: 1.15; letter-spacing: -.02em; color: var(--h-ink); }
.sk-n { font-family: var(--font-display); font-size: 32px; font-weight: 800; line-height: 1; letter-spacing: -.04em; color: var(--sk-ink); font-variant-numeric: tabular-nums; }
.sk-unit { font-size: 15px; font-weight: 750; letter-spacing: -.01em; color: var(--h-ink); white-space: nowrap; }
.sk-line { font-size: 13px; font-weight: 500; line-height: 1.35; color: var(--h-muted); }
.sk-go { flex: none; display: inline-flex; color: #B9BCC6; }
.sk-meta { display: flex; flex-direction: column; align-items: center; gap: 8px; }

/* the flame by level (streak.js streakFlame, STREAK_LEVELS): ONE picture, app/assets/home/
   streak.webp, re-coloured with a filter and haloed in the level's tint — grey with no streak,
   peach (1-2 days), orange (3-6), hot pink (7-29), violet (30-99), gold in a turning ring (100+).
   The level's ink and tint also colour the number and the level's pill (data-sk-level on the
   card, the page's hero and the flame itself). While today still has to count it is GREY —
   no colour, no glow — and wears an hourglass; it lights up in its level's colour the moment
   today counts (2026-10-23, the user: a dimmed but still yellow flame read as done today). */
.sk-card, .skp-hero, .sk-flame { --sk-ink: #6B6F7A; --sk-tint: #F1F2F5; --sk-glow: rgba(185, 188, 198, .3); --sk-f: grayscale(1) opacity(.45); }
[data-sk-level="1"] { --sk-ink: #A4470F; --sk-tint: #FFF1E5; --sk-glow: rgba(255, 196, 150, .55); --sk-f: saturate(.92); }
[data-sk-level="2"] { --sk-ink: #9C4300; --sk-tint: #FFEEDD; --sk-glow: rgba(255, 168, 96, .5); --sk-f: saturate(1.12); }
[data-sk-level="3"] { --sk-ink: #B3285C; --sk-tint: #FFE6EE; --sk-glow: rgba(255, 112, 158, .48); --sk-f: hue-rotate(-20deg) saturate(1.3); }
[data-sk-level="4"] { --sk-ink: #6B3FC4; --sk-tint: #F1EAFF; --sk-glow: rgba(160, 118, 255, .45); --sk-f: hue-rotate(-58deg) saturate(1.25); }
[data-sk-level="5"] { --sk-ink: #875A00; --sk-tint: #FFF3D6; --sk-glow: rgba(255, 200, 80, .6); --sk-f: hue-rotate(16deg) saturate(1.5) brightness(1.06); }
.sk-flame {
  --skf: 64px;
  position: relative; isolation: isolate; flex: none; display: grid; place-items: center;
  width: var(--skf); height: var(--skf);
}
.sk-flame::before {
  content: ""; position: absolute; inset: -6%; z-index: -1; border-radius: 50%;
  background: radial-gradient(closest-side, var(--sk-glow) 0%, var(--sk-glow) 38%, transparent 100%);
}
.sk-flame img { display: block; width: 92%; height: 92%; object-fit: contain; filter: var(--sk-f); transform-origin: 50% 88%; transition: filter .35s ease; }
.sk-flame[data-sk-level="5"]::after {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: 50%;
  background: conic-gradient(from 0deg, #FFD36E, #FF9EC4, #9EC9FF, #FFD36E);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px));
}
.sk-flame.is-risk { --sk-glow: rgba(185, 188, 198, .3); }
.sk-flame.is-risk img { filter: grayscale(1) opacity(.5); }
.sk-badge {
  position: absolute; right: -2px; bottom: 0; z-index: 1; display: grid; place-items: center;
  width: 24px; height: 24px; border-radius: 50%; background: #fff; color: #6B6F7A;
  box-shadow: 0 0 0 1.5px #E4E2EA, 0 3px 8px -2px rgba(23, 24, 28, .25);
}
.sk-badge[hidden] { display: none; }
.sk-badge .icon { display: inline-flex; }
/* the level's name, a pill in its tint */
.sk-level {
  display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 999px;
  background: var(--sk-tint); color: var(--sk-ink); font-size: 11.5px; font-weight: 750; line-height: 1.2; white-space: nowrap;
}
.sk-level[hidden] { display: none; }
/* while today still has to count: the hourglass and the time the server's day has left */
.sk-risk {
  display: inline-flex; align-items: center; gap: 5px; margin-top: 2px; padding: 4px 10px 4px 8px; border-radius: 999px;
  background: #FFF3DC; color: #8A5300; font-size: 12px; font-weight: 700; line-height: 1.2; white-space: nowrap;
}
.sk-risk[hidden] { display: none; }
.sk-risk .icon { display: inline-flex; }
/* the restores' pill (the old freeze's, from an older server: ice while it's there, grey once spent) */
.sk-freeze {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 5px 11px 5px 9px; border-radius: 999px;
  background: #EAF4FF; color: #245E96; font-size: 12.5px; font-weight: 650; line-height: 1.25; text-align: left;
}
.sk-freeze[hidden] { display: none; }
.sk-freeze .icon, .sk-freeze-ic { flex: none; display: inline-flex; }
.sk-freeze[data-state="used"] { background: #F1F3F7; color: #5B6170; }
/* the restores (2026-10-21, replacing the freeze): amber while some are left, warmer when the
   streak broke yesterday and today can bring it back, grey once they're spent */
.sk-freeze[data-state="left"] { background: #FFF4E0; color: #8A5300; }
.sk-freeze[data-state="restore"] { background: #FFE6C2; color: #8A4100; font-weight: 750; }
.sk-card.is-broken .sk-n { color: #A9ADB8; }
.sk-card.is-broken .sk-flame img { filter: grayscale(.85) opacity(.7); }
@media (prefers-reduced-motion: no-preference) {
  .sk-flame:not(.is-risk)[data-sk-level="3"] img,
  .sk-flame:not(.is-risk)[data-sk-level="4"] img,
  .sk-flame:not(.is-risk)[data-sk-level="5"] img { animation: sk-flicker 2.6s ease-in-out infinite; }
  .sk-flame[data-sk-level="5"]::after { animation: sk-spin 7s linear infinite; }
  .sk-badge .icon { animation: sk-sand 2.8s ease-in-out infinite; }
}
@keyframes sk-flicker { 0%, 100% { transform: none; } 30% { transform: scale(1.04, .98) rotate(-1.5deg); } 65% { transform: scale(.98, 1.04) rotate(1.2deg); } }
@keyframes sk-spin { to { transform: rotate(1turn); } }
@keyframes sk-sand { 0%, 72% { transform: none; } 86%, 100% { transform: rotate(180deg); } }
/* the week as seven days (streak.js weekRow) — one look on Home's moments card, the streak card
   and the streak page (2026-10-19, the user: "not so plain"): a soft pink-to-blue tray; today's
   day in a pink pill; a day you both sent one filled pink with a white check, a run of them on
   one pink band (a halo behind each, joined to the next); a day not ticked shows its date —
   dashed while it's still to come; today ringed in pink and breathing until it's done */
.sk-week {
  --sk-dot: 32px;
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  padding: 12px 2px; border-radius: 18px;
  background: linear-gradient(135deg, #FFF2F7 0%, #FFF8FA 50%, #F0F5FF 100%);
  box-shadow: inset 0 0 0 1px rgba(236, 95, 147, .1);
}
.sk-day { display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: 0; }
.sk-dow { padding: 4px 7px; border-radius: 999px; font-size: 11.5px; font-weight: 650; line-height: 1; color: var(--h-muted); white-space: nowrap; }
.sk-day.is-today .sk-dow { background: var(--h-deep); color: #fff; font-weight: 800; box-shadow: 0 4px 10px -4px rgba(194, 65, 111, .8); }
.sk-track { position: relative; display: grid; place-items: center; width: 100%; height: calc(var(--sk-dot) + 8px); }
.sk-day.is-done .sk-track::before,
.sk-day.is-joined .sk-track::after { content: ""; position: absolute; top: 50%; height: calc(var(--sk-dot) + 8px); background: #FFD3E2; }
.sk-day.is-done .sk-track::before { left: 50%; width: calc(var(--sk-dot) + 8px); border-radius: 50%; transform: translate(-50%, -50%); }
.sk-day.is-joined .sk-track::after { left: 50%; width: 100%; transform: translateY(-50%); }
.sk-dot {
  position: relative; z-index: 1; box-sizing: border-box; display: grid; place-items: center;
  width: var(--sk-dot); height: var(--sk-dot); border: 1.5px solid #E5E6EC; border-radius: 50%;
  background: #fff; color: #fff;
}
.sk-dot svg { display: block; }
.sk-num { font-size: 12.5px; font-weight: 700; line-height: 1; color: #8F929C; font-variant-numeric: tabular-nums; }
.sk-day.is-future .sk-dot { border-style: dashed; border-color: #D6D8DF; background: rgba(255, 255, 255, .55); }
.sk-day.is-future .sk-num { color: #BDC0C8; font-weight: 600; }
.sk-day.is-done .sk-dot {
  border-color: transparent; background: linear-gradient(150deg, #FF91B5 0%, #EC5F93 58%, #D84A7F 100%);
  box-shadow: 0 4px 10px -3px rgba(236, 95, 147, .75), inset 0 1px 0 rgba(255, 255, 255, .35);
}
.sk-day.is-today:not(.is-done) .sk-dot { border: 2px solid var(--h-pink); box-shadow: 0 0 0 4px rgba(236, 95, 147, .14); }
.sk-day.is-today:not(.is-done) .sk-num { color: var(--h-deep); font-weight: 800; }
.sk-day.is-today.is-done .sk-dot { box-shadow: 0 0 0 2.5px #fff, 0 0 0 5px #FF9DBF, 0 6px 14px -4px rgba(236, 95, 147, .8); }
/* a day the week's freeze covered: ice blue with a white snowflake, on an ice halo; the band
   that runs through it fades from pink to ice and back */
.sk-day.is-frozen .sk-track::before {
  content: ""; position: absolute; top: 50%; left: 50%; width: calc(var(--sk-dot) + 8px); height: calc(var(--sk-dot) + 8px);
  border-radius: 50%; transform: translate(-50%, -50%); background: #D9EEFF;
}
.sk-day.is-frozen .sk-dot {
  border-color: transparent; background: linear-gradient(150deg, #C4E6FF 0%, #84C5F4 58%, #5FA9E3 100%);
  box-shadow: 0 4px 10px -3px rgba(80, 150, 220, .7), inset 0 1px 0 rgba(255, 255, 255, .45);
}
.sk-day.is-joined.to-ice .sk-track::after { background: linear-gradient(90deg, #FFD3E2, #D9EEFF); }
.sk-day.is-frozen.is-joined .sk-track::after { background: linear-gradient(90deg, #D9EEFF, #FFD3E2); }
/* a day a restore brought back: amber with the restore mark, on an amber halo */
.sk-day.is-restored .sk-track::before {
  content: ""; position: absolute; top: 50%; left: 50%; width: calc(var(--sk-dot) + 8px); height: calc(var(--sk-dot) + 8px);
  border-radius: 50%; transform: translate(-50%, -50%); background: #FFE9C7;
}
.sk-day.is-restored .sk-dot {
  border-color: transparent; color: #fff; background: linear-gradient(150deg, #FFD48A 0%, #F7A440 58%, #EC8A2A 100%);
  box-shadow: 0 4px 10px -3px rgba(236, 138, 42, .7), inset 0 1px 0 rgba(255, 255, 255, .45);
}
.sk-day.is-joined.to-back .sk-track::after { background: linear-gradient(90deg, #FFD3E2, #FFE2B5); }
.sk-day.is-restored.is-joined .sk-track::after { background: linear-gradient(90deg, #FFE2B5, #FFD3E2); }
.sk-foot { font-size: 12.5px; font-weight: 600; color: var(--h-muted); text-align: center; }
.hmc-week-foot { font-size: 12.5px; font-weight: 600; color: var(--h-muted); text-align: center; }
@media (prefers-reduced-motion: no-preference) {
  .sk-day.is-done .sk-dot, .sk-day.is-frozen .sk-dot, .sk-day.is-restored .sk-dot { animation: sk-pop .36s cubic-bezier(.2, 1.4, .4, 1) backwards; }
  .sk-day.is-today:not(.is-done) .sk-dot { animation: sk-breathe 2.4s ease-in-out infinite; }
}
@keyframes sk-pop { from { transform: scale(.6); opacity: 0; } }
@keyframes sk-breathe { 50% { box-shadow: 0 0 0 7px rgba(236, 95, 147, .07); } }

/* ---- The streak page (2026-10-19, app/streakPage.js) -------------------------------------------
   One calm column on the paper: the flame big over the number and its level (2026-10-20, the
   TikTok look), the hourglass while today still has to count, the week; the restores (2026-10-21,
   replacing the week's freeze); two numbers (the longest streak, the date-night streak); the next milestone; this month as a
   small calendar; one line on what counts; one pink "I miss you". */
.skp-page { padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px)); }
.skp { width: min(100%, 560px); margin: 0 auto; display: flex; flex-direction: column; gap: 12px; padding: 4px 20px 8px; box-sizing: border-box; }
.skp-hero {
  display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 20px 16px 18px; text-align: center;
  border-radius: 24px; background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.skp-flame { --skf: 128px; margin-bottom: 2px; }
.skp-flame .sk-badge { right: 4px; bottom: 6px; width: 36px; height: 36px; box-shadow: 0 0 0 2px #E4E2EA, 0 4px 12px -3px rgba(23, 24, 28, .28); }
.skp-title { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 30px; font-weight: 800; line-height: 1.1; letter-spacing: -.03em; color: var(--h-ink); }
.skp-n { font-family: var(--font-display); font-size: 64px; font-weight: 800; line-height: .95; letter-spacing: -.05em; color: var(--sk-ink); font-variant-numeric: tabular-nums; }
.skp-unit { font-size: 17px; font-weight: 750; letter-spacing: -.01em; color: var(--h-ink); }
.skp-hero .sk-level { margin-top: 6px; font-size: 12.5px; padding: 4px 11px; }
.skp-line { margin: 8px 0 0; max-width: 34ch; font-size: 14px; line-height: 1.4; color: var(--h-muted); }
.skp-hero .sk-risk { margin-top: 6px; font-size: 12.5px; }
.skp-hero .sk-week-slot { width: 100%; max-width: 420px; margin-top: 14px; }
.skp-hero .sk-week { --sk-dot: 36px; }
.skp-foot { margin: 12px 0 0; font-size: 13px; font-weight: 600; color: var(--h-muted); }
/* the restores (the old freeze's ice tile, from an older server): where they stand, one line on
   how, and the Restore button when the streak broke yesterday */
.skp-freeze {
  display: flex; flex-direction: column; align-items: stretch; min-width: 0; padding: 14px 16px;
  border-radius: 18px; background: linear-gradient(135deg, #F2F9FF 0%, #FFFFFF 70%); border: 1px solid #D6E9FA; box-shadow: var(--h-shadow);
}
.skp-freeze[hidden] { display: none; }
.skp-freeze-ic {
  flex: none; display: grid; place-items: center; width: 42px; height: 42px; border-radius: 14px;
  background: linear-gradient(150deg, #C4E6FF 0%, #84C5F4 60%, #5FA9E3 100%); color: #fff;
  box-shadow: 0 6px 14px -6px rgba(80, 150, 220, .8), inset 0 1px 0 rgba(255, 255, 255, .45);
}
.skp-freeze-ic .icon { display: inline-flex; }
.skp-freeze-copy { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.skp-freeze-t { font-size: 15px; font-weight: 700; line-height: 1.25; color: #1D4F80; }
.skp-freeze-how { font-size: 12.5px; font-weight: 500; line-height: 1.35; color: var(--h-muted); }
.skp-freeze[data-state="used"] { background: var(--h-card); border-color: var(--h-line); }
.skp-freeze[data-state="used"] .skp-freeze-ic { background: #EEF0F4; color: #7A8090; box-shadow: none; }
.skp-freeze[data-state="used"] .skp-freeze-t { color: var(--h-ink); }
/* the restores (2026-10-21): the same tile, amber; when the streak broke yesterday it carries the
   one Restore button under its words */
.skp-freeze-row { display: flex; align-items: center; gap: 12px; min-width: 0; }
.skp-freeze[data-state="left"], .skp-freeze[data-state="restore"] {
  background: linear-gradient(135deg, #FFF6E6 0%, #FFFFFF 72%); border-color: #FBDDAE;
}
.skp-freeze[data-state="left"] .skp-freeze-ic, .skp-freeze[data-state="restore"] .skp-freeze-ic {
  background: linear-gradient(150deg, #FFD48A 0%, #F7A440 60%, #EC8A2A 100%);
  box-shadow: 0 6px 14px -6px rgba(236, 138, 42, .85), inset 0 1px 0 rgba(255, 255, 255, .45);
}
.skp-freeze[data-state="left"] .skp-freeze-t, .skp-freeze[data-state="restore"] .skp-freeze-t { color: #7A3F00; }
.skp-freeze[data-state="none"], .skp-freeze[data-state="empty"] { background: var(--h-card); border-color: var(--h-line); }
.skp-freeze[data-state="none"] .skp-freeze-ic, .skp-freeze[data-state="empty"] .skp-freeze-ic { background: #EEF0F4; color: #7A8090; box-shadow: none; }
.skp-freeze[data-state="none"] .skp-freeze-t, .skp-freeze[data-state="empty"] .skp-freeze-t { color: var(--h-ink); }
.skp-restore {
  display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 50px; margin-top: 12px;
  border: 0; border-radius: 999px; background: linear-gradient(150deg, #F7A440 0%, #EC7A2A 100%); color: #fff;
  font: 750 16px/1 var(--font-body); cursor: pointer; -webkit-tap-highlight-color: transparent;
  box-shadow: 0 10px 20px -12px rgba(236, 122, 42, .95);
}
.skp-restore[hidden] { display: none; }
.skp-restore .icon { display: inline-flex; }
.skp-restore:disabled { opacity: .6; cursor: progress; }
.skp-restore:active:not(:disabled) { transform: scale(.98); }
.skp-restore:focus-visible { outline: 3px solid #FFD29C; outline-offset: 2px; }
.skp-hero.is-broken .skp-n { color: #A9ADB8; }
.skp-hero.is-broken .skp-flame img { filter: grayscale(.85) opacity(.7); }
/* the next milestone: its number, a bar in the level's colours, how far, and five of them */
.skp-miles {
  display: flex; flex-direction: column; gap: 10px; padding: 16px;
  border-radius: var(--h-r); background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.skp-miles-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.skp-miles-t { font-size: 15px; font-weight: 700; color: var(--h-ink); }
.skp-miles-goal { font-size: 15px; font-weight: 800; color: var(--h-deep); white-space: nowrap; font-variant-numeric: tabular-nums; }
.skp-miles-bar { position: relative; height: 10px; overflow: hidden; border-radius: 999px; background: #F1F2F5; }
.skp-miles-bar i {
  position: absolute; inset: 0 auto 0 0; display: block; min-width: 10px; border-radius: inherit;
  background: linear-gradient(90deg, #FFB37A 0%, #FF7FA8 55%, #EC5F93 100%); transition: width .5s cubic-bezier(.2, 1, .4, 1);
}
.skp-miles-foot { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; font-weight: 600; color: var(--h-muted); font-variant-numeric: tabular-nums; }
.skp-pips { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; margin-top: 2px; }
.skp-pip { display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 0; }
.skp-pip-dot {
  box-sizing: border-box; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  border: 1.5px dashed #D6D8DF; background: #fff; color: #fff;
}
.skp-pip-dot svg { display: block; }
.skp-pip-n { font-size: 12px; font-weight: 700; color: #8F929C; font-variant-numeric: tabular-nums; }
.skp-pip.is-done .skp-pip-dot { border: 0; background: linear-gradient(150deg, #FFB37A 0%, #EC5F93 100%); box-shadow: 0 3px 8px -3px rgba(236, 95, 147, .7); }
.skp-pip.is-done .skp-pip-n { color: var(--h-ink); }
.skp-pip.is-next .skp-pip-dot { border: 2px solid var(--h-pink); box-shadow: 0 0 0 4px rgba(236, 95, 147, .12); }
.skp-pip.is-next .skp-pip-n { color: var(--h-deep); font-weight: 800; }
.skp-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.skp-stat {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; padding: 14px;
  border-radius: 18px; background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.skp-stat-ic { display: grid; place-items: center; width: 36px; height: 36px; margin-bottom: 10px; border-radius: 12px; background: var(--h-tint); color: var(--h-deep); }
.skp-stat + .skp-stat .skp-stat-ic { background: var(--h-blue-tint); color: #2F64B8; }
.skp-stat-ic .icon { display: inline-flex; }
.skp-stat-n { display: flex; align-items: baseline; flex-wrap: wrap; gap: 5px; }
.skp-stat-n b { font-family: var(--font-display); font-size: 26px; font-weight: 800; line-height: 1.05; letter-spacing: -.03em; color: var(--h-ink); font-variant-numeric: tabular-nums; }
.skp-stat-n span { font-size: 13px; font-weight: 600; color: var(--h-muted); }
.skp-stat-l { font-size: 12.5px; font-weight: 600; line-height: 1.25; color: var(--h-muted); }
.skp-month {
  display: flex; flex-direction: column; gap: 10px; padding: 16px;
  border-radius: var(--h-r); background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.skp-month-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.skp-month-t { font-size: 15px; font-weight: 700; color: var(--h-ink); }
.skp-month-n { font-size: 12.5px; font-weight: 600; color: var(--h-muted); white-space: nowrap; }
.skp-cal-dow, .skp-cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.skp-cal-dow span { font-size: 11.5px; font-weight: 600; text-align: center; color: var(--h-muted); }
.skp-cal-day { display: grid; place-items: center; height: 40px; min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--h-ink); font-variant-numeric: tabular-nums; }
.skp-cal-day > span { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; }
.skp-cal-day.is-done > span { background: var(--h-pink); color: #fff; font-weight: 700; }
.skp-cal-day.is-today:not(.is-done) > span { box-shadow: inset 0 0 0 2px var(--h-pink); color: var(--h-deep); font-weight: 700; }
.skp-cal-day.is-today.is-done > span { box-shadow: 0 0 0 2px #fff, 0 0 0 4px #FFC2D6; }
.skp-cal-day.is-frozen > span { background: #DDF0FF; color: #1D4F80; font-weight: 700; box-shadow: inset 0 0 0 1.5px #A9D6F7; }
.skp-cal-day.is-restored > span { background: #FFF0D6; color: #8A4100; font-weight: 700; box-shadow: inset 0 0 0 1.5px #FFCF85; }
.skp-cal-day.is-future { color: #C3C6CF; }
.skp-how { margin: 4px 8px 0; font-size: 13px; line-height: 1.4; color: var(--h-muted); text-align: center; }
.skp-send {
  display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 52px; margin: 2px 0 0;
  border: 0; border-radius: 999px; background: var(--h-pink); color: #fff; text-decoration: none;
  font: 700 16px/1 var(--font-body); cursor: pointer; -webkit-tap-highlight-color: transparent;
  box-shadow: 0 10px 22px -12px rgba(236, 95, 147, .8); transition: transform .12s ease;
}
.skp-send[hidden] { display: none; }
.skp-send .icon { display: inline-flex; }
.skp-send:active { transform: scale(.98); }
.skp-send:disabled { opacity: .6; }
.skp-send:focus-visible { outline: 3px solid #FFC2D8; outline-offset: 2px; }
.skp-link {
  align-self: center; display: inline-flex; align-items: center; gap: 2px; min-height: 40px; padding: 0 8px;
  border: 0; border-radius: 999px; background: none; color: var(--h-deep); font: 700 14px/1 var(--font-body); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.skp-link .icon { display: inline-flex; }
.skp-toast {
  position: fixed; left: 50%; bottom: calc(28px + env(safe-area-inset-bottom, 0px)); z-index: 350; translate: -50% 0;
  display: inline-flex; align-items: center; gap: 7px; max-width: calc(100vw - 40px);
  padding: 10px 16px; border-radius: 999px; background: var(--h-ink); color: #fff;
  font: 700 14px/1.2 var(--font-body); box-shadow: 0 10px 24px rgba(23, 24, 28, .25);
  opacity: 0; transform: translateY(8px); transition: opacity .2s ease, transform .2s ease; pointer-events: none;
}
.skp-toast.is-on { opacity: 1; transform: none; }
.skp-toast .icon { display: inline-flex; color: #FF9EC4; }
@media (prefers-reduced-motion: no-preference) {
  .skp-flame { animation: hw-bob 3.6s ease-in-out infinite; }
}

/* ---- Today's question (2026-10-20, app/homeDaily.js + app/dailyPage.js) ------------------------
   The reference's warm card, right under Home's three numbers: a sunset gradient in the app's
   pink, the words on the left, one small dark pill. Since 2026-10-21 (the user: "I don't like its
   asset, it isn't clear, make it fun and unique") the card on Home is what the question IS, a card
   from Honest Cards: that deck's own back fanned over a second card on the right (the letter on
   top once you've both answered), the deck's name beside the title, the two of you under the
   question (your faces with a mark each: in, sealed, still to come) and the time till tomorrow's
   card by the pill. The page keeps the pink + blue pair (app/assets/widgets/daily/ — holding up
   the question, thinking, waiting, both in, saved). The whole card is one button to its page, the pill its
   label (the moments card's pattern: the button lies under everything, which lets the taps
   through). The white type is 19px+ bold, large text, over 3:1 on every stop of the gradient;
   the small words sit on white chips. The page (app/dailyPage.js) is the card's own ritual:
   the card turned over, a note sealed into an envelope, the two envelopes opened together. */
.home-daily { min-width: 0; }
.hdq {
  --dq-warm: linear-gradient(118deg, #E8623F 0%, #EC5F6A 52%, #DE4F80 100%);
  position: relative; isolation: isolate; overflow: hidden; box-sizing: border-box; min-width: 0;
  border-radius: 24px; background: var(--dq-warm); color: #fff;
  box-shadow: 0 16px 30px -20px rgba(222, 79, 128, .95), 0 2px 6px rgba(232, 98, 63, .16);
  display: block; margin: 14px 20px 0; padding: 16px 122px 16px 18px; min-height: 186px; transition: transform .12s ease;
}
/* two soft lights on the gradient, under everything */
.hdq::before, .hdq::after { content: ""; position: absolute; z-index: -1; border-radius: 50%; pointer-events: none; }
.hdq::before { width: 240px; height: 240px; right: -70px; top: -110px; background: radial-gradient(closest-side, rgba(255, 210, 160, .55), transparent); }
.hdq::after { width: 200px; height: 200px; left: -80px; bottom: -120px; background: radial-gradient(closest-side, rgba(255, 255, 255, .2), transparent); }
.hdq-open {
  position: absolute; inset: 0; z-index: 0; padding: 0; border: 0; border-radius: inherit;
  background: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.hdq-open:disabled { cursor: default; }
.hdq-open:focus-visible { outline: 3px solid #FFD2B8; outline-offset: 3px; }
.hdq > :not(.hdq-open) { pointer-events: none; }
.hdq:has(.hdq-open:active:not(:disabled)) { transform: scale(.985); }
.hdq-copy { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 10px; min-height: 154px; }
.hdq-top { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.hdq-eyebrow, .hdq-chip {
  display: inline-flex; align-items: center; gap: 5px; max-width: 100%; padding: 5px 10px 5px 8px; box-sizing: border-box;
  border-radius: 999px; font: 700 12px/1.1 var(--font-body); white-space: nowrap;
}
.hdq-eyebrow { background: rgba(255, 255, 255, .95); color: #B23A5F; }
.hdq-eyebrow > span:last-child { overflow: hidden; text-overflow: ellipsis; }
.hdq-chip { background: rgba(23, 24, 28, .3); color: #fff; }
.hdq-chip[hidden], .hdq-pill[hidden], .hdq-who[hidden], .hdq-face[hidden] { display: none; }
/* today's deck, by name: a glass chip beside the title */
.hdq-chip.is-deck { background: rgba(255, 255, 255, .22); color: #fff; padding: 5px 10px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .32); }
/* the streak: the widgets' flame, then the days */
.hdq-chip.is-streak { padding-left: 4px; gap: 3px; }
.hdq-chip.is-streak img { display: block; width: 18px; height: 18px; object-fit: contain; }
.hdq-eyebrow .icon, .hdq-chip .icon, .hdq-pill .icon { display: inline-flex; flex: none; }
.hdq-chip .icon { color: #FFD2A8; }
.hdq-text {
  margin: 0; font-size: 19px; font-weight: 800; line-height: 1.26; letter-spacing: -.015em;
  text-shadow: 0 1px 2px rgba(120, 30, 40, .16); overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.hdq-pill {
  margin-top: auto; display: inline-flex; align-items: center; gap: 7px; min-height: 38px; max-width: 100%;
  padding: 0 16px 0 13px; box-sizing: border-box; border-radius: 999px; background: #17181C; color: #fff;
  font: 700 14px/1 var(--font-body); white-space: nowrap; box-shadow: 0 8px 16px -10px rgba(23, 24, 28, .85);
  transition: transform .12s ease;
}
.hdq-pill > span:last-child { overflow: hidden; text-overflow: ellipsis; }
.hdq-pill-ic { display: inline-flex; flex: none; }
.hdq:has(.hdq-open:active:not(:disabled)) .hdq-pill { transform: scale(.96); }
/* the two of you: your faces (who's in, whose answer is sealed) and the words for it */
.hdq-who {
  display: inline-flex; align-items: center; gap: 8px; max-width: 100%; box-sizing: border-box;
  padding: 4px 12px 4px 4px; border-radius: 999px; background: rgba(255, 255, 255, .18);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .26);
}
.hdq-faces { display: inline-flex; flex: none; }
.hdq-face {
  position: relative; display: grid; place-items: center; width: 28px; height: 28px; flex: none;
  border-radius: 50%; border: 2px solid #fff; box-sizing: border-box; overflow: visible;
}
.hdq-face.is-pink { background: #FFF1F7; }
.hdq-face.is-blue { background: #EEF4FF; }
.hdq-face + .hdq-face { margin-left: -7px; }
.hdq-face img { display: block; width: 26px; height: 26px; border-radius: 50%; object-fit: contain; }
/* the real profile pictures (2026-10-23): a photo fills the circle */
.hdq-pic { display: block; width: 100%; height: 100%; border-radius: 50%; overflow: hidden; }
.hdq-face .avatar-pic img { width: 100%; height: 100%; object-fit: cover; }
/* a mark on each face: in (green tick), sealed (a lock: theirs is in, it opens once yours is),
   still to come (a pencil for you, an hourglass for them) */
.hdq-mark { position: absolute; right: -4px; bottom: -4px; display: grid; place-items: center; width: 15px; height: 15px; border-radius: 50%; background: #fff; color: #B23A5F; box-shadow: 0 1px 3px rgba(80, 20, 40, .3); }
.hdq-mark:empty { display: none; }
.hdq-mark .icon { display: inline-flex; }
.hdq-face[data-state="done"] .hdq-mark, .hdq-face[data-state="open"] .hdq-mark { background: #34C759; color: #fff; }
.hdq-face[data-state="sealed"] .hdq-mark { background: #17181C; color: #fff; }
.hdq-face[data-state="wait"] .hdq-mark { color: #8A8F9C; }
.hdq-who-t { min-width: 0; font: 650 13px/1.25 var(--font-body); color: #fff; text-shadow: 0 1px 2px rgba(120, 30, 40, .18); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* the pill, and the time till tomorrow's card beside it */
.hdq-foot { margin-top: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; max-width: 100%; }
.hdq-foot .hdq-pill { margin-top: 0; }
.hdq-next { display: inline-flex; align-items: center; gap: 5px; font: 650 12.5px/1.2 var(--font-body); color: rgba(255, 255, 255, .92); white-space: nowrap; font-variant-numeric: tabular-nums; }
.hdq-next .icon { display: inline-flex; }
/* the picture on the right (2026-10-21 — it was two deck backs fanned until the user asked for
   another): the pair from the page's Higgsfield set showing where the day stands, standing on the
   card's foot — the pair with a card, the mailbox asleep, the two of them reading… */
.hdq-deck { position: absolute; z-index: 1; right: 6px; bottom: 10px; width: 116px; height: 118px; pointer-events: none; }
.hdq-pose { position: absolute; right: 0; bottom: 0; display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; filter: drop-shadow(0 8px 12px rgba(120, 30, 60, .3)); }
/* nothing known yet: the card's shape, two pale bars where the words go */
.hdq-skel { display: block; width: 100%; height: 16px; margin: 6px 0 8px; border-radius: 8px; background: rgba(255, 255, 255, .34); }
.hdq-skel.is-short { width: 62%; }
/* the pair in the card's right corner, standing on its foot */
.hdq-art { position: absolute; right: 0; bottom: 0; z-index: 1; width: 150px; height: 124px; pointer-events: none; }
.hdq-art img { position: absolute; right: -4px; bottom: -2px; display: block; width: 154px; height: auto; filter: drop-shadow(0 6px 10px rgba(120, 30, 60, .22)); }
@media (prefers-reduced-motion: no-preference) {
  .home-daily .hdq { animation: hd-in .4s cubic-bezier(.2, 1, .4, 1) backwards; }
  .hdq-art img { animation: hw-bob 3.6s ease-in-out infinite; }
  .hdq.is-loading .hdq-skel { animation: dq-glow 1.4s ease-in-out infinite; }
  /* the pair bobs; a press lifts it */
  .hdq-pose { animation: hw-bob 3.6s ease-in-out infinite; transition: scale .3s cubic-bezier(.34, 1.45, .5, 1); }
  .hdq:has(.hdq-open:hover:not(:disabled)) .hdq-pose { scale: 1.06; }
}
@keyframes dq-glow { 50% { opacity: .55; } }
/* the page's marks are stickers from the same set (2026-10-21). Its ground is plain (the user,
   2026-10-21: "on a phone take the background away" — the question-mark pattern is gone; a wide
   screen keeps Home's soft wash, below) */
.dq-sticker { display: block; flex: none; object-fit: contain; filter: drop-shadow(0 2px 3px rgba(120, 30, 60, .16)); }
.hdq-eyebrow .dq-sticker { width: 18px; height: 18px; filter: none; }
.dq-label.has-sticker { display: flex; align-items: center; gap: 8px; }
.dq-stat .dq-stat-ic.is-sticker, .dq-stat + .dq-stat .dq-stat-ic.is-sticker { background: none; box-shadow: none; }
.dq-stat-ic.is-sticker .dq-sticker { width: 30px; height: 30px; }
.dq-solo-t .dq-sticker { width: 26px; height: 26px; }
.sp-page.dq-page { background: var(--paper, #F8F9FB); }

/* the page (second round 2026-10-20, "fix its UI, responsive and clear"; third 2026-10-21, the
   card / the note / the post below). TODAY (.dq-today: today's card, the note to write on, the
   two envelopes — or the not-linked card) and THE REST (.dq-side: the two numbers, the past days).
   One column on a phone and an upright iPad; from a 900px page today is the wide column on the
   left and the rest runs beside it, scrolling with the page. The page measures itself (a
   container query, the week page's rule), so the sidebar is already taken off; the back link
   lines up with the column. */
.sp-page.dq-page:not(.mp-page) { container: dqpage / inline-size; padding-left: 0; padding-right: 0; }
.dq-page { --dq-col: 560px; --dq-pad: 20px; padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px)); }
/* the chevron's ink starts ~10px into the back link, so this puts it on the content's edge */
.dq-page > .sp-bar {
  padding-left: calc(max(0px, (100% - var(--dq-col)) / 2) + var(--dq-pad) - 10px);
  padding-right: calc(max(0px, (100% - var(--dq-col)) / 2) + var(--dq-pad) - 10px);
}
.dq {
  flex: none; width: 100%; max-width: var(--dq-col); margin: 0 auto; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 14px; padding: 4px var(--dq-pad) 8px;
}
.dq-today, .dq-side { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.dq [hidden] { display: none !important; }
.dq-label { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -.01em; color: var(--h-ink); }
/* the words sit inside the note's own margin and edges (fractions of the note: its margin line is
   at 8.5% of its width, its paper starts under the tape at ~6% of its height) */
.dq-input {
  position: absolute; left: 11%; right: 5.5%; top: 13%; bottom: 7%; display: block; width: auto; height: auto; min-height: 0;
  box-sizing: border-box; resize: none; margin: 0; padding: 0 4px; overflow-y: auto; border: 0; border-radius: 0;
  background: transparent repeating-linear-gradient(180deg, transparent 0, transparent 29px, rgba(226, 150, 150, .42) 29px, rgba(226, 150, 150, .42) 30px);
  background-attachment: local; color: var(--h-ink); font: 600 16px/30px var(--font-body);
}
.dq-input::placeholder { color: #B7A99A; }
.dq-input:focus { outline: none; }
/* under the box: why the button waits (or that Enter sends) and the count, then the button —
   a full-width row of its own on a phone, beside them from a 600px page */
.dq-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; }
.dq-meta { flex: 1 1 100%; display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.dq-hint { min-width: 0; font-size: 13px; font-weight: 600; line-height: 1.3; color: var(--h-muted); }
.dq-count { flex: none; margin-left: auto; font-size: 12.5px; font-weight: 600; color: var(--h-muted); font-variant-numeric: tabular-nums; }
.dq-count.is-near { color: var(--h-deep); }
.dq-solo { display: flex; flex-direction: column; gap: 12px; padding: 16px; border-radius: var(--h-r); background: var(--h-tint); border: 1px solid #FFDCE8; }
.dq-solo-t { display: flex; align-items: flex-start; gap: 8px; margin: 0; font-size: 14px; font-weight: 600; line-height: 1.4; color: var(--h-ink); }
.dq-solo-t .icon { flex: none; display: inline-flex; margin-top: 2px; color: var(--h-deep); }
.dq-connect {
  display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 50px; padding: 0 22px; box-sizing: border-box;
  border-radius: 999px; background: var(--h-pink); color: #fff; text-decoration: none; text-align: center;
  font: 700 15px/1.2 var(--font-body); box-shadow: 0 10px 22px -12px rgba(236, 95, 147, .8); transition: transform .12s ease, background .15s ease;
}
.dq-connect .icon { flex: none; display: inline-flex; }
.dq-connect:active { transform: scale(.98); }
.dq-connect[hidden] { display: none; }
.dq-connect:focus-visible { outline: 3px solid #FFC2D8; outline-offset: 2px; }
@media (hover: hover) {
  .dq-connect:hover { background: #DE4F86; }
}
/* two numbers: a big figure over what it counts (side by side once the row is wide enough) */
.dq-stats { container: dqstats / inline-size; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.dq-stat {
  display: flex; flex-direction: row; align-items: center; gap: 10px; min-width: 0; padding: 10px 12px;
  border-radius: 18px; background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.dq-stat-flame { display: block; width: 30px; height: 30px; object-fit: contain; }
.dq-stat-ic { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 12px; background: var(--h-tint); color: var(--h-deep); }
.dq-stat + .dq-stat .dq-stat-ic { background: #FFEEE4; color: #B4532F; }
.dq-stat-ic .icon { display: inline-flex; }
.dq-stat-copy { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.dq-stat-n { font-family: var(--font-display); font-size: 22px; font-weight: 800; line-height: 1; letter-spacing: -.03em; color: var(--h-ink); font-variant-numeric: tabular-nums; }
.dq-stat-l { font-size: 12px; font-weight: 600; line-height: 1.25; color: var(--h-muted); }
@container dqstats (min-width: 440px) {
  .dq-stat { flex-direction: row; align-items: center; gap: 14px; padding: 16px; }
  .dq-stat-ic { width: 44px; height: 44px; border-radius: 14px; }
}
/* the past days */
.dq-past-wrap { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.dq-past-h { margin: 6px 0 0; font-size: 18px; font-weight: 800; }
.dq-past { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.dq-day {
  display: grid; grid-template-columns: 34px minmax(0, 1fr); align-items: start; gap: 12px; padding: 14px 16px;
  border-radius: 18px; background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.dq-day-card { display: block; width: 34px; height: auto; border-radius: 5px; box-shadow: 0 4px 8px -4px rgba(60, 30, 60, .4); }
.dq-day-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.dq-day-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.dq-day-head b { font-size: 12.5px; font-weight: 700; color: var(--h-muted); }
.dq-day-tag { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; border-radius: 999px; background: var(--h-tint); color: var(--h-deep); font-size: 11.5px; font-weight: 700; }
.dq-day-tag .icon { display: inline-flex; }
.dq-day-q { margin: 0; font-size: 15px; font-weight: 700; line-height: 1.32; color: var(--h-ink); }
.dq-day-ans { display: flex; flex-direction: column; gap: 6px; }
.dq-line { display: grid; grid-template-columns: minmax(0, auto) minmax(0, 1fr); align-items: baseline; gap: 8px; padding: 8px 10px; border-radius: 12px; background: #FFF5F8; }
.dq-line.is-blue { background: #F1F6FF; }
.dq-line-who { max-width: 9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; font-weight: 700; color: var(--h-deep); }
.dq-line.is-blue .dq-line-who { color: #2F64B8; }
.dq-line-t { font-size: 14px; line-height: 1.4; color: var(--h-ink); overflow-wrap: anywhere; }
.dq-line-t.is-none { color: var(--h-muted); }
/* none yet: what fills it, and when */
.dq-empty {
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 18px 18px 22px;
  border-radius: 20px; border: 1.5px dashed #F2D6CC; background: rgba(255, 255, 255, .6); text-align: center;
}
.dq-empty img { width: 104px; height: auto; margin-bottom: 4px; }
.dq-empty b { font-size: 15px; font-weight: 700; line-height: 1.3; color: var(--h-ink); }
.dq-empty span { max-width: 32ch; font-size: 13px; font-weight: 500; line-height: 1.4; color: var(--h-muted); }
.dq-toast {
  position: fixed; left: 50%; bottom: calc(28px + env(safe-area-inset-bottom, 0px)); z-index: 350; translate: -50% 0;
  display: inline-flex; align-items: center; gap: 7px; max-width: calc(100vw - 40px);
  padding: 10px 16px; border-radius: 999px; background: var(--h-ink); color: #fff;
  font: 700 14px/1.2 var(--font-body); box-shadow: 0 10px 24px rgba(23, 24, 28, .25);
  opacity: 0; transform: translateY(8px); transition: opacity .2s ease, transform .2s ease; pointer-events: none;
}
.dq-toast.is-on { opacity: 1; transform: none; }
.dq-toast .icon { display: inline-flex; color: #FFB79C; }
/* ---- the page, third round (2026-10-21, the user: "honestly boring — a box and Send; make it
   unique"): today's CARD (its deck's back, turned over with a tap to its real front), the NOTE (the
   Higgsfield note card, "Seal and send", posted into the mailbox), the POST (two envelopes sealed
   with the wax seal, the mailbox asleep until theirs is in, opened together into two letters).
   The art is the user's Higgsfield set (art-src/higgsfield-daily/, cut by tools/daily-art.py);
   only the envelopes are still drawn here (their sheet was never made). */
.dq-table { display: flex; flex-direction: column; align-items: center; gap: 12px; padding-top: 2px; }
.dq-chips-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.dq-chip { display: inline-flex; align-items: center; height: 26px; padding: 0 11px; border-radius: 999px; background: #fff; border: 1px solid var(--h-line); font-size: 12.5px; font-weight: 700; color: var(--h-muted); }
.dq-chip.is-deck { background: var(--h-tint); border-color: #FFD3E2; color: var(--h-deep); }
.dq-cardwrap { position: relative; display: flex; flex-direction: column; align-items: center; gap: 12px; }
/* the card: 2:3, its back the deck's own art; turned, the deck's own front (tools/daily-art.py) */
.dq-flip {
  --deck: #F28DB2; --deck-ink: #C2416F; position: relative; display: block; width: 232px; aspect-ratio: 2 / 3; margin: 0; padding: 0;
  border: 0; background: none; cursor: pointer; perspective: 1100px; -webkit-tap-highlight-color: transparent;
}
.dq-flip:disabled, .dq-flip.is-turned { cursor: default; }
.dq-flip:focus-visible { outline: none; }
.dq-flip:focus-visible .dq-face { box-shadow: 0 0 0 4px #fff, 0 0 0 7px #FF8DB0; }
.dq-flip-in { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform .8s cubic-bezier(.3, 1.35, .5, 1); }
.dq-flip.is-turned .dq-flip-in { transform: rotateY(180deg); }
.dq-face {
  position: absolute; inset: 0; overflow: hidden; border-radius: 16px; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  box-shadow: 0 18px 30px -18px rgba(90, 30, 60, .55), 0 0 0 1px rgba(255, 255, 255, .6);
}
.dq-face.is-back img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* the face: the front's art under the words, which keep inside its border and clear of its
   ornaments — measured on the five fronts (tools/daily-art.py): the top ornaments end by 21.5% of
   the height, the bottom ones start at 77.9%, the border lines stand at 12% and 88% of the width.
   So: the deck's name just under the emblem, the question in the middle, the kind of card above the
   bottom flourishes; every place in % of the HEIGHT (top/bottom — a padding % would be of the
   width, which put the name on the emblem), every size in cqw so a smaller card keeps the lines */
.dq-face.is-front { transform: rotateY(180deg); container-type: inline-size; background: #FBF7E8; text-align: center; }
.dq-front-art { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: fill; pointer-events: none; }
.dq-front-stamp {
  position: absolute; left: 15%; right: 15%; top: 22.5%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 4.4cqw; font-weight: 800; line-height: 1.2; letter-spacing: .12em; text-transform: uppercase; color: var(--deck-ink);
}
.dq-front-q {
  position: absolute; left: 15%; right: 15%; top: 29%; bottom: 29%; margin: 0; display: flex; align-items: center; justify-content: center;
  font-size: 8.4cqw; font-weight: 800; line-height: 1.28; letter-spacing: -.01em; color: var(--h-ink); overflow-wrap: anywhere;
}
.dq-front-q.is-mid { font-size: 7.6cqw; }
.dq-front-q.is-long { font-size: 6.9cqw; }
.dq-front-kind { position: absolute; left: 15%; right: 15%; bottom: 23%; font-size: 4.6cqw; font-weight: 700; line-height: 1.2; color: var(--deck-ink); }
/* not turned yet: it breathes, and the pair shows how */
.dq-turn { display: flex; align-items: center; gap: 8px; pointer-events: none; }
.dq-turn-art { display: block; height: 70px; width: auto; flex: none; }
.dq-turn-pill { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 14px; border-radius: 999px; background: #17181C; color: #fff; font-size: 13px; font-weight: 700; white-space: nowrap; box-shadow: 0 8px 16px -10px rgba(23, 24, 28, .8); }
.dq-turn-pill .icon { display: inline-flex; }
/* theirs is in, yours isn't: their sealed letter, waiting for you */
.dq-lock-art { display: block; height: 96px; width: auto; }
@media (prefers-reduced-motion: no-preference) {
  .dq-lock-art, .dq-post-art { animation: hw-bob 3.6s ease-in-out infinite; }
}
@media (prefers-reduced-motion: no-preference) {
  .dq-flip:not(.is-turned):not(:disabled) .dq-flip-in { animation: dq-breathe 2.8s ease-in-out infinite; }
}
@keyframes dq-breathe { 0%, 100% { transform: rotateY(0) translateY(0); } 50% { transform: rotateY(-9deg) translateY(-4px); } }
@media (prefers-reduced-motion: reduce) { .dq-flip-in { transition: none; } }
.dq-lock { display: flex; align-items: flex-start; gap: 8px; margin: 0; max-width: 36ch; font-size: 13.5px; font-weight: 600; line-height: 1.4; color: var(--h-muted); }
.dq-lock-ic, .dq-lock-ic .icon { display: inline-flex; flex: none; }
.dq-lock-ic { margin-top: 1px; color: var(--h-deep); }

/* the note: the Higgsfield note card to write on (its margin and tape drawn, its lines ruled here
   at the words' own 30px), the pair writing on its top edge; sealing hands it to the mailbox */
.dq-note {
  position: relative; display: flex; flex-direction: column; gap: 12px; padding: 16px;
  border-radius: var(--h-r); background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.dq-note-head { display: flex; align-items: center; min-height: 26px; padding-right: 96px; }
.dq-paper { position: relative; width: 100%; max-width: 520px; margin: 0 auto; aspect-ratio: 644 / 495; border-radius: 18px; }
/* the pair writing, peeking over the note's top right corner (48px up: the head row, the gap and
   most of the card's padding, so it never pokes out of the card) */
.dq-note-art { position: absolute; z-index: 1; right: -4px; top: -48px; display: block; height: 76px; width: auto; pointer-events: none; }
.dq-paper-art { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: fill; pointer-events: none; filter: drop-shadow(0 12px 14px rgba(110, 70, 40, .16)); }
.dq-paper:focus-within { outline: 3px solid rgba(255, 143, 177, .5); outline-offset: 3px; }
.dq-note > :not(.dq-posting) { transition: opacity .35s ease, transform .45s cubic-bezier(.5, 0, .7, .4); }
.dq-note.is-sealing > :not(.dq-posting) { opacity: 0; transform: translateY(24px) scale(.86); }
.dq-posting {
  position: absolute; left: 50%; top: 50%; display: block; width: 150px; height: auto; translate: -50% -50%;
  opacity: 0; scale: .5; pointer-events: none; transition: opacity .25s ease .15s, scale .55s cubic-bezier(.3, 1.5, .5, 1) .15s;
}
.dq-note.is-sealing .dq-posting { opacity: 1; scale: 1; }
@media (prefers-reduced-motion: reduce) { .dq-note > *, .dq-posting { transition: none; } }
.dq-seal {
  flex: 1 1 100%; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 50px; padding: 0 22px;
  border: 0; border-radius: 999px; background: #FF4F8B; color: #fff; font: 800 15px/1 var(--font-body); cursor: pointer;
  box-shadow: 0 4px 0 #D23A72; transition: transform .1s ease, box-shadow .1s ease;
}
.dq-seal .icon { display: inline-flex; }
.dq-seal .icon svg { fill: currentColor; }
.dq-seal:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 1px 0 #D23A72; }
.dq-seal:disabled { background: var(--h-grey); color: #9A9DA6; box-shadow: none; cursor: not-allowed; }
.dq-seal.is-sending { background: #FF4F8B; color: #fff; opacity: .75; cursor: progress; }
.dq-seal:focus-visible { outline: 3px solid #FFC2D8; outline-offset: 2px; }

/* the post: your envelope and theirs, the button, the two letters */
.dq-post {
  display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 18px 14px;
  border-radius: var(--h-r); background: var(--h-card); border: 1px solid var(--h-line); box-shadow: var(--h-shadow);
}
.dq-slots { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; width: 100%; }
.dq-slots:has(> .dq-slot[hidden]) { grid-template-columns: minmax(0, 1fr); }
.dq-slot { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 8px; min-width: 0; min-height: 120px; }
.dq-slot-l { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; font-size: 12.5px; font-weight: 700; line-height: 1.3; color: var(--h-muted); text-align: left; }
.dq-slot-face { display: block; flex: none; width: 22px; height: 22px; border-radius: 50%; object-fit: contain; background: #fff; box-shadow: 0 0 0 1.5px #fff, 0 2px 4px rgba(60, 30, 60, .18); }
.dq-slot-wait { display: block; width: 100px; height: auto; }
/* both in: the mailbox awake over the two envelopes */
.dq-post-head { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.dq-post-art { display: block; width: 92px; height: auto; }
.dq-post-t { margin: 0; font-size: 15px; font-weight: 800; letter-spacing: -.01em; color: var(--h-ink); }
.dq-open {
  display: inline-flex; align-items: center; gap: 8px; min-height: 50px; padding: 0 24px; border: 0; border-radius: 999px;
  background: #FF4F8B; color: #fff; font: 800 15px/1 var(--font-body); cursor: pointer; box-shadow: 0 4px 0 #D23A72;
}
.dq-open .icon { display: inline-flex; }
.dq-open:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 1px 0 #D23A72; }
.dq-open:focus-visible { outline: 3px solid #FFC2D8; outline-offset: 2px; }
@media (prefers-reduced-motion: no-preference) { .dq-open:not(:disabled) { animation: dq-pulse 1.6s ease-out infinite; } }
@keyframes dq-pulse { 0% { box-shadow: 0 4px 0 #D23A72, 0 0 0 0 rgba(255, 79, 139, .45); } 100% { box-shadow: 0 4px 0 #D23A72, 0 0 0 14px rgba(255, 79, 139, 0); } }
/* an envelope, drawn: the body, the note inside, the pocket, the flap, the wax seal */
.dq-env { --env: #FFD3E3; --env-deep: #F7A9C6; --env-dark: #E7799F; position: relative; width: 132px; aspect-ratio: 3 / 2; perspective: 600px; }
.dq-env.is-blue { --env: #D3E3FF; --env-deep: #A9C6F7; --env-dark: #6F9BE0; }
.dq-env-body { position: absolute; inset: 0; border-radius: 10px; background: var(--env); box-shadow: 0 10px 18px -12px rgba(60, 30, 60, .5); }
.dq-env-note { position: absolute; left: 10%; right: 10%; top: 12%; bottom: 8%; border-radius: 6px; background: #FFFDF6; box-shadow: 0 2px 6px rgba(60, 30, 60, .15); transition: transform .6s cubic-bezier(.3, 1.3, .5, 1) .45s; }
.dq-env-note-t { display: none; }
.dq-env-pocket { position: absolute; inset: 0; border-radius: 10px; background: linear-gradient(160deg, var(--env) 0%, var(--env-deep) 100%); clip-path: polygon(0 18%, 50% 62%, 100% 18%, 100% 100%, 0 100%); }
.dq-env-flap { position: absolute; left: 0; right: 0; top: 0; height: 66%; transform-origin: 50% 0; background: linear-gradient(180deg, var(--env-deep), var(--env)); clip-path: polygon(0 0, 100% 0, 50% 100%); transition: transform .5s cubic-bezier(.5, 0, .3, 1); }
.dq-env-seal {
  position: absolute; left: 50%; top: 54%; width: 46px; height: 46px; translate: -50% -50%; display: block;
  transition: transform .3s ease, opacity .3s ease;
}
.dq-env-seal img { display: block; width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 3px 4px rgba(80, 30, 50, .28)); }
/* the seal is pink wax: on a blue envelope it turns blue */
.dq-env.is-blue .dq-env-seal img { filter: hue-rotate(-125deg) saturate(.95) drop-shadow(0 3px 4px rgba(30, 50, 90, .28)); }
/* opening: the seal pops, the flap folds up behind, the note slides out */
.dq-env.is-opening .dq-env-seal, .dq-env.is-open .dq-env-seal { transform: scale(0); opacity: 0; }
.dq-env.is-opening .dq-env-flap, .dq-env.is-open .dq-env-flap { transform: rotateX(180deg); z-index: -1; }
.dq-env.is-opening .dq-env-note, .dq-env.is-open .dq-env-note { transform: translateY(-46%); }
@media (prefers-reduced-motion: no-preference) {
  .dq-env.is-new { animation: dq-drop .5s cubic-bezier(.3, 1.3, .5, 1) both; }
  .dq-env.is-new .dq-env-flap { animation: dq-flap .55s cubic-bezier(.3, 1.3, .5, 1) .2s both; }
  .dq-env.is-new .dq-env-seal { animation: dq-stamp .5s cubic-bezier(.3, 1.6, .5, 1) .55s both; }
}
@keyframes dq-drop { 0% { transform: translateY(-30px) scale(.8); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes dq-flap { from { transform: rotateX(180deg); } to { transform: rotateX(0); } }
@keyframes dq-stamp { 0% { transform: scale(1.8); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
/* opened: the two letters, taped, in your colours */
.dq-letters { display: flex; flex-direction: column; align-items: center; gap: 10px; width: 100%; }
.dq-both-art { display: block; width: 168px; height: auto; }
.dq-letters-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; width: 100%; }
.dq-letter {
  position: relative; display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 16px 14px; border-radius: 16px;
  background-color: #FFFDF6; background-image: repeating-linear-gradient(180deg, transparent 0, transparent 25px, #F7E3EA 25px, #F7E3EA 26px);
  background-position: 0 40px; box-shadow: 0 10px 20px -14px rgba(90, 30, 60, .45), inset 0 0 0 1px #F3E6D8;
}
.dq-letter::before { content: ""; position: absolute; top: -6px; left: 50%; width: 46px; height: 14px; translate: -50% 0; rotate: -3deg; border-radius: 3px; background: rgba(255, 170, 200, .75); }
.dq-letter.is-blue::before { background: rgba(160, 195, 255, .8); }
.dq-letter-who { font-size: 12.5px; font-weight: 800; color: var(--h-deep); }
.dq-letter.is-blue .dq-letter-who { color: #2F64B8; }
.dq-letter-t { margin: 0; font-size: 15px; font-weight: 600; line-height: 26px; color: var(--h-ink); overflow-wrap: anywhere; }
@media (prefers-reduced-motion: no-preference) {
  .dq-post[data-state="opened"] .dq-letter { animation: dq-letter .6s cubic-bezier(.3, 1.3, .5, 1) both; }
  .dq-post[data-state="opened"] .dq-letter + .dq-letter { animation-delay: .12s; }
}
@keyframes dq-letter { from { transform: translateY(18px) rotate(-2deg); opacity: 0; } to { transform: none; opacity: 1; } }
.dq-tomorrow { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; font-weight: 700; color: var(--h-muted); }
.dq-tomorrow .icon { display: inline-flex; }
@media (max-width: 360px) {
  .dq-flip { width: 206px; }
  .dq-env { width: 116px; }
  .dq-turn-art { height: 58px; }
  .dq-note-art { height: 66px; }
  .dq-letters-row { grid-template-columns: minmax(0, 1fr); }
}

/* an upright iPad (and up): one roomier column, the button beside its count */
@container dqpage (min-width: 600px) {
  .dq-page > * { --dq-col: 680px; --dq-pad: 24px; }
  .dq { gap: 16px; padding: 8px var(--dq-pad) 12px; }
  .dq-today, .dq-side { gap: 16px; }
  .dq-flip { width: 256px; }
  .dq-front-q { font-size: 21px; }
  .dq-front-q.is-long { font-size: 18px; }
  .dq-turn-art { height: 80px; }
  .dq-note-art { height: 86px; }
  .dq-note-head { padding-right: 110px; }
  .dq-env { width: 148px; }
  .dq-label { font-size: 16px; }
  .dq-meta { flex: 1 1 auto; }
  .dq-solo { flex-direction: row; align-items: center; gap: 16px; padding: 16px 16px 16px 18px; }
  .dq-solo-t { flex: 1 1 auto; }
  .dq-connect { flex: none; }
}
/* a computer: today on the left, the numbers and the past days beside it */
@container dqpage (min-width: 900px) {
  .dq-page > * { --dq-col: 1100px; }
  .dq {
    display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(290px, 1fr);
    align-items: start; gap: 28px; padding: 10px var(--dq-pad) 20px;
  }
  /* today is ONE centred stack in its column: the card, the note and the post on one axis */
  .dq-today > * { width: 100%; max-width: 560px; margin-inline: auto; box-sizing: border-box; }
  .dq-past-h { margin-top: 8px; }
}
/* the page's own ground on a wide screen (Home's soft pink and blue wash); the toast centred
   on the page, not under the sidebar */
@media (min-width: 768px) {
  .sp-page.dq-page {
    background:
      radial-gradient(110% 50vh at 0% 0%, rgba(255, 214, 229, .34), transparent 62%),
      radial-gradient(110% 44vh at 100% 100%, rgba(207, 223, 255, .38), transparent 62%),
      var(--paper, #F8F9FB);
  }
  .dq-toast { left: calc(50% + var(--tabbar-side, 0px) / 2); max-width: calc(100vw - var(--tabbar-side, 0px) - 40px); }
}
@media (max-width: 360px) {
  .hdq { padding-right: 100px; }
  .hdq-deck { right: 4px; width: 94px; height: 96px; }
}

/* ==== Home on an iPad and on the web (768px and up, 2026-10-19) ==============================
   From 768px the app's navigation is a left sidebar (client/core/tabbar.js) and the page sits
   beside it. Home is one centred column to 1023px (an iPad held upright) and a two-column
   dashboard from 1024px: the greeting with the bell and the picture on one row (the wordmark
   is the sidebar's), the three numbers across, today's question as one wide banner, Our week
   beside the moments card (2026-10-20: the week first, as on a phone), Jump in as one wide
   row, the memories' slideshow beside their two tiles, the letters two by two. Every rule is scoped to the width, so the phone layout above
   is untouched. The ground is Profile's: white with the sidebar's soft pink and blue wash (the
   bar is no longer sticky here, so nothing sits over it). The pages pushed over Home start at
   the sidebar's edge and keep to a readable column; the sheets sit centred. */
@media (min-width: 768px) {
  #app:has(.home-dash) {
    background:
      radial-gradient(120% 46vh at 0% 0%, rgba(255, 214, 229, .38), transparent 62%),
      radial-gradient(120% 40vh at 100% 100%, rgba(207, 223, 255, .42), transparent 62%),
      #fff;
  }
  .home-dash {
    max-width: 760px; padding: 0 28px 56px;
    display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 20px; align-content: start;
  }
  .home-dash > * { grid-column: 1 / -1; min-width: 0; }
  .home-dash > .home-bar {
    grid-row: 1; grid-column: -2 / -1; justify-self: end; align-self: start;
    position: static; padding: calc(24px + env(safe-area-inset-top, 0px)) 0 0; background: none;
  }
  .home-dash > .home-bar .home-brand { display: none; }
  .home-dash > .home-bar .home-ava, .home-dash > .home-bar .home-bell { width: 42px; height: 42px; }
  .home-dash > .home-hey { grid-row: 1; grid-column: 1 / 2; padding: calc(26px + env(safe-area-inset-top, 0px)) 0 4px; }
  .home-dash .home-hey h1 { font-size: 34px; }
  .home-dash .home-hey p { font-size: 15px; }

  .home-dash .hd-stats { padding: 18px 0 0; gap: 14px; }
  /* the tiles size themselves off their row (@container hdstats, with the tiles above) */

  .home-dash .home-meet, .home-dash .hmc, .home-dash .hw-week, .home-dash .hdq { margin: 16px 0 0; }
  .home-dash > .avw, .home-dash > .tw-card { margin-left: 0; margin-right: 0; } /* the avatar and the town, when they're on */

  .home-dash .home-label { padding: 32px 0 12px; }
  .home-dash .home-label-row { padding: 32px 0 12px; }
  .home-dash .hd-quick { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px 10px; padding: 0 0 6px; }
  .home-dash > .ih { margin: 16px 0 0; }
  .home-dash .home-keep .ss { margin: 0 0 12px; }
  .home-dash .home-keep-grid { gap: 14px; padding: 0 0 8px; }
  .home-dash .hl-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; padding: 0; }
  .home-dash .hl-list > .hl-empty { grid-column: 1 / -1; }

  /* a page pushed over Home: beside the sidebar, its column centred */
  .sp-page { left: var(--tabbar-side, 0px); }
  .sp-page:not(.mp-page) {
    padding-left: max(0px, calc((100vw - var(--tabbar-side, 0px) - 820px) / 2));
    padding-right: max(0px, calc((100vw - var(--tabbar-side, 0px) - 820px) / 2));
  }
  .sp-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px 18px; }
  .sp-opts { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* a sheet: the same sheet, centred and no wider than a phone's */
  .sheet { left: 0; right: 0; max-width: 560px; margin: 0 auto; border-radius: 22px 22px 0 0; }
}

@media (min-width: 1024px) {
  .home-dash { max-width: 1080px; padding: 0 24px 64px; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 22px; }
  .home-dash .home-hey h1 { font-size: 38px; }

  /* today's question: one wide banner across both columns, the words bigger, the pair bigger on
     the right */
  .home-dash .hdq { margin-top: 18px; padding: 22px 260px 22px 26px; min-height: 196px; }
  .home-dash .hdq-copy { min-height: 152px; gap: 12px; }
  .home-dash .hdq-text { font-size: 23px; max-width: 46ch; -webkit-line-clamp: 3; }
  .home-dash .hdq-who-t { font-size: 14px; }
  .home-dash .hdq-deck { right: 40px; bottom: 14px; width: 210px; height: 166px; }

  /* Our week beside the moments card (the week first, as on a phone — 2026-10-20), the two as
     tall as each other (were the moments card ever hidden, Our week takes the whole row) */
  .home-dash > .home-moments, .home-dash > .hw-week { grid-column: auto; align-self: stretch; margin-top: 18px; }
  .home-dash > .home-moments { display: flex; flex-direction: column; }
  .home-dash > .home-moments > .hmc { flex: 1 1 auto; margin: 0; }
  .home-dash .hmc-miss { margin-top: auto; }
  .home-dash:has(> .home-moments[hidden]) > .hw-week { grid-column: 1 / -1; }
  .home-dash .hw-week { justify-content: space-between; }
  .home-dash .hw-bars { height: 120px; }
  .home-dash .hd-quick .hd-card { min-height: 124px; }
  .home-dash .hd-quick .hd-card img { width: 64px; height: 64px; }

  /* the memories: the slideshow beside the Strips | Scrapbook pair */
  .home-dash .home-keep { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); column-gap: 22px; align-items: stretch; }
  .home-dash .home-keep > .home-label { grid-column: 1 / -1; }
  .home-dash .home-keep .ss { grid-column: 1; display: flex; flex-direction: column; margin: 0; }
  .home-dash .home-keep .ss > .ss-empty { flex: 1 1 auto; }
  .home-dash .home-keep-grid { grid-column: 2; padding: 0 0 4px; }
  .home-dash .home-keep-grid .hk-card { flex-direction: column; justify-content: center; align-items: center; text-align: center; gap: 8px; }
  .home-dash .home-keep-grid .hk-card img { width: 88px; height: 88px; }
  .home-dash .home-keep-grid .hk-copy { flex: none; align-items: center; }
  .home-dash .home-keep-grid .hk-go { display: none; }
}
@media (min-width: 1280px) {
  .home-dash { padding: 0 32px 64px; column-gap: 24px; }
}
/* a big screen: centred and WIDE, the sides only a thin margin (the product owner, 2026-10-19:
   "not a narrow column — centred, a little padding left and right"); Jump in fills its row */
@media (min-width: 1440px) {
  .home-dash { max-width: 1440px; padding: 0 clamp(32px, 3vw, 48px) 72px; column-gap: 28px; }
  .home-dash .hd-quick { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px 12px; }
  .home-dash .home-keep { column-gap: 28px; }
}


/* A box in a page over Home has the focus and the keyboard is up (app/keyboardFit.js, 2026-10-23):
   the page is fitted to what's visible, and nothing before it shows around the keyboard — iOS
   pans the page under a fixed layer, and on iOS 26 its floating bar let Home's cards through. */
html.kb-up, html.kb-up body { background: #fff; }
html.kb-up body > :has(~ .kb-layer) { visibility: hidden; }
