/* ==================================================================
   VELOUR — Home
   Design system: CLAY MORPHISM on a burgundy accent.

   · Every raised surface is inflated, not outlined: a wide soft outer
     drop + a bright inset top-light + an inset bottom shadow. That
     third part is what makes a surface read as a pillow rather than
     a flat card with a shadow under it. No 1px borders anywhere.
   · Light mode is a soft grey canvas so white clay can rise off it.
     Dark mode is TRUE BLACK — burgundy is the accent, never the
     ground.
   · Background carries a drifting dot grid and two slow burgundy
     blooms, so the page is never a dead flat field.
   · Burgundy appears only on: primary fills, the active nav pill,
     accent text, and focus rings.
   ================================================================== */

/* ── 1. Reset ───────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
* { margin: 0; padding: 0; }

/* The browser hides [hidden] with a UA rule, and ANY author `display` beats a
   UA rule no matter how specific it is. Every class here that sets a display
   — .people, .iconbtn, .strip, .ptab, #panePlanner/#paneStreaks — therefore
   silently cancelled `el.hidden = true`, which is how the feed kept showing
   the followed-people row on the Discover tab, the back arrow appeared on
   screens that set no back target, and the calendar showed both its panes at
   once. One rule fixes all of them; !important is required to outrank the
   class rules that caused it. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
img, svg, video { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; background: none; border: none; }
button { cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
:focus { outline: none; }
:focus-visible { outline: 2.5px solid var(--focus); outline-offset: 3px; border-radius: 6px; }
::selection { background: var(--accent-soft); }

/* ── 2. Tokens — light (clay canvas) ────────────────────────────── */
:root {
  /* Burgundy scale */
  --wine-950:#26060F; --wine-900:#3B0C1B; --wine-800:#53132A;
  --wine-700:#6B1A36; --wine-600:#8A2244; --wine-500:#A32C53;
  --wine-400:#B3355C; --wine-300:#D2708A; --wine-200:#E8A6B6;
  --wine-100:#F6DCE3; --wine-50:#FDF4F7;

  /* Canvas is deliberately NOT white — clay needs a ground to rise off */
  --bg:           #ECE7E8;
  --bg-2:         #E5DFE1;
  --surface:      #FFFFFF;
  --surface-2:    #F7F3F4;
  --surface-3:    #E8E2E4;
  --surface-sunk: #E9E4E5;

  --ink:   #14090C;
  --ink-2: #3A2E31;
  --ink-3: #665A5C;

  --line:  rgba(38,6,15,.09);
  --dot:   rgba(38,6,15,.055);
  --amb-1: rgba(138,34,68,.055);
  --amb-2: rgba(138,34,68,.032);

  --glass:      rgba(255,255,255,.82);
  --glass-line: rgba(255,255,255,.7);

  --accent:       var(--wine-600);
  --accent-hover: var(--wine-700);
  --accent-ink:   #FFFFFF;
  --accent-soft:  rgba(138,34,68,.12);
  --accent-edge:  rgba(138,34,68,.26);
  --accent-text:  var(--wine-700);
  --focus:        var(--wine-600);

  --danger: #A82121; --danger-soft: rgba(168,33,33,.11);
  --ok:     #1F6B45;

  /* CLAY — outer drop + inset top-light + inset bottom shadow */
  --sh-1: 0 4px 11px rgba(38,6,15,.07),
          inset 0 2px 3px rgba(255,255,255,.95),
          inset 0 -4px 9px rgba(38,6,15,.05);
  --sh-2: 0 10px 26px rgba(38,6,15,.10), 0 3px 8px rgba(38,6,15,.05),
          inset 0 3px 4px rgba(255,255,255,1),
          inset 0 -7px 13px rgba(38,6,15,.06);
  --sh-3: 0 22px 48px rgba(38,6,15,.14), 0 8px 16px rgba(38,6,15,.07),
          inset 0 3px 4px rgba(255,255,255,1),
          inset 0 -8px 15px rgba(38,6,15,.06);
  --sh-4: 0 36px 78px rgba(38,6,15,.20), 0 13px 30px rgba(38,6,15,.10),
          inset 0 3px 4px rgba(255,255,255,1),
          inset 0 -9px 17px rgba(38,6,15,.06);
  --sunk: inset 0 3px 9px rgba(38,6,15,.13), inset 0 1px 3px rgba(38,6,15,.08);
  --glow:    0 10px 24px rgba(138,34,68,.26), inset 0 2px 3px rgba(255,255,255,.34);
  --glow-sm: 0 4px 12px rgba(138,34,68,.24), inset 0 2px 3px rgba(255,255,255,.28);

  /* Clay is generous and chunky */
  --r-xs:12px; --r-sm:16px; --r:22px; --r-lg:28px; --r-xl:34px; --r-2xl:44px; --r-full:999px;

  --gut: 18px;
  --rail-w: 0px;
  --topbar-h: 60px;
  --nav-h: 48px;
  /* True space the floating dock occupies: 15px bottom offset + 50px FAB.
     Anything anchored above the dock measures from this, not --nav-h. */
  --dock-h: 66px;

  /* Gentle clay overshoot */
  --e-out:    cubic-bezier(.34,1.2,.4,1);
  --e-spring: cubic-bezier(.34,1.56,.5,1);
  --e-lin:    cubic-bezier(.4,0,.2,1);
  --t-fast: .18s; --t: .28s; --t-slow: .46s;

  --f-display: "Bodoni Moda", "Didot", "Times New Roman", serif;
  --f-ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* ── 3. Tokens — dark (TRUE BLACK) ──────────────────────────────── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:           #000000;
    --bg-2:         #050304;
    --surface:      #0C0A0B;
    --surface-2:    #131011;
    --surface-3:    #1B1719;
    --surface-sunk: #000000;

    --ink:   #FFFFFF;
    --ink-2: #CBC2C4;
    --ink-3: #998D90;

    --line:  rgba(255,255,255,.07);
    --dot:   rgba(255,255,255,.05);
    --amb-1: rgba(179,53,92,.07);
    --amb-2: rgba(179,53,92,.04);

    --glass:      rgba(10,8,9,.82);
    --glass-line: rgba(255,255,255,.07);

    --accent:       var(--wine-400);
    --accent-hover: #C2456B;
    --accent-ink:   #FFFFFF;
    --accent-soft:  rgba(179,53,92,.18);
    --accent-edge:  rgba(210,112,138,.32);
    --accent-text:  var(--wine-300);
    --focus:        var(--wine-300);

    --danger: #F0556D; --danger-soft: rgba(240,85,109,.16);
    --ok:     #2ECF82;

    /* On pure black an outer drop barely registers, so the puff comes
       almost entirely from the insets. */
    --sh-1: 0 2px 7px rgba(0,0,0,.6),
            inset 0 2px 2px rgba(255,255,255,.06),
            inset 0 -3px 6px rgba(0,0,0,.28);
    --sh-2: 0 8px 22px rgba(0,0,0,.65),
            inset 0 2px 2px rgba(255,255,255,.075),
            inset 0 -4px 9px rgba(0,0,0,.30);
    --sh-3: 0 18px 40px rgba(0,0,0,.72),
            inset 0 2px 2px rgba(255,255,255,.085),
            inset 0 -5px 11px rgba(0,0,0,.32);
    --sh-4: 0 30px 64px rgba(0,0,0,.8),
            inset 0 2px 2px rgba(255,255,255,.09),
            inset 0 -6px 13px rgba(0,0,0,.32);
    --sunk: inset 0 3px 9px rgba(0,0,0,.75), inset 0 1px 3px rgba(0,0,0,.55);
    --glow:    0 10px 26px rgba(179,53,92,.34), inset 0 2px 2px rgba(255,255,255,.12);
    --glow-sm: 0 4px 14px rgba(179,53,92,.3),  inset 0 2px 2px rgba(255,255,255,.1);
  }
}
:root[data-theme="dark"] {
  --bg:           #000000;
  --bg-2:         #050304;
  --surface:      #0C0A0B;
  --surface-2:    #131011;
  --surface-3:    #1B1719;
  --surface-sunk: #000000;

  --ink:   #FFFFFF;
  --ink-2: #CBC2C4;
  --ink-3: #998D90;

  --line:  rgba(255,255,255,.07);
  --dot:   rgba(255,255,255,.05);
  --amb-1: rgba(179,53,92,.07);
  --amb-2: rgba(179,53,92,.04);

  --glass:      rgba(10,8,9,.82);
  --glass-line: rgba(255,255,255,.07);

  --accent:       var(--wine-400);
  --accent-hover: #C2456B;
  --accent-ink:   #FFFFFF;
  --accent-soft:  rgba(179,53,92,.18);
  --accent-edge:  rgba(210,112,138,.32);
  --accent-text:  var(--wine-300);
  --focus:        var(--wine-300);

  --danger: #F0556D; --danger-soft: rgba(240,85,109,.16);
  --ok:     #2ECF82;

  --sh-1: 0 2px 7px rgba(0,0,0,.6),
          inset 0 2px 2px rgba(255,255,255,.06),
          inset 0 -3px 6px rgba(0,0,0,.28);
  --sh-2: 0 8px 22px rgba(0,0,0,.65),
          inset 0 2px 2px rgba(255,255,255,.075),
          inset 0 -4px 9px rgba(0,0,0,.30);
  --sh-3: 0 18px 40px rgba(0,0,0,.72),
          inset 0 2px 2px rgba(255,255,255,.085),
          inset 0 -5px 11px rgba(0,0,0,.32);
  --sh-4: 0 30px 64px rgba(0,0,0,.8),
          inset 0 2px 2px rgba(255,255,255,.09),
          inset 0 -6px 13px rgba(0,0,0,.32);
  --sunk: inset 0 3px 9px rgba(0,0,0,.75), inset 0 1px 3px rgba(0,0,0,.55);
  --glow:    0 10px 26px rgba(179,53,92,.34), inset 0 2px 2px rgba(255,255,255,.12);
  --glow-sm: 0 4px 14px rgba(179,53,92,.3),  inset 0 2px 2px rgba(255,255,255,.1);
}

/* ── 4. Base + living background ────────────────────────────────── */
/* The ground colour lives on <html> so body can stay transparent and the
   two fixed texture layers below can paint over it. */
html { background-color: var(--bg); }

body {
  font-family: var(--f-ui);
  font-size: 15px;
  line-height: 1.5;
  letter-spacing: -.005em;
  color: var(--ink);
  background: transparent;
  overscroll-behavior-y: none;
  min-height: 100svh;
  overflow-x: hidden;
  transition: color var(--t) var(--e-lin);
}
body.is-locked { overflow: hidden; }

/* Layer 1 — the dot grid, drifting one full tile over 90s so it loops
   seamlessly and reads as motion you feel rather than notice. */
html::before {
  content: ""; position: fixed; inset: -30px; z-index: -1; pointer-events: none;
  background-image: radial-gradient(var(--dot) 1.1px, transparent 1.2px);
  background-size: 26px 26px;
  animation: drift 90s linear infinite;
}
/* Layer 2 — two slow burgundy blooms that breathe. */
html::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    radial-gradient(58% 42% at 12% -8%, var(--amb-1), transparent 62%),
    radial-gradient(50% 38% at 94% 3%,  var(--amb-2), transparent 58%);
  animation: bloom 26s ease-in-out infinite alternate;
}
@keyframes drift { from { transform: translate3d(0,0,0); } to { transform: translate3d(26px,26px,0); } }
@keyframes bloom { from { opacity: .7; transform: scale(1); } to { opacity: 1; transform: scale(1.07); } }

.wordmark {
  font-family: var(--f-display);
  font-weight: 500;
  letter-spacing: .30em; text-indent: .30em;
  text-transform: uppercase; line-height: 1;
}
.display { font-family: var(--f-display); font-weight: 500; letter-spacing: -.01em; line-height: 1.08; }
.mono-k { font-size: 10px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3); }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.topbar, .navdock, .rail, .chip, .btn, .stat-k, .sec-h { user-select: none; -webkit-user-select: none; }

/* ── 5. Primitives ──────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  height: 48px; padding: 0 22px;
  border-radius: var(--r-full);
  font-size: 14.5px; font-weight: 700; letter-spacing: -.01em;
  background: var(--surface); color: var(--ink);
  box-shadow: var(--sh-2);
  transition: background-color var(--t-fast) var(--e-lin),
              color var(--t-fast) var(--e-lin),
              box-shadow var(--t) var(--e-out),
              transform var(--t) var(--e-out),
              opacity var(--t-fast) var(--e-lin);
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); box-shadow: var(--sh-3); }
/* Clay press: it squashes down into the surface rather than just scaling */
.btn:active { transform: translateY(1px) scale(.978); box-shadow: var(--sh-1); }
.btn[disabled], .btn.is-busy { opacity: .55; pointer-events: none; }
.btn--primary { background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow); }
.btn--primary:hover { background: var(--accent-hover); box-shadow: var(--glow), var(--sh-2); }
.btn--ghost { background: var(--surface-2); color: var(--ink); box-shadow: var(--sh-1); }
.btn--ghost:hover { background: var(--surface); box-shadow: var(--sh-2); }
.btn--quiet { background: transparent; color: var(--ink-2); box-shadow: none; }
.btn--quiet:hover { background: var(--surface-2); color: var(--ink); box-shadow: var(--sh-1); transform: none; }
.btn--quiet:active { transform: scale(.97); box-shadow: var(--sunk); }
.btn--sm { height: 40px; padding: 0 17px; font-size: 13px; }
.btn--block { width: 100%; }

.iconbtn {
  position: relative;
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-full);
  background: var(--surface); color: var(--ink-2);
  font-size: 16px;
  box-shadow: var(--sh-1);
  transition: color var(--t-fast) var(--e-lin),
              box-shadow var(--t) var(--e-out),
              transform var(--t) var(--e-out);
}
.iconbtn:hover { color: var(--ink); box-shadow: var(--sh-2); transform: translateY(-1px); }
.iconbtn:active { transform: scale(.88); box-shadow: var(--sunk); }

.badge {
  position: absolute; top: -2px; right: -2px;
  min-width: 18px; height: 18px; padding: 0 5px;
  display: none; place-items: center;
  border-radius: var(--r-full);
  background: var(--accent); color: var(--accent-ink);
  font-size: 10px; font-weight: 800; line-height: 1;
  box-shadow: var(--glow-sm);
}
.badge.on { display: grid; animation: pop .4s var(--e-spring); }

.chip {
  display: inline-flex; align-items: center; gap: 7px;
  height: 38px; padding: 0 17px;
  border-radius: var(--r-full);
  background: var(--surface); color: var(--ink-2);
  font-size: 13px; font-weight: 700;
  box-shadow: var(--sh-1);
  /* A pill must never wrap. Inside the flex .filters row these would
     otherwise shrink on a narrow phone and break "Most loved" across
     two lines; flex:none makes the row scroll sideways instead. */
  flex: none; white-space: nowrap;
  transition: color var(--t-fast) var(--e-lin),
              background-color var(--t-fast) var(--e-lin),
              box-shadow var(--t) var(--e-out),
              transform var(--t) var(--e-out);
}
.chip:hover { color: var(--ink); transform: translateY(-2px); box-shadow: var(--sh-2); }
.chip:active { transform: translateY(1px) scale(.96); box-shadow: var(--sh-1); }
.chip[aria-selected="true"] { background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow-sm); }

.avatar {
  border-radius: var(--r-full);
  background: var(--surface-2);
  object-fit: cover; flex: none;
  box-shadow: var(--sh-1);
}
.avatar--fallback {
  display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent-text);
  font-weight: 800; text-transform: uppercase;
  font-size: .8em; letter-spacing: .02em;
}

/* Media frame — a failed load degrades to a branded tile, never a
   broken-image glyph. */
.frame { position: relative; overflow: hidden; background: var(--surface-3); }
/* An image that fills a clay tile hides the inset light that makes it look
   inflated, so the tile paints that edge back over the picture. */
.frame--clay::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 2px 3px rgba(255,255,255,.5), inset 0 -6px 12px rgba(38,6,15,.16);
}
:root[data-theme="dark"] .frame--clay::after,
:root:not([data-theme="light"]) .frame--clay::after {
  box-shadow: inset 0 2px 2px rgba(255,255,255,.1), inset 0 -6px 12px rgba(0,0,0,.4);
}
.frame img {
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0;
  transition: opacity var(--t-slow) var(--e-lin), transform var(--t-slow) var(--e-out);
}
.frame img.ready { opacity: 1; }
.frame.failed::after {
  content: "\f03e";
  font-family: "Font Awesome 6 Free"; font-weight: 900;
  position: absolute; inset: 0;
  display: grid; place-items: center;
  color: var(--ink-3); font-size: 20px;
  background: var(--surface-3);
}

/* Skeletons breathe rather than sweep — a sweeping highlight needs a
   gradient, and this system keeps gradients out of the furniture. */
.sk { background: var(--surface-3); border-radius: var(--r-sm); animation: breathe 1.6s var(--e-lin) infinite; }

@keyframes breathe { 0%,100% { opacity: 1 } 50% { opacity: .45 } }
@keyframes pop     { from { transform: scale(.2); opacity: 0 } to { transform: scale(1); opacity: 1 } }
/* Same motion as `pop`, but for elements that are centred with translateX(-50%).
   A keyframe's `transform` replaces the rule's, so the offset has to be
   carried through every step or the element jumps sideways as it animates. */
@keyframes pop-x   { from { transform: translateX(-50%) scale(.2); opacity: 0 } to { transform: translateX(-50%) scale(1); opacity: 1 } }
@keyframes rise    { from { opacity: 0; transform: translateY(16px) } to { opacity: 1; transform: none } }
@keyframes fade    { from { opacity: 0 } to { opacity: 1 } }
@keyframes spin    { to { transform: rotate(360deg) } }
@keyframes heartbeat {
  0% { transform: scale(1) } 38% { transform: scale(1.45) }
  62% { transform: scale(.88) } 100% { transform: scale(1) }
}
/* A soft burgundy ring that expands and fades — used on the streak flame */
@keyframes halo { 0% { box-shadow: 0 0 0 0 var(--accent-soft) } 70%,100% { box-shadow: 0 0 0 14px transparent } }

.spinner {
  width: 16px; height: 16px; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; opacity: .85;
  animation: spin .7s linear infinite;
}

/* Staged entrance */
.stage { animation: rise .6s var(--e-out) backwards; animation-delay: calc(var(--i, 0) * 70ms); }

/* ── 6. Shell ───────────────────────────────────────────────────── */
.shell { margin-left: var(--rail-w); min-height: 100svh; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 40;
  height: calc(var(--topbar-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) var(--gut) 0;
  display: flex; align-items: center; gap: 8px;
  background: transparent;
  transition: background-color var(--t) var(--e-lin), box-shadow var(--t) var(--e-out);
}
/* Only once content slides under it does it become frosted chrome */
.topbar.stuck {
  background: var(--glass);
  -webkit-backdrop-filter: saturate(180%) blur(22px);
  backdrop-filter: saturate(180%) blur(22px);
  box-shadow: 0 6px 22px rgba(38,6,15,.07);
}
:root[data-theme="dark"] .topbar.stuck { box-shadow: 0 6px 22px rgba(0,0,0,.6); }

.topbar__mark { font-size: 17px; margin-right: auto; color: var(--ink); display: flex; align-items: baseline; }
.topbar__mark .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--accent); margin-left: -.22em; align-self: center; }

.avatar-btn {
  width: 42px; height: 42px; flex: none;
  border-radius: var(--r-full); overflow: hidden;
  background: var(--surface);
  box-shadow: var(--sh-1);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.avatar-btn:hover { transform: translateY(-1px); box-shadow: var(--sh-2); }
.avatar-btn:active { transform: scale(.9); box-shadow: var(--sunk); }
.avatar-btn img { width: 100%; height: 100%; object-fit: cover; }

.main {
  flex: 1; width: 100%;
  padding: 8px var(--gut) calc(var(--dock-h) + env(safe-area-inset-bottom) + 34px);
  display: flex; flex-direction: column; gap: 32px;
}

/* ── 7. Greeting ────────────────────────────────────────────────── */
.greet { padding-top: 8px; }
.greet__date { font-size: 11px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3); }
.greet__line { font-size: 32px; margin-top: 10px; color: var(--ink); }
.greet__line em { font-style: italic; color: var(--accent-text); }
.greet__sub { margin-top: 9px; font-size: 14px; color: var(--ink-2); max-width: 46ch; }

/* ── 8. Hero — today's look ─────────────────────────────────────── */
.hero__card {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--sh-3);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.hero__card:hover { transform: translateY(-3px); box-shadow: var(--sh-4); }
.hero__media { aspect-ratio: 4 / 5; position: relative; flex: none; }
.hero__media img { transition: transform 1.2s var(--e-out), opacity var(--t-slow) var(--e-lin); }
.hero__card:hover .hero__media img.ready { transform: scale(1.04); }

.hero__plate { padding: 20px; background: var(--surface); }
.hero__slot {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px; border-radius: var(--r-full);
  white-space: nowrap;
  background: var(--accent-soft); color: var(--accent-text);
  font-size: 10px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
}
.hero__title { font-size: 23px; margin-top: 13px; color: var(--ink); }
.hero__note {
  margin-top: 7px; font-size: 13.5px; color: var(--ink-2);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.hero__acts { display: flex; gap: 10px; margin-top: 18px; }
.hero__acts .btn { flex: 1; }

.hero__empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; padding: 46px 26px; text-align: center;
  background: var(--surface);
}
.hero__empty .glyph {
  width: 72px; height: 72px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--surface-sunk); color: var(--accent-text);
  font-size: 25px; box-shadow: var(--sunk);
}
.hero__empty h3 { font-family: var(--f-display); font-weight: 500; font-size: 24px; }
.hero__empty p { font-size: 14px; color: var(--ink-2); max-width: 30ch; }

/* ── 9. Stat strip ──────────────────────────────────────────────── */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.stat {
  padding: 18px 10px; text-align: center;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--sh-2);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.stat:hover { transform: translateY(-2px); box-shadow: var(--sh-3); }
.stat-v {
  font-family: var(--f-display); font-weight: 500;
  font-size: 30px; line-height: 1; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.stat-v .unit { font-family: var(--f-ui); font-size: 11.5px; font-weight: 600; color: var(--ink-3); margin-left: 4px; }
.stat-k {
  display: block; margin-top: 9px;
  font-size: 9.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stat--live { position: relative; }
.stat--live .stat-v { color: var(--accent-text); }
/* A live streak gets a slow burgundy pulse. It rides on a pseudo-element
   rather than the tile, because animating the tile's own box-shadow would
   replace the clay puff for the length of the animation. */
.stat--live.alive::after {
  content: ""; position: absolute; inset: 0;
  border-radius: inherit; pointer-events: none;
  animation: halo 2.8s var(--e-lin) infinite;
}

/* ── 10. Quick actions ──────────────────────────────────────────── */
.quick { display: grid; grid-template-columns: repeat(2, 1fr); gap: 11px; }
.qa {
  display: flex; align-items: center; gap: 13px;
  padding: 15px;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--sh-2);
  text-align: left;
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.qa:hover { transform: translateY(-3px); box-shadow: var(--sh-3); }
.qa:active { transform: translateY(1px) scale(.98); box-shadow: var(--sh-1); }
.qa__ico {
  width: 44px; height: 44px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  background: var(--surface-sunk); color: var(--accent-text);
  font-size: 16px; box-shadow: var(--sunk);
  transition: background-color var(--t-fast) var(--e-lin), color var(--t-fast) var(--e-lin);
}
.qa:hover .qa__ico { background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow-sm); }
.qa__txt { min-width: 0; }
/* These were inline spans stacking on one line — "WardrobeAdd a piece". */
.qa__t { display: block; font-size: 14.5px; font-weight: 700; line-height: 1.25; }
.qa__s { display: block; font-size: 11.5px; color: var(--ink-3); margin-top: 3px; line-height: 1.3; }

/* ── 11. Section headers ────────────────────────────────────────── */
.sec-h { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.sec-h h2 { font-family: var(--f-display); font-weight: 500; font-size: 22px; letter-spacing: -.01em; }
.sec-h .sub { font-size: 12.5px; color: var(--ink-3); margin-top: 4px; }
.sec-h .more {
  font-size: 12.5px; font-weight: 700; color: var(--accent-text);
  display: inline-flex; align-items: center; gap: 7px;
  flex: none; white-space: nowrap;
  padding: 8px 14px; border-radius: var(--r-full);
  background: var(--surface); box-shadow: var(--sh-1);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.sec-h .more:hover { transform: translateY(-2px); box-shadow: var(--sh-2); }
.sec-h .more:active { transform: translateY(1px) scale(.96); box-shadow: var(--sunk); }

/* ── 12. Wardrobe rail ──────────────────────────────────────────── */
.rail-scroll {
  display: flex; gap: 12px;
  overflow-x: auto; scroll-snap-type: x proximity;
  margin: 0 calc(var(--gut) * -1); padding: 6px var(--gut) 10px;
  scrollbar-width: none;
}
.rail-scroll::-webkit-scrollbar { display: none; }
.piece { width: 110px; flex: none; scroll-snap-align: start; transition: transform var(--t) var(--e-out); }
.piece:hover { transform: translateY(-3px); }
.piece:active { transform: translateY(1px) scale(.96); }
.piece .frame { aspect-ratio: 3 / 4; border-radius: var(--r-lg); box-shadow: var(--sh-2); }
.piece__cat {
  display: block; margin-top: 9px; font-size: 11.5px; font-weight: 600; color: var(--ink-2);
  text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-transform: capitalize;
}
.piece--add .frame {
  display: grid; place-items: center;
  background: var(--surface-sunk); color: var(--ink-3);
  box-shadow: var(--sunk);
  transition: color var(--t-fast) var(--e-lin);
}
.piece--add:hover .frame { color: var(--accent-text); }
.piece--add .frame i { font-size: 20px; }

/* ── 13. Feed ───────────────────────────────────────────────────── */
.filters {
  display: flex; gap: 9px; overflow-x: auto;
  margin: 0 calc(var(--gut) * -1) 16px; padding: 6px var(--gut) 10px;
  scrollbar-width: none;
}
.filters::-webkit-scrollbar { display: none; }

.grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 13px; }

.look {
  position: relative;
  border-radius: var(--r-lg); overflow: hidden;
  background: var(--surface);
  box-shadow: var(--sh-2);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
  animation: fade .45s var(--e-lin) backwards;
  animation-delay: calc(var(--i, 0) * 45ms);
}
.look:hover { transform: translateY(-4px); box-shadow: var(--sh-3); }
.look__media { aspect-ratio: 3 / 4; cursor: pointer; width: 100%; }
.look__media img { transition: transform .8s var(--e-out), opacity var(--t-slow) var(--e-lin); }
.look:hover .look__media img.ready { transform: scale(1.06); }
.look__foot { display: flex; align-items: center; gap: 9px; padding: 11px 12px; }
.look__who { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1; }
.look__who .avatar { width: 24px; height: 24px; }
.look__name { font-size: 12px; font-weight: 600; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.like {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 700; color: var(--ink-3);
  padding: 5px 9px; border-radius: var(--r-full);
  font-variant-numeric: tabular-nums;
  transition: color var(--t-fast) var(--e-lin), background-color var(--t-fast) var(--e-lin);
}
.like:hover { color: var(--accent-text); background: var(--accent-soft); }
.like[aria-pressed="true"] { color: var(--accent); }
.like.beat i { animation: heartbeat .55s var(--e-spring); }
.look__views {
  position: absolute; top: 11px; right: 11px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 11px; border-radius: var(--r-full);
  background: var(--glass);
  -webkit-backdrop-filter: blur(14px) saturate(160%); backdrop-filter: blur(14px) saturate(160%);
  font-size: 11px; font-weight: 700; color: var(--ink-2);
  font-variant-numeric: tabular-nums;
  box-shadow: var(--sh-1);
  opacity: 0; transform: translateY(-6px);
  transition: opacity var(--t) var(--e-out), transform var(--t) var(--e-out);
}
.look:hover .look__views, .look:focus-within .look__views { opacity: 1; transform: none; }

.sentinel { height: 1px; }
.feed-end { text-align: center; padding: 26px 0 4px; color: var(--ink-3); font-size: 12.5px; }
.feed-end .rule { width: 36px; height: 3px; border-radius: 3px; background: var(--surface-3); box-shadow: var(--sunk); margin: 0 auto 14px; }

.blank {
  padding: 44px 26px; text-align: center;
  border-radius: var(--r-lg);
  background: var(--surface-sunk); box-shadow: var(--sunk);
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.blank i { font-size: 24px; color: var(--ink-3); }
.blank h4 { font-family: var(--f-display); font-weight: 500; font-size: 19px; }
.blank p { font-size: 13.5px; color: var(--ink-2); max-width: 34ch; }

/* ── 14. Floating nav dock (mobile) ─────────────────────────────────
   A slim frosted capsule with the round Create button riding beside it
   on the same row — lifted off the bottom edge, not pinned to it. */
.navdock {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(15px + env(safe-area-inset-bottom));
  z-index: 60;
  display: flex; align-items: center; gap: 9px;
  /* Must animate translate(-50%, …): the shared `rise` keyframe ends at
     transform:none, which wiped the -50% and parked the dock off to the
     right until the animation finished. */
  animation: dockIn .6s var(--e-out) .2s backwards;
}
@keyframes dockIn {
  from { opacity: 0; transform: translate(-50%, 16px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
.navbar {
  display: flex; align-items: center; gap: 2px; padding: 5px;
  background: var(--glass);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  border-radius: var(--r-full);
  box-shadow: var(--sh-3);
}
@supports not (backdrop-filter: blur(1px)) { .navbar { background: var(--surface); } }
.navbar__item {
  position: relative;
  width: 42px; height: 42px;
  border-radius: var(--r-full);
  color: var(--ink-3); font-size: 17px;
  display: grid; place-items: center;
  transition: color var(--t-fast) var(--e-lin),
              background-color var(--t-fast) var(--e-lin),
              transform var(--t) var(--e-out);
}
.navbar__item:hover { color: var(--ink); }
.navbar__item:active { transform: scale(.84); }
.navbar__item[aria-current="page"] { background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow-sm); }
.navbar__item .badge { top: 0; right: 0; }

.fab {
  flex: 0 0 auto;
  width: 50px; height: 50px;
  border-radius: var(--r-full);
  background: var(--accent); color: var(--accent-ink);
  font-size: 20px;
  display: grid; place-items: center;
  box-shadow: var(--glow), var(--sh-2);
  transition: background-color var(--t-fast) var(--e-lin),
              transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.fab:hover { background: var(--accent-hover); transform: translateY(-2px); box-shadow: var(--glow), var(--sh-3); }
.fab:active { transform: scale(.9) rotate(90deg); }

/* ── 15. Side rail (desktop) ────────────────────────────────────── */
.rail {
  position: fixed; inset: 0 auto 0 0; z-index: 50;
  width: var(--rail-w);
  display: none; flex-direction: column;
  padding: 24px 13px calc(20px + env(safe-area-inset-bottom));
  background: var(--glass);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  backdrop-filter: blur(24px) saturate(170%);
  border-right: 1px solid var(--glass-line);
}
.rail__mark { font-size: 15px; color: var(--ink); padding: 6px 12px 26px; display: flex; align-items: baseline; }
.rail__nav { display: flex; flex-direction: column; gap: 7px; }
.rnav {
  position: relative;
  display: flex; align-items: center; gap: 14px;
  height: 48px; padding: 0 15px;
  border-radius: var(--r-full);
  background: var(--surface); color: var(--ink-2);
  font-size: 14px; font-weight: 700;
  box-shadow: var(--sh-1);
  transition: color var(--t-fast) var(--e-lin),
              background-color var(--t-fast) var(--e-lin),
              box-shadow var(--t) var(--e-out),
              transform var(--t) var(--e-out);
  white-space: nowrap;
}
.rnav i { width: 20px; text-align: center; font-size: 16px; flex: none; }
.rnav:hover { color: var(--ink); transform: translateY(-2px); box-shadow: var(--sh-2); }
.rnav:active { transform: translateY(1px) scale(.97); box-shadow: var(--sunk); }
.rnav[aria-current="page"] { background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow-sm); }
.rnav[aria-current="page"]:hover { background: var(--accent-hover); color: var(--accent-ink); }
.rail__cta { margin-top: 16px; }
.rail__spacer { flex: 1; }
.rail__user {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px; border-radius: var(--r-full);
  background: var(--surface); box-shadow: var(--sh-1);
  width: 100%; text-align: left;
  transition: box-shadow var(--t) var(--e-out), transform var(--t) var(--e-out);
}
.rail__user:hover { transform: translateY(-2px); box-shadow: var(--sh-2); }
.rail__user:active { transform: translateY(1px) scale(.98); box-shadow: var(--sunk); }
.rail__user .avatar { width: 34px; height: 34px; }
.rail__user .meta { min-width: 0; flex: 1; }
/* nested inline spans — must stack, or the name and plan run together */
.rail__user .nm { display: block; font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail__user .pl { display: block; font-size: 11px; color: var(--ink-3); text-transform: capitalize; margin-top: 1px; }

/* ── 16. Right column (wide desktop) ────────────────────────────── */
.aside { display: none; }
.panel { padding: 20px; border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--sh-2); }
.panel + .panel { margin-top: 16px; }
.panel__h { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.panel__h h3 { font-family: var(--f-display); font-weight: 500; font-size: 17px; }

.streakbar { display: flex; gap: 6px; margin-top: 14px; }
.streakbar span {
  flex: 1; height: 34px; border-radius: var(--r-xs);
  background: var(--surface-sunk); box-shadow: var(--sunk);
  display: grid; place-items: center;
  font-size: 9.5px; font-weight: 800; color: var(--ink-3);
  text-transform: uppercase;
  transition: background-color var(--t) var(--e-lin), color var(--t) var(--e-lin);
}
.streakbar span.on { background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow-sm); }
.streakbar span.today { color: var(--accent-text); }
.streakbar span.on.today { color: var(--accent-ink); }

.plus-card { background: var(--surface); box-shadow: var(--sh-3); }
.plus-card h3 { color: var(--accent-text); }
.plus-card p { font-size: 13px; color: var(--ink-2); margin: 10px 0 16px; }

/* ── 17. Overlays ───────────────────────────────────────────────── */
.scrim {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(20,4,9,.5);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
  opacity: 0; pointer-events: none;
  transition: opacity var(--t) var(--e-lin);
}
.scrim.open { opacity: 1; pointer-events: auto; }

.sheet {
  position: fixed; z-index: 91;
  left: 0; right: 0; bottom: 0;
  max-height: 88svh;
  display: flex; flex-direction: column;
  background: var(--bg-2);
  border-radius: var(--r-2xl) var(--r-2xl) 0 0;
  box-shadow: var(--sh-4);
  transform: translateY(100%);
  transition: transform var(--t-slow) var(--e-out);
  padding-bottom: env(safe-area-inset-bottom);
}
.sheet.open { transform: none; }
.sheet__grab { width: 42px; height: 5px; border-radius: 3px; background: var(--surface-3); box-shadow: var(--sunk); margin: 12px auto 0; flex: none; }
.sheet__h { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px 14px; flex: none; }
.sheet__h h2 { font-family: var(--f-display); font-weight: 500; font-size: 20px; }
.sheet__body { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 4px 14px 20px; }

.nrow {
  display: flex; gap: 13px; align-items: flex-start;
  padding: 14px 15px; margin-bottom: 9px;
  border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-1);
  width: 100%; text-align: left;
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.nrow:hover { transform: translateY(-2px); box-shadow: var(--sh-2); }
.nrow:active { transform: translateY(1px) scale(.99); box-shadow: var(--sunk); }
.nrow .avatar { width: 38px; height: 38px; }
.nrow__t { font-size: 13.5px; font-weight: 700; }
.nrow__b { font-size: 13px; color: var(--ink-2); margin-top: 3px; }
.nrow__d { font-size: 11px; color: var(--ink-3); margin-top: 6px; }
.nrow.unread { background: var(--accent-soft); }
.nrow.unread .nrow__t::after {
  content: ""; display: inline-block; vertical-align: middle;
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent); margin-left: 8px;
}

.menu {
  position: fixed; z-index: 91;
  min-width: 226px; padding: 8px;
  background: var(--surface); border-radius: var(--r-lg);
  box-shadow: var(--sh-4);
  opacity: 0; transform: translateY(-8px) scale(.96);
  pointer-events: none; transform-origin: top right;
  transition: opacity var(--t-fast) var(--e-lin), transform var(--t) var(--e-out);
}
.menu.open { opacity: 1; transform: none; pointer-events: auto; }
.mitem {
  display: flex; align-items: center; gap: 12px;
  width: 100%; height: 44px; padding: 0 13px;
  border-radius: var(--r-sm);
  font-size: 13.5px; font-weight: 600; color: var(--ink);
  text-align: left;
  transition: background-color var(--t-fast) var(--e-lin), transform var(--t-fast) var(--e-out);
}
.mitem i { width: 18px; text-align: center; color: var(--ink-3); font-size: 13px; }
.mitem:hover { background: var(--surface-2); }
.mitem:active { transform: scale(.97); }
.mitem--danger { color: var(--danger); }
.mitem--danger i { color: var(--danger); }
.msep { height: 1px; background: var(--line); margin: 6px 10px; }
.mhead { padding: 10px 13px 9px; }
.mhead .nm { font-size: 14px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mhead .em { font-size: 12px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.modal {
  position: fixed; z-index: 91;
  left: 50%; top: 50%;
  width: min(560px, calc(100vw - 28px));
  max-height: min(86svh, 780px);
  display: flex; flex-direction: column;
  background: var(--bg-2);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-4);
  overflow: hidden;
  opacity: 0; pointer-events: none;
  transform: translate(-50%, -47%) scale(.95);
  transition: opacity var(--t) var(--e-lin), transform var(--t) var(--e-out);
}
.modal.open { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); }
.modal__body { overflow-y: auto; overscroll-behavior: contain; }
.modal__x {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  background: var(--glass);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}

/* width:100% is load-bearing. With only `aspect-ratio` and `max-height`, the
   box's automatic width is derived from the ratio once max-height binds — so it
   shrank to 46svh x 3/4 and sat left-aligned in the card, leaving a blank strip
   down the right. Pinning the width keeps the hero full-bleed and lets the
   image's own object-fit:cover do the cropping. */
.detail__media { width: 100%; aspect-ratio: 3 / 4; max-height: 46svh; background: var(--surface-3); }
.detail__body { padding: 20px; }
.detail__who { display: flex; align-items: center; gap: 11px; }
.detail__who .avatar { width: 44px; height: 44px; }
.detail__who .nm { font-size: 15px; font-weight: 700; }
.detail__who .mt { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.detail__prompt { margin-top: 16px; font-size: 14px; color: var(--ink-2); line-height: 1.55; }
.detail__meta {
  display: flex; gap: 10px; margin-top: 16px;
}
.detail__meta div {
  flex: 1; padding: 12px; border-radius: var(--r-sm); text-align: center;
  background: var(--surface-sunk); box-shadow: var(--sunk);
  font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
}
.detail__meta b {
  display: block; margin-bottom: 4px;
  font-family: var(--f-display); font-weight: 500; font-size: 21px;
  letter-spacing: 0; text-transform: none; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.detail__acts { display: flex; gap: 10px; margin-top: 18px; }
.detail__acts .btn { flex: 1; }
.detail__items { display: flex; gap: 9px; margin-top: 18px; overflow-x: auto; scrollbar-width: none; padding: 4px 0; }
.detail__items::-webkit-scrollbar { display: none; }
.detail__items .frame { width: 64px; height: 80px; flex: none; border-radius: var(--r-sm); box-shadow: var(--sh-1); }

.relog { padding: 30px 24px 26px; text-align: center; }
.relog .glyph {
  width: 62px; height: 62px; margin: 0 auto 16px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--surface-sunk); color: var(--accent-text);
  box-shadow: var(--sunk); font-size: 21px;
}
.relog h2 { font-family: var(--f-display); font-weight: 500; font-size: 25px; }
.relog p { font-size: 13.5px; color: var(--ink-2); margin-top: 9px; }
.relog form { margin-top: 22px; display: flex; flex-direction: column; gap: 11px; text-align: left; }

.field { position: relative; }
.field input {
  width: 100%; height: 54px;
  padding: 0 16px 0 46px;
  border-radius: var(--r-sm);
  background: var(--surface-sunk); color: var(--ink);
  font-size: 15px;
  box-shadow: var(--sunk);
  transition: box-shadow var(--t) var(--e-out);
}
.field input::placeholder { color: var(--ink-3); }
.field input:focus { box-shadow: var(--sunk), 0 0 0 2.5px var(--accent); }
.field > i {
  position: absolute; left: 17px; top: 50%; transform: translateY(-50%);
  color: var(--ink-3); font-size: 14px; pointer-events: none;
  transition: color var(--t-fast) var(--e-lin);
}
.field input:focus ~ i { color: var(--accent-text); }
.formerr {
  display: none; align-items: center; gap: 9px;
  font-size: 13px; color: var(--danger);
  background: var(--danger-soft);
  border-radius: var(--r-sm); padding: 12px 14px;
}
.formerr.on { display: flex; animation: rise .3s var(--e-out); }

.toasts {
  position: fixed; z-index: 95;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--dock-h) + env(safe-area-inset-bottom) + 14px);
  width: min(420px, calc(100vw - 28px));
  display: flex; flex-direction: column; gap: 9px;
  pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 17px;
  border-radius: var(--r-full);
  background: var(--surface);
  box-shadow: var(--sh-3);
  font-size: 13.5px; font-weight: 600; color: var(--ink);
  animation: rise .38s var(--e-spring);
  pointer-events: auto;
  /* pan-y leaves vertical scrolling to the browser while the horizontal axis
     stays ours, so a toast can be swiped away without the page fighting it.
     Dragging text selection instead of the toast would break the gesture. */
  touch-action: pan-y;
  user-select: none; -webkit-user-select: none;
  cursor: grab;
}
.toast:active { cursor: grabbing; }
.toast.out { animation: fade .24s var(--e-lin) reverse forwards; }
.toast i { font-size: 15px; flex: none; color: var(--accent-text); }
.toast span { min-width: 0; }
.toast.err i { color: var(--danger); }
.toast.ok i { color: var(--ok); }

/* ── 18. Breakpoints ────────────────────────────────────────────────
   Each width gets a layout of its own — never a scaled copy. */

/* Large phone */
@media (min-width: 430px) {
  :root { --gut: 22px; }
  .stat-k { font-size: 10px; letter-spacing: .13em; }
  .greet__line { font-size: 36px; }
  .piece { width: 118px; }
}

/* Tablet portrait — two-up hero, the dock stays for thumb reach */
@media (min-width: 640px) {
  :root { --gut: 30px; --topbar-h: 66px; }
  body { font-size: 15.5px; }
  .main { gap: 40px; max-width: 780px; margin: 0 auto; }
  .greet__line { font-size: 42px; }
  .hero__card { flex-direction: row; align-items: stretch; }
  .hero__media { flex: 1 1 50%; aspect-ratio: auto; min-height: 400px; }
  .hero__plate { flex: 1 1 50%; padding: 30px 28px; display: flex; flex-direction: column; justify-content: center; }
  .hero__slot { align-self: flex-start; }
  .hero__title { font-size: 28px; }
  .hero__note { -webkit-line-clamp: 4; font-size: 14px; }
  .hero__empty { min-height: 340px; }
  .quick { grid-template-columns: repeat(4, 1fr); }
  .qa { flex-direction: column; align-items: flex-start; gap: 15px; padding: 18px; }
  .grid { grid-template-columns: repeat(3, 1fr); gap: 16px; }
  .stats { gap: 14px; }
  .stat-v { font-size: 34px; }
}

/* Laptop — the dock gives way to an icon side rail */
@media (min-width: 1024px) {
  :root { --rail-w: 92px; --gut: 34px; --nav-h: 0px; --dock-h: 0px; }
  .navdock { display: none; }
  .rail { display: flex; }
  .rail__mark { justify-content: center; font-size: 0; padding: 4px 0 24px; }
  .rail__mark::before {
    content: "V"; font-family: var(--f-display); font-size: 28px; font-weight: 500;
    color: var(--ink); letter-spacing: 0;
  }
  .rail__mark .dot { display: none; }
  .rnav { justify-content: center; padding: 0; gap: 0; }
  .rnav span { display: none; }
  .rnav i { font-size: 18px; }
  .rail__cta .btn span { display: none; }
  .rail__cta .btn { padding: 0; height: 52px; }
  .rail__user { justify-content: center; padding: 7px; }
  .rail__user .meta, .rail__user .caret { display: none; }
  .main { max-width: 920px; padding-bottom: 70px; }
  .toasts { bottom: 26px; left: calc(50% + var(--rail-w) / 2); }
  .topbar__mark { font-size: 0; }
  .topbar__mark::after {
    content: "Home"; font-family: var(--f-ui); font-size: 15.5px; font-weight: 700;
    letter-spacing: -.01em; text-indent: 0; text-transform: none; color: var(--ink);
  }
  .topbar__mark .dot { display: none; }
}

/* Desktop — the rail opens up with labels */
@media (min-width: 1200px) {
  :root { --rail-w: 256px; --gut: 40px; }
  .rail { padding: 26px 16px calc(22px + env(safe-area-inset-bottom)); }
  .rail__mark { justify-content: flex-start; font-size: 15px; padding: 6px 14px 26px; }
  .rail__mark::before { content: none; }
  .rail__mark .dot { display: block; }
  .rnav { justify-content: flex-start; padding: 0 17px; gap: 14px; }
  .rnav span { display: block; }
  .rail__cta .btn { padding: 0 22px; }
  .rail__cta .btn span { display: block; }
  .rail__user { justify-content: flex-start; padding: 9px 11px; }
  .rail__user .meta, .rail__user .caret { display: block; }
  .main { max-width: 1020px; }
}

/* Wide desktop — a third column for today / streak / plus */
@media (min-width: 1440px) {
  .content-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 344px;
    gap: 40px;
    max-width: 1440px; margin: 0 auto;
    padding: 0 var(--gut);
  }
  .main { max-width: none; padding-left: 0; padding-right: 0; margin: 0; }
  .aside { display: block; padding: 14px 0 70px; }
  .aside__inner { position: sticky; top: calc(var(--topbar-h) + 24px); }
  .grid { grid-template-columns: repeat(3, 1fr); gap: 20px; }
}

@media (min-width: 1720px) {
  .content-grid { grid-template-columns: minmax(0, 1fr) 372px; max-width: 1660px; }
  .grid { grid-template-columns: repeat(4, 1fr); }
}

/* Detail modal becomes a two-panel spread */
@media (min-width: 900px) {
  .modal--detail { width: min(920px, calc(100vw - 60px)); }
  .modal--detail .modal__body { display: grid; grid-template-columns: 1fr 1fr; overflow: hidden; }
  .detail__media { max-height: none; height: 100%; aspect-ratio: auto; min-height: 500px; }
  .detail__body { padding: 30px; overflow-y: auto; }
  .sheet {
    left: auto; right: 20px; bottom: auto; top: calc(var(--topbar-h) + 14px);
    width: 412px; max-height: min(74svh, 660px);
    border-radius: var(--r-xl);
    transform: translateY(-12px) scale(.96); opacity: 0;
    transition: opacity var(--t) var(--e-lin), transform var(--t) var(--e-out);
  }
  .sheet.open { transform: none; opacity: 1; }
  .sheet__grab { display: none; }
}

/* Hover is a pointer-only affordance */
@media (hover: none) {
  .look:hover, .qa:hover, .stat:hover, .piece:hover, .chip:hover,
  .btn:hover, .rnav:hover, .nrow:hover, .hero__card:hover, .iconbtn:hover,
  .sec-h .more:hover, .rail__user:hover, .avatar-btn:hover, .fab:hover {
    transform: none;
  }
  .look:hover .look__media img.ready,
  .hero__card:hover .hero__media img.ready { transform: none; }
  .look__views { opacity: 1; transform: none; }
  .qa:hover .qa__ico { background: var(--surface-sunk); color: var(--accent-text); box-shadow: var(--sunk); }
}

/* ── 19. Reduced motion ─────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  html::before, html::after { animation: none !important; }
  .frame img { opacity: 1; }
}

@media print { .topbar, .navdock, .rail, .aside, .toasts { display: none !important; } }

/* ── Page chrome shared by every non-home screen ────────────────── */
.topbar__title {
  font-size: 16px; font-weight: 700; letter-spacing: -.01em;
  margin-right: auto; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.page-head { padding-top: 8px; }
.page-head h1 { font-family: var(--f-display); font-weight: 500; font-size: 32px; letter-spacing: -.01em; }
.page-head p { margin-top: 9px; font-size: 14px; color: var(--ink-2); max-width: 52ch; }
@media (min-width: 430px) { .page-head h1 { font-size: 36px; } }
@media (min-width: 640px) { .page-head h1 { font-size: 42px; } }

/* ── Shared form + section primitives ──────────────────────────────
   Promoted here because several screens use them; keeping one copy
   stops the pages drifting apart visually. */
.mhead2 { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.mhead2 h2 { font-family: var(--f-display); font-weight: 500; font-size: 22px; flex: 1; letter-spacing: -.01em; }

.opt__l {
  display: block; margin-bottom: 9px; padding-left: 4px;
  font-size: 10px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-3);
}
.ta {
  width: 100%; min-height: 84px; padding: 14px 16px;
  border-radius: var(--r-sm); resize: vertical; line-height: 1.5;
  background: var(--surface-sunk); color: var(--ink); font-size: 15px;
  box-shadow: var(--sunk); transition: box-shadow var(--t) var(--e-out);
}
.ta:focus { box-shadow: var(--sunk), 0 0 0 2.5px var(--accent); }
.ta::placeholder { color: var(--ink-3); }

.fset { margin-top: 16px; }
.fset label {
  display: block; margin-bottom: 8px; padding-left: 4px;
  font-size: 10px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-3);
}
.fset input, .fset select, .fset textarea {
  width: 100%; min-height: 50px; padding: 13px 16px;
  border-radius: var(--r-sm);
  background: var(--surface-sunk); color: var(--ink);
  font-size: 15px; box-shadow: var(--sunk);
  transition: box-shadow var(--t) var(--e-out);
}
.fset textarea { resize: vertical; min-height: 84px; line-height: 1.5; }
.fset select { appearance: none; -webkit-appearance: none; padding-right: 42px; cursor: pointer; }
.fset__sel { position: relative; }
.fset__sel::after {
  content: "\f078"; font-family: "Font Awesome 6 Free"; font-weight: 900;
  position: absolute; right: 18px; top: 50%; transform: translateY(-50%);
  font-size: 11px; color: var(--ink-3); pointer-events: none;
}
.fset input:focus, .fset select:focus, .fset textarea:focus { box-shadow: var(--sunk), 0 0 0 2.5px var(--accent); }
.fgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.det__facts { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.fact {
  padding: 7px 13px; border-radius: var(--r-full);
  background: var(--surface-sunk); box-shadow: var(--sunk);
  font-size: 11px; font-weight: 700; color: var(--ink-2);
  text-transform: capitalize; white-space: nowrap;
}


/* ── Shared page components ─────────────────────────────────────────
   Defined once: several screens use them and this is one stylesheet
   now, so duplicate definitions would silently fight each other. */
.card2 { border-radius: var(--r-xl); padding: 20px; background: var(--surface); box-shadow: var(--sh-2); margin-bottom: 18px; }
.card2 > h2 { font-family: var(--f-display); font-weight: 500; font-size: 19px; letter-spacing: -.01em; }
.card2 > p.hint { margin-top: 7px; font-size: 13px; color: var(--ink-3); }

.ftabs { display: flex; gap: 4px; margin-bottom: 16px; }
.ftab {
  position: relative; flex: 1; height: 46px;
  font-size: 14px; font-weight: 700; color: var(--ink-3); white-space: nowrap;
  transition: color var(--t-fast) var(--e-lin);
}
.ftab:hover { color: var(--ink); }
.ftab[aria-selected="true"] { color: var(--ink); }
.ftab[aria-selected="true"]::after {
  content: ""; position: absolute; left: 50%; bottom: 4px; transform: translateX(-50%);
  width: 28px; height: 3px; border-radius: 3px; background: var(--accent);
  /* NOT `pop` — that keyframe sets `transform: scale()`, which replaces the
     translateX(-50%) doing the centering, so the bar sat 14px right of its
     tab for the length of the animation and then snapped back. */
  animation: pop-x .3s var(--e-spring);
}

/* The router cross-fades #view; this is the fallback when the browser has
   no View Transition API. */
#view.swapping { opacity: 0; }
#view { transition: opacity .09s cubic-bezier(.4,0,.2,1); }

/* Chrome's default view transition is a ~250ms cross-fade, and the router
   awaits it before mounting the next screen — long enough that a tap on the
   dock reads as laggy. A screen swap should feel like a cut, not a dissolve. */
::view-transition-old(root),
::view-transition-new(root) { animation-duration: .11s; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}


/* ══════════ page: home ══════════ */
/* ── Home ───────────────────────────────────────────────────────────
   .main lays its DIRECT children out with a gap, but everything here
   sits inside .home-cols, so the sections were butting straight into
   each other. They carry their own rhythm instead. */
.home-cols > div, .home-cols > aside { display: flex; flex-direction: column; gap: 30px; }
.home-cols > aside { margin-top: 30px; }
.home-cols section { margin: 0; }
.sec-h { margin-bottom: 14px; }

.hello { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 4px; }
.hello__m { flex: 1; min-width: 0; }
.hello__t { font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.hello__s { margin-top: 4px; font-size: 13px; color: var(--ink-3); }

/* Hero — the one big invitation on the screen */
.hero {
  position: relative; overflow: hidden;
  border-radius: var(--r-xl);
  background: var(--surface); box-shadow: var(--sh-3);
  min-height: 300px; display: flex; align-items: flex-end;
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.hero:hover { transform: translateY(-3px); box-shadow: var(--sh-4); }
.hero__bg { position: absolute; inset: 0; }
.hero__bg img { transition: transform 1.2s var(--e-out), opacity var(--t-slow) var(--e-lin); }
.hero:hover .hero__bg img.ready { transform: scale(1.04); }
/* A solid ink plate, not a scrim wash — the copy sits on a defined block */
.hero__in {
  position: relative; z-index: 1; width: 100%;
  padding: 22px;
  background: linear-gradient(to top, rgba(8,3,5,.86) 0%, rgba(8,3,5,.72) 55%, rgba(8,3,5,0) 100%);
}
.hero__t { font-family: var(--f-display); font-weight: 500; font-size: 34px; line-height: 1.06; color: #fff; letter-spacing: -.015em; }
.hero__p { margin-top: 10px; font-size: 13.5px; color: rgba(255,255,255,.78); max-width: 30ch; line-height: 1.5; }
.hero__a { display: flex; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.hero__a .btn { flex: 1; min-width: 130px; }
.hero__a .btn--onwash {
  background: rgba(255,255,255,.14); color: #fff;
  box-shadow: inset 0 1px 1px rgba(255,255,255,.2), inset 0 -3px 7px rgba(0,0,0,.24);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.hero__a .btn--onwash:hover { background: rgba(255,255,255,.22); }

/* Three quick tiles */
.quick3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 11px; }
.q3 {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 18px 10px; text-align: center;
  border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-2);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.q3:hover { transform: translateY(-3px); box-shadow: var(--sh-3); }
.q3:active { transform: translateY(1px) scale(.97); box-shadow: var(--sh-1); }
.q3 i { font-size: 17px; color: var(--accent-text); }
.q3 b { font-size: 11.5px; font-weight: 700; line-height: 1.25; }

/* Today / tomorrow plan rows */
.plan {
  display: flex; align-items: center; gap: 14px;
  padding: 12px; border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-2);
}
.plan .frame { width: 64px; height: 80px; flex: none; border-radius: var(--r-sm); box-shadow: var(--sh-1); }
.plan__e {
  width: 64px; height: 80px; flex: none; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: var(--surface-sunk); box-shadow: var(--sunk); color: var(--ink-3); font-size: 16px;
}
.plan__m { flex: 1; min-width: 0; }
.plan__n { font-size: 14px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan__s { display: block; margin-top: 4px; font-size: 12px; color: var(--ink-3); }
.plan__a { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

/* Featured look */
.feat {
  position: relative; overflow: hidden;
  border-radius: var(--r-xl); box-shadow: var(--sh-3);
  display: block; width: 100%;
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.feat:hover { transform: translateY(-3px); box-shadow: var(--sh-4); }
.feat__m { aspect-ratio: 16 / 9; width: 100%; }
.feat__in {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 20px 18px 16px;
  background: linear-gradient(to top, rgba(8,3,5,.84), rgba(8,3,5,0));
  text-align: left;
}
.feat__t { font-family: var(--f-display); font-weight: 500; font-size: 21px; color: #fff; }
.feat__s { display: block; margin-top: 5px; font-size: 12px; color: rgba(255,255,255,.75); }
.feat__k {
  position: absolute; top: 12px; left: 12px;
  padding: 6px 12px; border-radius: var(--r-full);
  background: var(--glass); box-shadow: var(--sh-1);
  font-size: 9.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2);
}

/* Recent looks strip */
.strip { display: flex; gap: 11px; overflow-x: auto; margin: 0 calc(var(--gut) * -1); padding: 6px var(--gut) 10px; scrollbar-width: none; }
.strip::-webkit-scrollbar { display: none; }
.strip__i { width: 100px; flex: none; transition: transform var(--t) var(--e-out); }
.strip__i:active { transform: scale(.96); }
.strip__i .frame { aspect-ratio: 3/4; border-radius: var(--r-lg); box-shadow: var(--sh-2); }

/* Digital double row */
.dbl {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 15px; border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-2); width: 100%; text-align: left;
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.dbl:hover { transform: translateY(-2px); box-shadow: var(--sh-3); }
.dbl .avatar { width: 46px; height: 46px; }
.dbl__m { flex: 1; min-width: 0; }
.dbl__m b { display: block; font-size: 10px; font-weight: 800; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3); }
.dbl__m span { display: block; margin-top: 5px; font-size: 13.5px; font-weight: 600; }

@media (min-width: 640px) {
  .hero { min-height: 380px; }
  .hero__t { font-size: 44px; }
  .hero__in { padding: 30px; }
  .strip__i { width: 118px; }
}
@media (min-width: 1024px) {
  .home-cols { display: grid; grid-template-columns: minmax(0,1fr) 320px; gap: 26px; align-items: start; }
  .home-cols > aside { margin-top: 0; }
  .hero { min-height: 420px; }
}
@media (hover: none) {
  .hero:hover, .feat:hover, .q3:hover, .dbl:hover { transform: none; }
  .hero:hover .hero__bg img.ready { transform: none; }
}


/* ══════════ page: generate ══════════ */
/* ── Generate — one calm screen ─────────────────────────────────── */

/* Sections breathe; every one is a plain block, no nesting games. */
.gstep { margin-bottom: 0; }
/* Folded rows read as one list, so they sit tight to each other. */
.gstep--fold + .gstep--fold { margin-top: 10px; }
.gstep__h { display: flex; align-items: center; gap: 10px; margin-bottom: 13px; }
.gstep__t { font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.gstep__pick { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--accent-text); white-space: nowrap; }
.gstep__link { margin-left: auto; font-size: 12.5px; font-weight: 700; color: var(--accent-text); white-space: nowrap; }

/* Collapsible optional steps — closed until wanted */
.gstep--fold .gstep__h {
  cursor: pointer; user-select: none; -webkit-user-select: none;
  padding: 14px 16px; margin: 0;
  border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-1);
  transition: box-shadow var(--t) var(--e-out);
}
.gstep--fold .gstep__h:hover { box-shadow: var(--sh-2); }
.gstep__chev {
  width: 28px; height: 28px; flex: none; margin-left: 4px;
  display: grid; place-items: center; border-radius: var(--r-full);
  color: var(--ink-3); font-size: 10px;
  background: var(--surface-sunk); box-shadow: var(--sunk);
  transition: transform var(--t) var(--e-out), color var(--t-fast) var(--e-lin);
}
.gstep--fold.open .gstep__chev { transform: rotate(180deg); color: var(--accent-text); }
.gstep__body { display: none; padding-top: 16px; }
.gstep--fold.open .gstep__body { display: block; animation: unfold .3s var(--e-out); }
@keyframes unfold { from { opacity: 0; transform: translateY(-6px) } to { opacity: 1; transform: none } }

/* ── The look you're building ───────────────────────────────────── */
.tray {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; margin-bottom: 24px;
  border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-2);
}
.tray__strip { display: flex; gap: 7px; flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.tray__strip::-webkit-scrollbar { display: none; }
.tray__i { position: relative; width: 42px; height: 52px; flex: none; }
.tray__i .frame { width: 100%; height: 100%; border-radius: var(--r-xs); box-shadow: var(--sh-1); }
.tray__x {
  position: absolute; top: -5px; right: -5px;
  width: 19px; height: 19px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--surface); color: var(--ink-2); font-size: 8px; box-shadow: var(--sh-2);
}
.tray__x:hover { color: var(--danger); }
.tray__e { flex: 1; font-size: 13px; color: var(--ink-3); }
.tray__n { font-size: 12px; font-weight: 700; color: var(--ink-3); white-space: nowrap; flex: none; }

/* ── Wardrobe grid ──────────────────────────────────────────────── */
.pieces { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.pc {
  position: relative; border-radius: var(--r-lg); overflow: hidden;
  background: var(--surface); box-shadow: var(--sh-1);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.pc:active { transform: translateY(1px) scale(.96); }
.pc.on { box-shadow: var(--glow), var(--sh-1); }
/* The picture fills the tile and is clipped by the tile's own radius, so it
   curves with the box. Insetting it (contain + padding) left the source
   image's own square edge sitting inside a rounded card. */
.pc__media { aspect-ratio: 1; width: 100%; background: var(--surface-2); border-radius: var(--r-lg) var(--r-lg) 0 0; overflow: hidden; }
.pc__media img { object-fit: cover; }
.pc__n {
  position: absolute; top: 7px; right: 7px;
  min-width: 22px; height: 22px; padding: 0 6px; border-radius: var(--r-full);
  display: none; place-items: center;
  background: var(--accent); color: #fff; font-size: 11px; font-weight: 800; box-shadow: var(--glow-sm);
}
.pc.on .pc__n { display: grid; }
.pc__cat {
  padding: 0 8px 9px; font-size: 10.5px; font-weight: 600; color: var(--ink-3);
  text-align: center; text-transform: capitalize;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pc__edit {
  position: absolute; top: 7px; left: 7px;
  width: 24px; height: 24px; border-radius: var(--r-full);
  display: none; place-items: center;
  background: var(--glass); color: var(--ink-2); font-size: 10px; box-shadow: var(--sh-1);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.managing .pc__edit { display: grid; }
.managing .pc.on { box-shadow: var(--sh-1); }
.managing .pc__n { display: none; }

/* One surface only. Nesting a sunk box inside the raised card read as two
   mismatched rounded shapes stacked on each other. */
.pc--action { background: var(--surface-sunk); box-shadow: var(--sunk); }
.pc--action .pc__media {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  background: none; box-shadow: none; border-radius: var(--r-lg);
  color: var(--ink-3); font-size: 18px;
  transition: color var(--t-fast) var(--e-lin);
}
.pc--action:hover .pc__media { color: var(--accent-text); }
.pc--action .pc__lbl { font-size: 9px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }

/* ── Model tiles ────────────────────────────────────────────────── */
.tiles3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.tile {
  position: relative; border-radius: var(--r-lg); overflow: hidden;
  background: var(--surface); box-shadow: var(--sh-1);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.tile:active { transform: translateY(1px) scale(.97); }
.tile.on { box-shadow: var(--glow), var(--sh-1); }
.tile__pad {
  aspect-ratio: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 9px; padding: 12px; text-align: center;
}
.tile__pad i { font-size: 19px; color: var(--ink-3); }
.tile.on .tile__pad i { color: var(--accent-text); }
.tile__pad b { font-size: 11.5px; font-weight: 700; line-height: 1.25; }
.tile__media { aspect-ratio: 1; width: 100%; border-radius: var(--r-lg); overflow: hidden; }
/* A person photo reads best cropped from the top — faces stay in frame. */
.tile__media img { object-position: center 22%; }
.tile__cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 16px 6px 7px; font-size: 10.5px; font-weight: 700; color: #fff; text-align: center;
  background: rgba(10,4,7,.66);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tile__tick {
  position: absolute; top: 7px; right: 7px;
  width: 22px; height: 22px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--glass); color: transparent; font-size: 9px; box-shadow: var(--sh-1);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.tile.on .tile__tick { background: var(--accent); color: #fff; }
/* Shown on the digital-double tile once it is the chosen model, to say that
   tapping again replaces the photo rather than just re-selecting it. */
.tile__edit {
  position: absolute; top: 7px; left: 7px;
  width: 22px; height: 22px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--glass); color: var(--ink); font-size: 9px; box-shadow: var(--sh-1);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}

.styles { display: flex; gap: 8px; overflow-x: auto; padding: 4px 0 8px; scrollbar-width: none; }
.styles::-webkit-scrollbar { display: none; }

/* ── Sticky generate bar (always clears the dock) ───────────────── */
/* In the flow, directly under the choices it acts on. A fixed bar sat on
   top of Recent creations and there was no scroll position that cleared it. */
.gobar { width: 100%; }
.gobar .btn { width: 100%; height: 54px; }
.gobar__note { display: block; margin-top: 9px; text-align: center; font-size: 11.5px; color: var(--ink-3); }

/* ── Recent strip ───────────────────────────────────────────────── */
.recent { display: flex; gap: 11px; overflow-x: auto; margin: 0 calc(var(--gut) * -1); padding: 6px var(--gut) 10px; scrollbar-width: none; }
.recent::-webkit-scrollbar { display: none; }
.rc { position: relative; width: 108px; flex: none; transition: transform var(--t) var(--e-out); }
.rc:active { transform: scale(.96); }
.rc__m { aspect-ratio: 3/4; width: 100%; border-radius: var(--r-lg); box-shadow: var(--sh-2); }
.rc__m img { object-position: center 20%; }
.rc__f {
  position: absolute; top: 8px; left: 8px;
  padding: 4px 9px; border-radius: var(--r-full);
  background: var(--glass); box-shadow: var(--sh-1);
  font-size: 8.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-2); white-space: nowrap;
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.rc__f--live { background: var(--accent); color: #fff; }

/* Gallery sheet — the full history, paged */
.ggrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.ggrid .rc { width: auto; }

/* ── Full-screen look viewer ────────────────────────────────────── */
.viewer {
  /* inset:0 alone is not enough on mobile: a fixed element resolves it against
     the LARGE viewport (URL bar retracted), so the element runs taller than
     what is actually visible. .viewer__stage is flex:1 and absorbs the extra,
     pushing .viewer__bar and its action icons below the fold — the image then
     appears to cover the buttons. An explicit dynamic-viewport height wins over
     `bottom` and keeps the bar on screen. */
  position: fixed; inset: 0; height: 100vh; height: 100dvh; z-index: 92;
  overflow: hidden;            /* nothing paints outside the viewer box */
  background: var(--bg-2);
  /* Two explicit rows rather than flex: the look row is a `1fr` TRACK, which
     is a definite height, so `max-height: 100%` on the image below resolves
     against it. As a flex item the stage's height was indefinite, the
     percentage was ignored, and a tall look simply overflowed downward across
     the action bar. Sizing it correctly is the fix — the image now ends above
     the bar with the stage's bottom padding as real clearance. */
  display: grid; grid-template-rows: 1fr auto;
  opacity: 0; pointer-events: none;
  transition: opacity var(--t) var(--e-lin);
}
.viewer.open { opacity: 1; pointer-events: auto; }
.viewer__top {
  position: absolute; top: 0; left: 0; right: 0; z-index: 3;
  padding: calc(env(safe-area-inset-top) + 12px) 14px 12px;
  display: flex; align-items: center; gap: 8px;
}
.viewer__ttl { flex: 1; min-width: 0; font-size: 14px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.viewer__stage {
  min-height: 0; overflow: hidden; position: relative;
  display: grid; place-items: center;
  /* The bottom value is clearance above .viewer__bar. At 14px the look sat
     flush against the action icons; the image is centred in whatever is left,
     so this padding is the only thing separating them. */
  padding: calc(env(safe-area-inset-top) + 62px) 14px 26px;
}
/* contain — the whole look, never cropped */
.viewer__img {
  max-width: 100%; max-height: 100%;
  min-width: 0; min-height: 0;     /* a grid item's auto minimum is its intrinsic
                                      size, which overrides max-height and is how
                                      a tall look pushed past the track */
  object-fit: contain; border-radius: var(--r-lg); box-shadow: var(--sh-3);
}
.viewer__bar {
  /* .viewer__stage above is position:relative (the grade chips and the angle
     strip are absolutely placed inside it). Positioned elements paint in a
     later layer than in-flow blocks, so the stage — and any overflow of the
     look inside it — drew straight over these controls: the icons were
     covered and only their labels showed. Joining the positioned layer with a
     higher z-index puts the bar back on top, and its opaque --surface then
     hides anything that reaches it instead of being hidden by it. */
  position: relative; z-index: 4;
  display: flex; align-items: stretch;
  padding: 10px 8px calc(10px + env(safe-area-inset-bottom));
  background: var(--surface); box-shadow: 0 -6px 22px rgba(0,0,0,.14);
}
.vact {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 2px; border-radius: var(--r-sm);
  font-size: 9.5px; font-weight: 700; color: var(--ink-3);
  transition: color var(--t-fast) var(--e-lin), background-color var(--t-fast) var(--e-lin), transform var(--t) var(--e-out);
}
.vact i { font-size: 17px; }
.vact:hover { color: var(--ink); background: var(--surface-2); }
.vact:active { transform: scale(.9); }
.vact.on { color: var(--accent); }
.vact--danger:hover { color: var(--danger); }
.vact[disabled] { opacity: .4; pointer-events: none; }

/* Angle strip inside the viewer */
.angles { position: absolute; left: 0; right: 0; bottom: 12px; display: flex; gap: 8px; justify-content: center; padding: 0 14px; z-index: 2; }
/* The strip is absolutely placed INSIDE the stage, so it does not shorten the
   look on its own — without this the image runs under the angle thumbnails
   exactly as it used to run under the action bar. 58px thumb + 12px offset +
   the usual 26px of clearance. Browsers without :has() simply keep the
   original padding; the strip is a progressive extra either way. */
.viewer__stage:has(.angles) { padding-bottom: 96px; }
.angle {
  width: 46px; height: 58px; flex: none; border-radius: var(--r-xs); overflow: hidden;
  background: var(--surface); box-shadow: var(--sh-2);
  transition: transform var(--t) var(--e-out);
}
.angle.on { box-shadow: var(--glow), var(--sh-1); }
.angle:active { transform: scale(.92); }
.angle img { width: 100%; height: 100%; object-fit: cover; }

/* Working state inside the viewer */
.vwork { display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center; padding: 24px; }
.vwork__orb {
  width: 78px; height: 78px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--surface); color: var(--accent-text); box-shadow: var(--sh-2); font-size: 26px;
  animation: orb 2.4s var(--e-lin) infinite;
}
@keyframes orb {
  0%,100% { transform: scale(1); box-shadow: var(--sh-2), 0 0 0 0 var(--accent-soft); }
  50%     { transform: scale(1.06); box-shadow: var(--sh-2), 0 0 0 16px transparent; }
}
.vwork h3 { font-family: var(--f-display); font-weight: 500; font-size: 22px; }
.vwork p { font-size: 13.5px; color: var(--ink-2); max-width: 30ch; min-height: 2.8em; }
.vwork__bar { width: 160px; height: 5px; border-radius: 3px; background: var(--surface-3); box-shadow: var(--sunk); overflow: hidden; }
.vwork__bar i { display: block; height: 100%; width: 38%; border-radius: 3px; background: var(--accent); animation: sweep 1.5s var(--e-out) infinite; }
@keyframes sweep { from { transform: translateX(-115%) } to { transform: translateX(300%) } }
.vwork__t { font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.vgrade { display: flex; flex-wrap: wrap; gap: 7px; justify-content: center; margin-top: 12px; }
.grade {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px; border-radius: var(--r-full);
  background: var(--surface-sunk); box-shadow: var(--sunk);
  font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-2); white-space: nowrap;
}
.grade--good { color: var(--ok); }
.grade--warn { color: var(--danger); }

/* ── Shop drawer ────────────────────────────────────────────────── */
.shopitem {
  display: flex; align-items: center; gap: 13px;
  padding: 13px; margin-bottom: 10px;
  border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-1);
}
.shopitem__i {
  width: 46px; height: 46px; flex: none; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: var(--surface-sunk); box-shadow: var(--sunk); color: var(--ink-3); font-size: 15px;
}
.shopitem__m { flex: 1; min-width: 0; }
.shopitem__n { font-size: 13.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shopitem__c { display: block; margin-top: 3px; font-size: 11.5px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shopitem__p { font-size: 13px; font-weight: 800; color: var(--accent-text); white-space: nowrap; }

/* ── Background activity lives in the top bar — never over content ── */
.actbtn { position: relative; display: none; }
.actbtn.on { display: grid; }
.actbtn__s {
  width: 16px; height: 16px;
  border: 2px solid var(--accent); border-right-color: transparent;
  border-radius: 50%; animation: spin .8s linear infinite;
}
.job {
  display: flex; align-items: center; gap: 13px;
  padding: 12px; margin-bottom: 10px;
  border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-1);
}
.job .frame { width: 44px; height: 56px; flex: none; border-radius: var(--r-sm); box-shadow: var(--sh-1); }
.job .frame img { object-fit: contain; padding: 4%; }
.job__e {
  width: 44px; height: 56px; flex: none; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: var(--surface-sunk); box-shadow: var(--sunk); color: var(--accent-text); font-size: 15px;
}
.job__m { flex: 1; min-width: 0; }
.job__t { font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.job__s { display: block; margin-top: 4px; font-size: 11.5px; color: var(--ink-3); }
.job__s.err { color: var(--danger); }
.job__s.ok { color: var(--ok); }
.bar { height: 5px; border-radius: 3px; background: var(--surface-sunk); box-shadow: var(--sunk); margin-top: 8px; overflow: hidden; }
.bar i { display: block; height: 100%; border-radius: 3px; background: var(--accent); width: 0; transition: width .25s var(--e-lin); }
.bar.indet i { width: 40%; animation: slide 1.1s var(--e-out) infinite; }
@keyframes slide { from { transform: translateX(-110%) } to { transform: translateX(300%) } }

.capbox {
  border-radius: var(--r-lg); padding: 26px 22px; text-align: center;
  background: var(--surface-sunk); box-shadow: var(--sunk);
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.capbox .glyph {
  width: 58px; height: 58px; border-radius: var(--r-full); display: grid; place-items: center;
  background: var(--surface); box-shadow: var(--sh-1); color: var(--accent-text); font-size: 20px;
}
.capbox h3 { font-family: var(--f-display); font-weight: 500; font-size: 21px; }
.capbox p { font-size: 13.5px; color: var(--ink-2); max-width: 34ch; }

@media (min-width: 480px) { .pieces { grid-template-columns: repeat(4, 1fr); } .ggrid { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 700px) { .pieces { grid-template-columns: repeat(5, 1fr); } }
@media (min-width: 900px) {
  .viewer__stage { padding: calc(env(safe-area-inset-top) + 70px) 40px 20px; }
  .viewer__bar { justify-content: center; gap: 6px; }
  .vact { flex: 0 0 108px; }
  .ggrid { grid-template-columns: repeat(5, 1fr); }
}
@media (min-width: 1024px) { .pieces { grid-template-columns: repeat(6, 1fr); } }

/* The viewer holds the page still on its own, independent of Overlay's
   shared lock, so closing a sheet on top of it cannot free the scroll. */
html.viewer-open, html.viewer-open body { overflow: hidden; }




/* ══════════ page: discover ══════════ */


/* Masonry. The tile takes its height from the IMAGE — no fixed ratio and no
   crop, which is the whole point of a pinboard. */
/* Real column elements, NOT column-count. A multi-column container rebalances
   every item across all of its columns whenever one is appended, so on an
   infinite-scroll feed the tiles already on screen visibly reshuffle each time
   the next page arrives — which reads as the right-hand column "reloading".
   Separate column elements only ever grow at the bottom, so nothing that has
   been seen ever moves. The column COUNT is set by discover.js, which mirrors
   the breakpoints below. */
.mason { display: flex; align-items: flex-start; gap: 10px; }
.mason__col { flex: 1 1 0; min-width: 0; }
.mason__i {
  break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid;
  display: block; width: 100%; margin: 0 0 10px;
  position: relative; border-radius: var(--r-lg); overflow: hidden;
  background: var(--surface); box-shadow: var(--sh-2);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
  animation: fade .4s var(--e-lin) backwards; animation-delay: calc(var(--i,0) * 34ms);
}
.mason__i:hover { transform: translateY(-3px); box-shadow: var(--sh-3); }
.mason__m { display: block; width: 100%; cursor: pointer; background: var(--surface-2); }
.mason__m img { display: block; width: 100%; height: auto; }
.mason__i::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  box-shadow: inset 0 2px 3px rgba(255,255,255,.4), inset 0 -6px 12px rgba(38,6,15,.14);
}
:root[data-theme="dark"] .mason__i::after,
:root:not([data-theme="light"]) .mason__i::after {
  box-shadow: inset 0 2px 2px rgba(255,255,255,.08), inset 0 -6px 12px rgba(0,0,0,.36);
}

.mason__save {
  position: absolute; top: 9px; right: 9px; z-index: 2;
  width: 32px; height: 32px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--glass); color: var(--ink-2); font-size: 12px; box-shadow: var(--sh-1);
  -webkit-backdrop-filter: blur(14px) saturate(160%); backdrop-filter: blur(14px) saturate(160%);
  transition: color var(--t-fast) var(--e-lin), background-color var(--t-fast) var(--e-lin), transform var(--t) var(--e-out);
}
.mason__save:active { transform: scale(.88); }
.mason__save[aria-pressed="true"] { background: var(--accent); color: #fff; }

.mason__bar {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; align-items: center; gap: 8px;
  padding: 22px 11px 10px;
  background: rgba(10,4,7,.66);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.mason__like {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums;
  transition: transform var(--t) var(--e-out);
}
.mason__like:active { transform: scale(.88); }
.mason__like[aria-pressed="true"] { color: var(--wine-200); }
.mason__like.beat i { animation: heartbeat .55s var(--e-spring); }
.mason__who { display: flex; align-items: center; gap: 7px; margin-left: auto; min-width: 0; }
.mason__who .avatar { width: 21px; height: 21px; box-shadow: none; }
.mason__nm { font-size: 11px; font-weight: 600; color: rgba(255,255,255,.92); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 84px; }

/* Empty / end states live OUTSIDE the columns — inside, a block gets torn
   across two columns and clipped at the bottom. */
.feed-msg { margin-top: 6px; }
.people { display: flex; gap: 12px; overflow-x: auto; margin: 0 calc(var(--gut) * -1) 14px; padding: 4px var(--gut) 10px; scrollbar-width: none; }
.people::-webkit-scrollbar { display: none; }
.person { width: 66px; flex: none; text-align: center; transition: transform var(--t) var(--e-out); }
.person:active { transform: scale(.94); }
.person .avatar { width: 58px; height: 58px; margin: 0 auto; box-shadow: var(--sh-2); }
.person__n { display: block; margin-top: 8px; font-size: 11px; font-weight: 600; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Pin detail — a page, not a dialog ──────────────────────────── */
.pin {
  position: fixed; inset: 0; height: 100vh; height: 100dvh; z-index: 92;
  background: var(--bg);
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  opacity: 0; pointer-events: none;
  transition: opacity var(--t) var(--e-lin);
}
.pin.open { opacity: 1; pointer-events: auto; }
.pin__back {
  position: fixed; top: calc(env(safe-area-inset-top) + 12px); left: 14px; z-index: 4;
  background: var(--glass);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.pin__in { max-width: 720px; margin: 0 auto; padding: calc(env(safe-area-inset-top) + 66px) var(--gut) calc(var(--dock-h) + env(safe-area-inset-bottom) + 40px); }
.pin__hero { width: 100%; border-radius: var(--r-xl); overflow: hidden; background: var(--surface-2); box-shadow: var(--sh-3); }
.pin__hero img { display: block; width: 100%; height: auto; }
.pin__acts { display: flex; align-items: center; gap: 10px; margin-top: 18px; }
.pinact {
  display: inline-flex; align-items: center; gap: 8px;
  height: 46px; padding: 0 18px; border-radius: var(--r-full);
  background: var(--surface); box-shadow: var(--sh-2);
  font-size: 13.5px; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums;
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out), color var(--t-fast) var(--e-lin);
}
.pinact:hover { transform: translateY(-2px); box-shadow: var(--sh-3); }
.pinact:active { transform: translateY(1px) scale(.97); box-shadow: var(--sunk); }
.pinact[aria-pressed="true"] { color: var(--accent); }
.pinact.beat i { animation: heartbeat .55s var(--e-spring); }
.pinact--go { margin-left: auto; background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow); }
.pinact--go:hover { background: var(--accent-hover); }

.pin__who { display: flex; align-items: center; gap: 12px; margin-top: 22px; }
.pin__who .avatar { width: 46px; height: 46px; }
.pin__wm { flex: 1; min-width: 0; }
.pin__wn { font-size: 14.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pin__ws { display: block; margin-top: 3px; font-size: 12px; color: var(--ink-3); }
.pin__cap { margin-top: 18px; font-size: 15px; line-height: 1.6; color: var(--ink-2); }
.pin__items { display: flex; gap: 9px; margin-top: 18px; overflow-x: auto; scrollbar-width: none; padding-bottom: 4px; }
.pin__items::-webkit-scrollbar { display: none; }
.pin__items .frame { width: 66px; height: 82px; flex: none; border-radius: var(--r-sm); box-shadow: var(--sh-1); }
.pin__more { margin-top: 34px; }
.pin__more h3 { font-family: var(--f-display); font-weight: 500; font-size: 20px; margin-bottom: 14px; }

/* Column COUNT now lives in discover.js (cols.want) — these breakpoints must
   stay in step with it. Only the gutter changes here. */
@media (min-width: 1024px) { .mason { gap: 14px; } .mason__i { margin-bottom: 14px; } }
@media (min-width: 900px)  { .pin__in { padding-bottom: 60px; } }

@media (hover: none) {
  .mason__i:hover, .pinact:hover { transform: none; }
}

/* The pin view holds the page still behind it. */
html.pin-open, html.pin-open body { overflow: hidden; }


/* ══════════ page: calendar ══════════ */
/* ── Calendar ───────────────────────────────────────────────────────
   #view spaces its DIRECT children, but these sections live inside the
   tab panes, so they carry their own rhythm or they butt together. */
#panePlanner, #paneStreaks { display: flex; flex-direction: column; gap: 28px; }
.cal-cols { display: flex; flex-direction: column; gap: 28px; }
#planBanner:empty { display: none; }

.cal { border-radius: var(--r-xl); padding: 16px; background: var(--surface); box-shadow: var(--sh-2); }
.dow { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; margin-bottom: 8px; }
.dow span { text-align: center; font-size: 9.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.day {
  position: relative; aspect-ratio: 1; border-radius: var(--r-sm);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  font-size: 13px; font-weight: 600; color: var(--ink-2);
  background: var(--surface-sunk); box-shadow: var(--sunk);
  transition: color var(--t-fast) var(--e-lin), background-color var(--t-fast) var(--e-lin),
              box-shadow var(--t) var(--e-out), transform var(--t) var(--e-out);
}
.day:hover { color: var(--ink); }
.day:active { transform: scale(.93); }
.day.pad { background: none; box-shadow: none; color: var(--ink-3); opacity: .35; pointer-events: none; }
.day.today { box-shadow: var(--sunk), inset 0 0 0 2px var(--accent); color: var(--accent-text); font-weight: 800; }
.day.has { background: var(--surface); box-shadow: var(--sh-1); color: var(--ink); }
.day.sel { background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow-sm); }
.day__d { display: flex; gap: 2px; height: 4px; }
.day__d i { width: 4px; height: 4px; border-radius: 50%; background: var(--accent); }
.day.sel .day__d i { background: var(--accent-ink); }

.slot {
  display: flex; align-items: center; gap: 13px;
  padding: 11px; margin-bottom: 10px;
  border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-1);
  width: 100%; text-align: left;
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.slot:hover { transform: translateY(-2px); box-shadow: var(--sh-2); }
.slot:active { transform: translateY(1px) scale(.99); box-shadow: var(--sunk); }
.slot .frame { width: 52px; height: 66px; flex: none; border-radius: var(--r-sm); box-shadow: var(--sh-1); }
.slot__e {
  width: 52px; height: 66px; flex: none; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: var(--surface-sunk); box-shadow: var(--sunk); color: var(--ink-3); font-size: 15px;
}
.slot__m { flex: 1; min-width: 0; }
.slot__n { font-size: 13.5px; font-weight: 700; text-transform: capitalize; }
.slot__s { display: block; margin-top: 4px; font-size: 12px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.slot__x { width: 34px; height: 34px; flex: none; border-radius: var(--r-full); display: grid; place-items: center; color: var(--ink-3); font-size: 12px; }
.slot__x:hover { color: var(--danger); background: var(--surface-sunk); }

.pickgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.pickgrid .frame { aspect-ratio: 3/4; border-radius: var(--r-sm); box-shadow: var(--sh-1); width: 100%; }
.pickgrid button { border-radius: var(--r-sm); overflow: hidden; transition: transform var(--t) var(--e-out); }
.pickgrid button:hover { transform: translateY(-3px); }
.pickgrid button:active { transform: scale(.95); }

.banner {
  display: flex; align-items: center; gap: 12px; margin-bottom: 18px;
  padding: 14px 16px; border-radius: var(--r-lg);
  background: var(--accent-soft); box-shadow: var(--sh-1);
}
.banner i { color: var(--accent-text); font-size: 15px; flex: none; }
.banner span { flex: 1; font-size: 13px; font-weight: 600; color: var(--ink-2); }

@media (min-width: 640px) {
  .day { font-size: 15px; }
  .pickgrid { grid-template-columns: repeat(4, 1fr); }
  .cal { padding: 22px; }
}
@media (min-width: 1024px) { .cal-cols { display: grid; grid-template-columns: minmax(0,1fr) 380px; gap: 34px; align-items: start; } }

/* ── Streaks tab ────────────────────────────────────────────────── */
.flame {
  border-radius: var(--r-xl); padding: 28px 22px; text-align: center;
  background: var(--surface); box-shadow: var(--sh-3);
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
.flame__o {
  position: relative;
  width: 92px; height: 92px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--surface-sunk); box-shadow: var(--sunk);
  color: var(--accent-text); font-size: 34px;
}
.flame__o.alive::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  animation: halo 2.8s var(--e-lin) infinite;
}
.flame__n { font-family: var(--f-display); font-weight: 500; font-size: 52px; line-height: 1; font-variant-numeric: tabular-nums; }
.flame__k { font-size: 10px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3); }
.flame__s { font-size: 14px; color: var(--ink-2); max-width: 34ch; }

.week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 7px; margin-top: 20px; }
.wd {
  aspect-ratio: 1; border-radius: var(--r-sm);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  background: var(--surface-sunk); box-shadow: var(--sunk);
  font-size: 9.5px; font-weight: 800; text-transform: uppercase; color: var(--ink-3);
}
.wd b { font-size: 13px; font-weight: 700; color: var(--ink-2); }
.wd.on { background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow-sm); }
.wd.on b { color: var(--accent-ink); }
.wd.today { box-shadow: var(--sunk), inset 0 0 0 2px var(--accent); }
.wd.on.today { box-shadow: var(--glow-sm), inset 0 0 0 2px var(--accent-ink); }

.logs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 13px; }
.log {
  position: relative; border-radius: var(--r-lg); overflow: hidden;
  background: var(--surface); box-shadow: var(--sh-2);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
  animation: fade .45s var(--e-lin) backwards; animation-delay: calc(var(--i,0) * 42ms);
}
.log:hover { transform: translateY(-3px); box-shadow: var(--sh-3); }
.log__media { aspect-ratio: 3/4; width: 100%; }
.log__b { padding: 10px 12px 12px; }
.log__d { font-size: 12.5px; font-weight: 700; }
.log__s { display: block; margin-top: 3px; font-size: 11px; color: var(--ink-3); text-transform: capitalize; }
.log__v {
  position: absolute; top: 9px; right: 9px;
  width: 26px; height: 26px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--glass); color: var(--ink-2); font-size: 10px; box-shadow: var(--sh-1);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
@media (min-width: 640px) { .logs { grid-template-columns: repeat(3, 1fr); gap: 16px; } }
@media (min-width: 1024px) { .logs { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1440px) { .logs { grid-template-columns: repeat(5, 1fr); } }


/* ══════════ page: profile ══════════ */
/* ── Profile ────────────────────────────────────────────────────── */
.phead {
  border-radius: var(--r-xl); padding: 24px 22px;
  background: var(--surface); box-shadow: var(--sh-3);
  text-align: center;
}
.phead .avatar { width: 96px; height: 96px; margin: 0 auto 16px; font-size: 30px; box-shadow: var(--sh-2); }
.phead h2 { font-family: var(--f-display); font-weight: 500; font-size: 27px; letter-spacing: -.01em; }
.phead .handle { margin-top: 5px; font-size: 12.5px; color: var(--ink-3); }
.phead .bio { margin-top: 13px; font-size: 14px; color: var(--ink-2); line-height: 1.55; max-width: 46ch; margin-inline: auto; }
.phead .where {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 12px;
  padding: 7px 14px; border-radius: var(--r-full);
  background: var(--surface-sunk); box-shadow: var(--sunk);
  font-size: 12px; font-weight: 600; color: var(--ink-2); white-space: nowrap;
}
.pnums { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 20px; }
.pnum { padding: 14px 8px; border-radius: var(--r-lg); background: var(--surface-sunk); box-shadow: var(--sunk); }
.pnum b { display: block; font-family: var(--f-display); font-weight: 500; font-size: 24px; line-height: 1; font-variant-numeric: tabular-nums; }
.pnum span { display: block; margin-top: 7px; font-size: 9.5px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }
.pacts { display: flex; gap: 10px; margin-top: 20px; }
.pacts .btn { flex: 1; }

.shopcard {
  display: flex; align-items: center; gap: 14px; margin-top: 16px;
  padding: 15px; border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--sh-2); text-align: left; width: 100%;
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out);
}
.shopcard:hover { transform: translateY(-2px); box-shadow: var(--sh-3); }
.shopcard .frame { width: 52px; height: 52px; border-radius: var(--r-sm); flex: none; box-shadow: var(--sh-1); }
.shopcard b { display: block; font-size: 14px; font-weight: 700; }
.shopcard span { display: block; margin-top: 3px; font-size: 12px; color: var(--ink-3); }

/* ── Account hub (own profile only) ─────────────────────────────── */
.grp { margin-top: 26px; }
.grp__k { display: block; margin: 0 0 10px 4px; font-size: 10px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.grp__b { border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--sh-2); overflow: hidden; }
.row {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
  padding: 15px 17px;
  transition: background-color var(--t-fast) var(--e-lin);
}
.row + .row { box-shadow: inset 0 1px 0 var(--line); }
.row:hover { background: var(--surface-2); }
.row:active { background: var(--surface-3); }
.row__i { width: 24px; text-align: center; color: var(--ink-3); font-size: 15px; flex: none; }
.row__t { flex: 1; font-size: 14px; font-weight: 600; }
.row__v { font-size: 12.5px; color: var(--ink-3); white-space: nowrap; }
.row__c { color: var(--ink-3); font-size: 12px; }
.row--danger .row__t, .row--danger .row__i { color: var(--danger); }

.ptabs { display: flex; gap: 4px; margin: 22px 0 14px; }
.ptab {
  position: relative; flex: 1; height: 44px;
  font-size: 13.5px; font-weight: 700; color: var(--ink-3); white-space: nowrap;
  transition: color var(--t-fast) var(--e-lin);
}
.ptab[aria-selected="true"] { color: var(--ink); }
.ptab[aria-selected="true"]::after {
  content: ""; position: absolute; left: 50%; bottom: 4px; transform: translateX(-50%);
  width: 26px; height: 3px; border-radius: 3px; background: var(--accent);
  animation: pop .3s var(--e-spring);
}
@media (min-width: 1024px) { .prof-cols { display: grid; grid-template-columns: 360px minmax(0,1fr); gap: 32px; align-items: start; } }


/* ══════════ page: settings ══════════ */


.photorow { display: flex; align-items: center; gap: 16px; margin-top: 16px; }
.photorow .avatar { width: 76px; height: 76px; font-size: 24px; box-shadow: var(--sh-2); }
.photorow .frame { width: 68px; height: 86px; border-radius: var(--r-sm); box-shadow: var(--sh-2); flex: none; }
.photorow__m { flex: 1; min-width: 0; }
.photorow__m b { display: block; font-size: 14px; font-weight: 700; }
.photorow__m span { display: block; margin-top: 4px; font-size: 12px; color: var(--ink-3); line-height: 1.4; }
.photorow__a { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

.tog {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 0; cursor: pointer;
}
.tog + .tog { box-shadow: inset 0 1px 0 var(--line); }
.tog__m { flex: 1; min-width: 0; }
.tog__m b { display: block; font-size: 14px; font-weight: 600; }
.tog__m span { display: block; margin-top: 3px; font-size: 12px; color: var(--ink-3); }
.tog input { position: absolute; opacity: 0; width: 0; height: 0; }
.tog__s {
  width: 50px; height: 30px; flex: none; border-radius: var(--r-full); position: relative;
  background: var(--surface-sunk); box-shadow: var(--sunk);
  transition: background-color var(--t) var(--e-lin);
}
.tog__s::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 24px; height: 24px; border-radius: var(--r-full);
  background: var(--surface); box-shadow: var(--sh-1);
  transition: transform var(--t) var(--e-out);
}
.tog input:checked ~ .tog__s { background: var(--accent); box-shadow: var(--glow-sm); }
.tog input:checked ~ .tog__s::after { transform: translateX(20px); }
.tog input:focus-visible ~ .tog__s { outline: 2.5px solid var(--focus); outline-offset: 3px; }

.themerow { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 14px; }
.themeopt {
  padding: 15px 10px; border-radius: var(--r-lg); text-align: center;
  background: var(--surface-sunk); box-shadow: var(--sunk);
  font-size: 12.5px; font-weight: 700; color: var(--ink-3);
  transition: color var(--t-fast) var(--e-lin), background-color var(--t-fast) var(--e-lin),
              box-shadow var(--t) var(--e-out), transform var(--t) var(--e-out);
}
.themeopt i { display: block; font-size: 17px; margin-bottom: 8px; }
.themeopt:active { transform: scale(.96); }
.themeopt[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); box-shadow: var(--glow-sm); }

.planbar {
  display: flex; align-items: center; gap: 14px; margin-top: 16px;
  padding: 15px; border-radius: var(--r-lg);
  background: var(--surface-sunk); box-shadow: var(--sunk);
}
.planbar__i { width: 44px; height: 44px; flex: none; border-radius: var(--r-full); display: grid; place-items: center;
  background: var(--surface); box-shadow: var(--sh-1); color: var(--accent-text); font-size: 17px; }
.planbar__m { flex: 1; min-width: 0; }
.planbar__m b { display: block; font-size: 14px; font-weight: 700; }
.planbar__m span { display: block; margin-top: 3px; font-size: 12px; color: var(--ink-3); }

.linkrow {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
  padding: 15px 0; transition: opacity var(--t-fast) var(--e-lin);
}
.linkrow + .linkrow { box-shadow: inset 0 1px 0 var(--line); }
.linkrow:active { opacity: .6; }
.linkrow i.lead { width: 22px; text-align: center; color: var(--ink-3); font-size: 15px; flex: none; }
.linkrow b { flex: 1; font-size: 14px; font-weight: 600; }
.linkrow i.chev { color: var(--ink-3); font-size: 12px; }
.linkrow--danger b, .linkrow--danger i.lead { color: var(--danger); }

@media (min-width: 900px) { .set-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; } }


/* ══════════ page: analytics ══════════ */
/* ── Analytics ──────────────────────────────────────────────────── */
.kpis { display: grid; grid-template-columns: repeat(2, 1fr); gap: 11px; }
.kpi { padding: 17px 15px; border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--sh-2); }
.kpi__k { display: block; font-size: 10px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }
.kpi__v { display: block; margin-top: 9px; font-family: var(--f-display); font-weight: 500; font-size: 30px; line-height: 1; font-variant-numeric: tabular-nums; }

/* Chart: one series, so one colour for every column and no legend —
   the heading names what is plotted. */
.chart { border-radius: var(--r-lg); padding: 20px 18px 16px; background: var(--surface); box-shadow: var(--sh-2); }
.chart__h { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.chart__t { font-size: 14px; font-weight: 700; }
.chart__sub { margin-left: auto; font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.chart__plot { position: relative; height: 168px; margin-top: 18px; }
/* Solid hairline gridlines, one shade off the surface — never dashed */
.chart__grid { position: absolute; inset: 0; pointer-events: none; }
.chart__grid i { position: absolute; left: 0; right: 0; height: 1px; background: var(--line); }
.chart__ax {
  position: absolute; left: 0; font-size: 10px; font-weight: 600; color: var(--ink-3);
  transform: translateY(-50%); font-variant-numeric: tabular-nums; background: var(--surface); padding-right: 6px;
}
.chart__cols { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 8px; }
.col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; position: relative; }
.col__bar {
  width: 100%; border-radius: 4px 4px 0 0;         /* rounded data-end, anchored to the baseline */
  background: var(--accent); min-height: 3px;
  transform-origin: bottom;
  animation: grow .7s var(--e-out) backwards;
  animation-delay: calc(var(--i, 0) * 55ms);
  transition: filter var(--t-fast) var(--e-lin);
}
@keyframes grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }
.col:hover .col__bar { filter: brightness(1.12); }
.col--zero .col__bar { background: var(--surface-3); }
/* Selective direct label — only the peak carries a number; the axis and the
   tooltip carry the rest. */
.col__cap {
  position: absolute; left: 0; right: 0; text-align: center;
  font-size: 10.5px; font-weight: 800; color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.chart__days { display: flex; gap: 8px; margin-top: 9px; }
.chart__days span { flex: 1; text-align: center; font-size: 10px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; }
.chart__tip {
  position: absolute; z-index: 3; pointer-events: none;
  padding: 8px 12px; border-radius: var(--r-sm);
  background: var(--surface); box-shadow: var(--sh-3);
  font-size: 11.5px; font-weight: 600; color: var(--ink); white-space: nowrap;
  opacity: 0; transform: translate(-50%, -6px);
  transition: opacity var(--t-fast) var(--e-lin);
}
.chart__tip.on { opacity: 1; }
.chart__tip b { color: var(--accent-text); }
.chart__foot { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.chart__foot button { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--accent-text); }
.chart__foot button:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Table view — nothing is gated behind hover */
.dtable { width: 100%; margin-top: 14px; border-collapse: collapse; font-size: 13px; }
.dtable th, .dtable td { padding: 9px 6px; text-align: left; }
.dtable th { font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.dtable td { box-shadow: inset 0 1px 0 var(--line); font-variant-numeric: tabular-nums; }
.dtable td:last-child, .dtable th:last-child { text-align: right; }

.follower { display: flex; align-items: center; gap: 12px; padding: 11px 0; }
.follower + .follower { box-shadow: inset 0 1px 0 var(--line); }
.follower .avatar { width: 38px; height: 38px; }
.follower__m { flex: 1; min-width: 0; }
.follower__n { font-size: 13.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.follower__d { display: block; margin-top: 3px; font-size: 11.5px; color: var(--ink-3); }

@media (min-width: 640px) { .kpis { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1024px) { .an-cols { display: grid; grid-template-columns: minmax(0,1fr) 340px; gap: 30px; align-items: start; } }


/* ══════════ page: developer ══════════ */


.bal { display: flex; align-items: baseline; gap: 10px; margin-top: 14px; }
.bal b { font-family: var(--f-display); font-weight: 500; font-size: 44px; line-height: 1; font-variant-numeric: tabular-nums; }
.bal span { font-size: 13px; color: var(--ink-3); }

.mini { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 18px; }
.mini div { padding: 13px 10px; border-radius: var(--r-lg); background: var(--surface-sunk); box-shadow: var(--sunk); text-align: center; }
.mini b { display: block; font-family: var(--f-display); font-weight: 500; font-size: 21px; line-height: 1; font-variant-numeric: tabular-nums; }
.mini span { display: block; margin-top: 6px; font-size: 9px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }

.keyrow {
  display: flex; align-items: center; gap: 13px;
  padding: 14px 0;
}
.keyrow + .keyrow { box-shadow: inset 0 1px 0 var(--line); }
.keyrow__m { flex: 1; min-width: 0; }
.keyrow__n { font-size: 13.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.keyrow__p {
  display: block; margin-top: 5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.keyrow__s { display: block; margin-top: 5px; font-size: 11px; color: var(--ink-3); }
.keyrow.dead { opacity: .5; }
.keyrow__x { width: 36px; height: 36px; flex: none; border-radius: var(--r-full); display: grid; place-items: center; color: var(--ink-3); font-size: 13px; }
.keyrow__x:hover { color: var(--danger); background: var(--surface-sunk); }

.secret {
  margin-top: 16px; padding: 15px;
  border-radius: var(--r-lg);
  background: var(--surface-sunk); box-shadow: var(--sunk);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px; word-break: break-all; line-height: 1.6; color: var(--ink);
}
.code {
  margin-top: 14px; padding: 16px;
  border-radius: var(--r-lg);
  background: var(--surface-sunk); box-shadow: var(--sunk);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; line-height: 1.7; color: var(--ink-2);
  overflow-x: auto; white-space: pre;
}
.code b { color: var(--accent-text); font-weight: 700; }

.usage { margin-top: 8px; }
.urow { display: flex; align-items: center; gap: 12px; padding: 11px 0; font-size: 12.5px; }
.urow + .urow { box-shadow: inset 0 1px 0 var(--line); }
.udot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--ok); }
.udot.bad { background: var(--danger); }
.urow__e { flex: 1; font-weight: 600; }
.urow__t { color: var(--ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.urow__c { font-weight: 700; color: var(--ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }

@media (min-width: 900px) { .dev-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; } }

/* ── Connection status ───────────────────────────────────────────────
   Deliberately not a toast: connectivity is a state, not an event, and it
   used to arrive as a stack of red toasts — one per failed request — for
   something the user cannot act on. This sits above the dock, out of the
   way, and says only what is true. */
.netbar {
  position: fixed;
  left: 50%;
  bottom: calc(var(--dock-h, 64px) + 14px + env(safe-area-inset-bottom));
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100vw - 32px);
  padding: 9px 15px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--ink-2);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 6px 18px rgba(38, 6, 15, .12);
  transform: translate(-50%, 10px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s var(--e-lin), transform .22s var(--e-lin);
}
.netbar.on { opacity: 1; transform: translate(-50%, 0); }
.netbar i { font-size: 12px; opacity: .75; }

@media (prefers-reduced-motion: reduce) {
  .netbar { transition: opacity .01s; transform: translate(-50%, 0); }
}
