/* ─────────────────────────────────────────────────────────────
   now. — Cory, right now
   Tokens → base → top bar → hero (fan / carousel) → tiles →
   cards → charts → tooltips → footer → motion
   ───────────────────────────────────────────────────────────── */

/* ── Tokens ───────────────────────────────────────────────────── */
:root {
  --font-display: 'Bricolage Grotesque', ui-sans-serif, system-ui, sans-serif;
  --font-sans: 'Geist', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --page: 1296px;
  --gutter: 72px;
  --radius-card: 24px;
  --tile-base: 240;                      /* the size tiles are drawn at; --u (below) is a pixel of it */
  --tile: calc(var(--tile-base) * 1px);
  --tile-radius: calc(var(--tile) * 56 / var(--tile-base));   /* scales with the tile, like everything in it */
  --ease-out: cubic-bezier(.2, .8, .2, 1);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0E100F;
  --card: #161817;
  --ink: 255 252 225;               /* cream, as RGB for alpha mixes */
  --text: rgb(var(--ink));
  --text-70: rgb(var(--ink) / .7);
  --text-55: rgb(var(--ink) / .55);
  --hairline: rgb(var(--ink) / .08);
  --neutral: rgb(var(--ink) / .14);  /* past-day bars, tracks */
  --grid: rgb(var(--ink) / .09);
  --card-shadow: none;
  --tile-shadow: drop-shadow(0 24px 22px rgb(0 0 0 / .5));

  /* headline + metric colours */
  --c-sleep: #9D95FF;  --c-move: #FF8709;  --c-listen: #FEA6E1;  --c-music: #0AE448;
  --c-heart: #FF5C7A;  --c-hrv: #A6FF00;   --c-steps: #FF9F0A;   --c-spo2: #5AC8FA;
  --c-ring-move: #FA114F; --c-ring-ex: #A6FF00; --c-ring-stand: #00E5FF;
  --ring-track-o: .18;  /* ring tracks use their own hue in dark */
  --c-speed: #5AC8FA;  --c-stride: #A6FF00; --c-walkhr: #FF375F; --c-asym: #BF5AF2;
  --c-gauge-a: #0A84FF; --c-gauge-b: #5AC8FA;
  --c-stage-awake: #FF8A65; --c-stage-rem: #5AC8FA; --c-stage-core: #0A84FF; --c-stage-deep: #5E5CE6;
  --t-ex: #A6FF00; --t-stand: #00E5FF; --t-move: #FA114F;   /* coloured label text */
  --sync-on: #A6FF00; --sync-stale: #FF9F0A;
}

:root[data-theme="light"] {
  color-scheme: light;
  --bg: #F5F2EA;
  --card: #FFFFFF;
  --ink: 23 21 15;
  --text: rgb(var(--ink));
  --text-70: rgb(var(--ink) / .72);
  --text-55: rgb(var(--ink) / .62);
  --hairline: rgb(var(--ink) / .07);
  --neutral: rgb(var(--ink) / .08);
  --grid: rgb(var(--ink) / .08);
  --card-shadow: 0 8px 24px -6px rgb(23 21 15 / .06);
  --tile-shadow: drop-shadow(0 16px 16px rgb(23 21 15 / .13)) drop-shadow(0 2px 2px rgb(23 21 15 / .07));

  --c-sleep: #5D4FE8;  --c-move: #F26B00;  --c-listen: #D6339A;  --c-music: #0E9F3E;
  --c-heart: #F0365A;  --c-hrv: #4CC500;   --c-steps: #FF8500;   --c-spo2: #0A9FE0;
  --c-ring-move: #F20F4B; --c-ring-ex: #4CC500; --c-ring-stand: #00B2E3;
  --ring-track-o: .07;  /* neutral tracks on white */
  --track-move: var(--text); --track-ex: var(--text); --track-stand: var(--text);
  --c-speed: #0A9FE0;  --c-stride: #4CC500; --c-walkhr: #FF375F; --c-asym: #A447E6;
  --c-gauge-a: #0A6FE0; --c-gauge-b: #0A9FE0;
  --c-stage-awake: #FF7A45; --c-stage-rem: #0A9FE0; --c-stage-core: #0A6FE0; --c-stage-deep: #4B49D6;
  --t-ex: #3A9A00; --t-stand: #0093BD; --t-move: #E00D45;
  --sync-on: #12A140; --sync-stale: #C25E00;
}

/* ── Base ─────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  transition: background-color .4s var(--ease-out), color .4s var(--ease-out);
  overflow-x: hidden;
}
a { color: inherit; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
.mono { font-family: var(--font-mono); }

main, .topbar, .footer { width: min(var(--page), 100% - 2 * var(--gutter)); margin-inline: auto; }

/* ── Top bar ──────────────────────────────────────────────────── */
.topbar { display: flex; align-items: center; justify-content: space-between; padding-top: 36px; }
.wordmark { font-family: var(--font-display); font-weight: 800; font-size: 36px; letter-spacing: -.04em; text-decoration: none; }
.topbar-actions { display: flex; align-items: center; gap: 14px; }

/* top bar speaks in the headline's voice: "Synced 10:13 AM · ☾ Lights off" */
.topbar-actions { gap: 20px; font-family: var(--font-display); font-weight: 600; font-size: 20px; letter-spacing: -.02em; }
.sync { color: var(--text-55); white-space: nowrap; }
/* usually server-rendered (already .is-ready); otherwise the bar fades in as one */
.topbar-actions { transition: opacity .4s ease-out; }
.topbar-actions:not(.is-ready) { opacity: 0; }
.sync-time { color: var(--sync-on); transition: color .3s; }
.sync.is-stale .sync-time { color: var(--sync-stale); }
.topbar-sep { width: 4px; height: 4px; border-radius: 50%; background: rgb(var(--ink) / .25); flex: none; }
.theme-switch {
  display: inline-flex; align-items: center; gap: 7px; padding: 6px 0;
  letter-spacing: inherit; white-space: nowrap; color: rgb(var(--ink) / .88); transition: color .2s;
}
.theme-switch:hover { color: var(--text); }
.theme-switch:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; border-radius: 6px; }
.theme-icon { width: 16px; height: 16px; flex: none; background: currentColor; mask: var(--sun) center / contain no-repeat; transition: rotate .5s var(--ease-out); }
:root[data-theme="dark"] .theme-icon { mask-image: var(--moon); }
.theme-switch:hover .theme-icon { rotate: -18deg; }
/* both phrases share one grid cell, so the switch is always as wide as the longer
   one and toggling never nudges the sync text */
.theme-word { display: inline-grid; }
.theme-word::before, .theme-word::after { grid-area: 1 / 1; }
.theme-word::before { content: 'Lights on'; }
.theme-word::after { content: 'Lights off'; visibility: hidden; }
:root[data-theme="dark"] .theme-word::before { visibility: hidden; }
:root[data-theme="dark"] .theme-word::after { visibility: visible; }
:root {
  --sun: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4.5'/%3E%3Cpath d='M12 2v2.5M12 19.5V22M2 12h2.5M19.5 12H22M4.9 4.9l1.8 1.8M17.3 17.3l1.8 1.8M4.9 19.1l1.8-1.8M17.3 6.7l1.8-1.8' stroke='%23000' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E");
  --moon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.5 14.5A8.5 8.5 0 0 1 9.5 3.5a8.5 8.5 0 1 0 11 11z'/%3E%3C/svg%3E");
}

/* ── Hero ─────────────────────────────────────────────────────── */
.hero { padding-top: 64px; }
.headline {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(46px, 7.8vw, 112px); line-height: 1; letter-spacing: -.03em;
  text-align: center; max-width: 1240px; margin-inline: auto; text-wrap: balance;
}
/* load: hidden until the font is ready, then each line fades up in turn
   (failsafe: shows anyway after 3s if the reveal script never runs) */
.reveal .headline:not(.is-ready) { opacity: 0; animation: failsafe 0s 3s forwards; }
@keyframes failsafe { to { opacity: 1; } }
.headline .w, .headline .wi { display: inline-block; }
/* each word is a mask (clip-path keeps the baseline, and the insets leave room
   for ascenders/descenders); words slide up one after another, in reading order.
   A keyframe animation always starts hidden and waits for the first painted frame. */
.headline.is-ready .w { clip-path: inset(-.2em -.15em -.22em -.15em); }
.headline.is-ready .wi { animation: rise 1.15s cubic-bezier(.16, 1, .3, 1) both; animation-delay: calc(100ms + var(--word, 0) * 55ms); }
@keyframes rise { from { translate: 0 1.5em; } }
.headline .wp { color: var(--text); }


/* desktop: a fan of tiles on an arc */
.fan { position: relative; height: 420px; margin-top: 56px; }
/* the slot places, tilts and shadows a tile; the tile inside is clipped to a squircle,
   so the shadow is a drop-shadow that follows the clipped shape */
.tile-slot {
  --x: 0px; --y: 0px; --r: 0deg;
  position: absolute; left: 50%; top: 40px;
  width: var(--tile); height: var(--tile); margin-left: calc(var(--tile) / -2);
  transform: translate(var(--x), var(--y)) rotate(var(--r));
  filter: var(--tile-shadow);
  transition: transform .6s var(--ease-out);
}
.tile-slot:nth-child(1) { --x: -470px; --y: 55px; --r: -12deg; z-index: 1; }
.tile-slot:nth-child(2) { --x: -235px; --y: 15px; --r: -6deg;  z-index: 2; }
.tile-slot:nth-child(3) { --x: 0px;    --y: 0px;  --r: 0deg;   z-index: 3; }
.tile-slot:nth-child(4) { --x: 235px;  --y: 15px; --r: 6deg;   z-index: 2; }
.tile-slot:nth-child(5) { --x: 470px;  --y: 55px; --r: 12deg;  z-index: 1; }
/* hover lifts the tile inside its slot: the slot (the hover target) stays put, so a
   cursor near the bottom edge can't fall off and back on. Fan layout only. */
@media (hover: hover) and (min-width: 1001px) {
  .fan .tile-slot:hover { z-index: 5; }
  .fan .tile-slot:hover .tile { transform: translateY(-10px); }
}
.tile {
  --edge: rgb(255 255 255 / .12);
  position: absolute; inset: 0; overflow: hidden;
  border-radius: var(--tile-radius);
  color: #fff;
  transition: transform .5s var(--ease-out);
}
.tile.sq { clip-path: var(--sq-clip); }
/* one unit for everything inside a tile: a desktop pixel, scaled to the tile's width.
   Tiles are drawn at --tile-base (240px), so --u is 1px there and ~1.17px on the 280px mobile tile;
   every tile grows as one rather than leaving its content desktop-sized. Without
   container units (Safari 15 and older) it stays 1px: desktop sizes, still laid out. */
.tile { --u: 1px; }
@supports (width: 1cqw) { .tile { container-type: inline-size; --u: calc(100cqw / var(--tile-base)); } }
/* the base size for anything inside a tile (not on .tile: its cqw would measure the fan, not the tile) */
.tile > * { font-size: calc(16 * var(--u)); }

/* hairline edge, drawn inside the shape (a CSS border would let the gradient repeat into it) */
.tile::before, .card::after {
  content: ''; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  border-radius: inherit; box-shadow: inset 0 0 0 1px var(--edge);
}
.tile.sq::before, .card.sq::after {
  box-shadow: none; background: var(--edge);
  -webkit-mask: var(--sq-edge) 0 0 / 100% 100%; mask: var(--sq-edge) 0 0 / 100% 100%;
}
.fan-dots { display: none; }

/* entrance: once the headline has landed, tiles rise into place left to right.
   --tiles-at is set by the headline reveal; failsafe shows them after 3.5s */
.reveal .hero:not(.is-in) .tile { opacity: 0; animation: failsafe 0s 3.5s forwards; }
.hero.is-in .tile { animation: tile-in .9s cubic-bezier(.16, 1, .3, 1) both; animation-delay: calc(var(--tiles-at, 0ms) + var(--i, 0) * 70ms); }
.tile-slot:nth-child(2) .tile { --i: 1; } .tile-slot:nth-child(3) .tile { --i: 2; }
.tile-slot:nth-child(4) .tile { --i: 3; } .tile-slot:nth-child(5) .tile { --i: 4; }
@keyframes tile-in { from { opacity: 0; translate: 0 48px; } 40% { opacity: 1; } }

/* ── Tiles ────────────────────────────────────────────────────── */
.tile-inner { position: absolute; inset: 0; padding: calc(22 * var(--u)); display: flex; flex-direction: column; justify-content: space-between; }
.tile-label { font-family: var(--font-mono); font-weight: 500; font-size: calc(10 * var(--u)); letter-spacing: .08em; text-transform: uppercase; opacity: .75; }
.tile-value { font-weight: 300; font-size: calc(56 * var(--u)); letter-spacing: -.04em; line-height: 1; white-space: nowrap; }
.tile-value .u { font-size: .42em; font-weight: 400; letter-spacing: .01em; margin-left: .12em; }
.tile-sub { font-size: calc(13 * var(--u)); opacity: .7; margin-top: calc(6 * var(--u)); }
.tile-bottom { position: relative; }

/* sky follows the conditions: clear day, night, grey (cloud, fog, rain, snow) or storm */
/* dark skies match the Figma range cards ("Weather icons — redrawn") */
.tile-weather { background: linear-gradient(#4F86DA, #24489A); }
.tile-weather[data-sky="night"] { background: linear-gradient(#22306A, #0D1433); }
.tile-weather[data-sky="grey"] { background: linear-gradient(#6F7F98, #3C4659); }
.tile-weather[data-sky="storm"] { background: linear-gradient(#4A4F66, #1E2130); }
:root[data-theme="light"] .tile-weather { background: linear-gradient(#6EC1FF, #2F7FE8); }
:root[data-theme="light"] .tile-weather[data-sky="night"] { background: linear-gradient(#34488F, #18224D); }
:root[data-theme="light"] .tile-weather[data-sky="grey"] { background: linear-gradient(#9AABC4, #5F6F88); }
:root[data-theme="light"] .tile-weather[data-sky="storm"] { background: linear-gradient(#6A7189, #2E3346); }
/* the Figma range card (drawn at 200px) at tile size. The temperature is deliberately
   larger than the other tiles' 56px values. */
.tile-weather .weather-art { position: absolute; right: calc(16.8 * var(--u)); top: calc(9.6 * var(--u)); width: calc(72 * var(--u)); height: calc(72 * var(--u)); filter: drop-shadow(0 calc(6 * var(--u)) calc(10 * var(--u)) rgb(0 0 26 / .25)); }
.wx-temp { position: absolute; left: calc(15.6 * var(--u)); top: calc(57.6 * var(--u)); font-size: calc(72 * var(--u)); line-height: 1.3; letter-spacing: 0; }
.wx-cond { position: absolute; left: calc(22 * var(--u)); right: calc(22 * var(--u)); top: calc(148.8 * var(--u)); margin: 0; font-size: calc(14.4 * var(--u)); line-height: 1.33; opacity: .78; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wx-range { position: absolute; left: calc(22 * var(--u)); right: calc(22 * var(--u)); top: calc(199.2 * var(--u)); translate: 0 -50%; display: grid; grid-template-columns: calc(33.6 * var(--u)) 1fr calc(33.6 * var(--u)); align-items: center; font-family: var(--font-mono); font-size: calc(12 * var(--u)); }
.wx-range > span:not(.wx-bar) { opacity: .6; }
.wx-range > span:last-child { text-align: right; }
.wx-bar { position: relative; height: calc(4.8 * var(--u)); border-radius: calc(2.4 * var(--u)); background: rgb(255 255 255 / .18); }
.wx-bar i { position: absolute; inset: 0 auto 0 0; width: max(calc(4.8 * var(--u)), var(--pos)); border-radius: inherit; background: linear-gradient(90deg, #8FD3FF, #FFD166); }
.wx-bar b { position: absolute; top: 50%; left: var(--pos); width: calc(14.4 * var(--u)); height: calc(14.4 * var(--u)); margin: calc(-7.2 * var(--u)) 0 0 calc(-7.2 * var(--u)); box-sizing: border-box; border-radius: 50%; background: #fff; border: calc(3 * var(--u)) solid rgb(30 42 74 / .9); }

.tile-awake { background: linear-gradient(#1D2614, #0D110A); }
.tile-awake .tile-label { color: #C8FF4D; opacity: 1; }
.awake-bars { display: grid; grid-template-columns: repeat(24, 1fr); gap: calc(3 * var(--u)); height: calc(26 * var(--u)); align-items: end; margin-top: calc(20 * var(--u)); }
.awake-bars i { display: block; height: calc(20 * var(--u)); border-radius: calc(2 * var(--u)); background: rgb(255 255 255 / .12); }
.awake-bars i.on { background: #C8FF4D; opacity: .85; }
.awake-bars i.now { height: calc(26 * var(--u)); opacity: 1; }
.awake-scale { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: calc(9 * var(--u)); opacity: .45; margin-top: calc(6 * var(--u)); }
:root[data-theme="light"] .tile-awake { background: linear-gradient(#D4F86A, #8FD82E); color: #17150F; --edge: rgb(23 21 15 / .06); }
:root[data-theme="light"] .tile-awake .tile-label { color: #17150F; opacity: .75; }
:root[data-theme="light"] .awake-bars i { background: rgb(23 21 15 / .14); }
:root[data-theme="light"] .awake-bars i.on { background: #17150F; opacity: .9; }

/* each face layer paints its own background (light / dark versions live in clock.js) */
.tile-clock { background: linear-gradient(#2A2A2E, #141416); cursor: pointer; }
:root[data-theme="light"] .tile-clock { background: linear-gradient(#FFFFFF, #F1EEE6); --edge: rgb(23 21 15 / .08); }
.tile-clock:focus-visible { outline: 2px solid var(--sync-on); outline-offset: 4px; }
.clock-face { position: absolute; inset: 0; }
/* switch: old markings fade out fast, then the new face fades in over the old background */
.clock-face.is-leaving svg { animation: face-out .12s ease-in forwards; }
.clock-face.is-entering { animation: face-in .26s .08s ease-out both; }
@keyframes face-in { from { opacity: 0; } }
@keyframes face-out { to { opacity: 0; } }
.clock-face svg { position: absolute; inset: 0; width: 100%; height: 100%; }
/* desktop: the faces slide out from under the tile, then sit above everything */
.face-menu {
  position: absolute; left: 50%; top: calc(100% + 14px); z-index: -1; translate: -50% -56px; scale: .94; opacity: 0; pointer-events: none;
  display: flex; gap: 12px; padding: 10px; border-radius: 99px; background: rgb(27 30 33 / .96); box-shadow: 0 0 0 1px rgb(255 255 255 / .08), 0 16px 34px -8px rgb(0 0 0 / .6);
  transition: translate .38s cubic-bezier(.16, 1, .3, 1), scale .38s cubic-bezier(.16, 1, .3, 1), opacity .22s ease-out;
}
.face-menu.is-open { translate: -50% 0; scale: 1; opacity: 1; pointer-events: auto; }
.face-menu::before { content: ''; position: absolute; left: -24px; right: -24px; bottom: 100%; height: 30px; }   /* bridge across the gap, so the hover holds */
@media (min-width: 1001px) { .fan .tile-slot.has-menu .tile { transform: translateY(-10px); } }
.face-menu:not(.is-open) { transition: opacity .2s ease-in, translate 0s .2s, scale 0s .2s; }
.face-menu button { position: relative; width: 36px; height: 36px; padding: 0; border: 0; border-radius: 50%; background: none; cursor: pointer; transition: scale .2s cubic-bezier(.16, 1, .3, 1); }
.face-menu button svg { width: 100%; height: 100%; display: block; border-radius: 50%; box-shadow: inset 0 0 0 1px rgb(255 255 255 / .12); }
.face-menu button:hover, .face-menu button:focus-visible { scale: 1.12; outline: none; }
.face-menu button:active { scale: .94; transition-duration: .08s; }   /* pressed: a quick dip under the finger */
.face-menu button[aria-checked="true"]::after { content: ''; position: absolute; inset: -4px; border-radius: 50%; box-shadow: 0 0 0 2px var(--text); animation: ring-in .28s cubic-bezier(.16, 1, .3, 1); }
@keyframes ring-in { from { opacity: 0; scale: .8; } }   /* the selected ring arriving on a newly picked face */
:root[data-theme="light"] .face-menu { background: rgb(255 255 255 / .97); box-shadow: 0 0 0 1px rgb(23 21 15 / .08), 0 16px 34px -10px rgb(23 21 15 / .3); }
.face-name { position: absolute; left: 50%; top: calc(100% + 10px); translate: -50% 0; font: 500 13px var(--font-sans); color: var(--text); white-space: nowrap; }
.tile-slot.has-menu { z-index: 10 !important; }

.tile-music { background: #222 center / cover no-repeat; cursor: pointer; }
.tile-music::after { content: ''; position: absolute; inset: 0; background: linear-gradient(rgb(0 0 0 / .3), transparent 28%, transparent 40%, rgb(0 0 0 / .85)); }
.tile-music .tile-inner { z-index: 1; }
/* nothing to show: a record at rest */
.tile-music.is-quiet { background: linear-gradient(#26262A, #121214); }
.music-quiet { position: absolute; inset: 0; width: 100%; height: 100%; }
.music-quiet g circle { stroke: rgb(255 255 255 / .07); stroke-width: 10; }
.music-quiet .label { fill: #1ED760; opacity: .5; }
.music-quiet .hole { fill: #141416; }
/* frosted pill: dark enough to read over white type on a cover, blurred so it still sits in the art */
.music-status {
  align-self: flex-start; display: inline-flex; align-items: center; gap: calc(7 * var(--u)); padding: calc(7 * var(--u)) calc(11 * var(--u)) calc(7 * var(--u)) calc(10 * var(--u)); border-radius: 999px;
  margin: calc(-1 * var(--u)) 0 0 calc(-10 * var(--u));   /* text sits on the same line as the Weather and Awake labels */
  background: rgb(14 14 14 / .7); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .14);   /* a hairline stays 1px at any size */
  -webkit-backdrop-filter: blur(calc(14 * var(--u))) saturate(1.5); backdrop-filter: blur(calc(14 * var(--u))) saturate(1.5);
  font-family: var(--font-mono); font-weight: 500; font-size: calc(10 * var(--u)); letter-spacing: .08em; text-transform: uppercase; color: #fff;
}
.music-status.is-preview { background: #1ED760; color: #0E100F; }
/* equaliser: four bars, each on its own rhythm so the pattern never visibly repeats */
.eq { display: inline-flex; gap: calc(2 * var(--u)); align-items: end; height: calc(11 * var(--u)); }
.eq i { width: calc(2.5 * var(--u)); height: 100%; border-radius: calc(1.5 * var(--u)); background: #1ED760; transform-origin: 50% 100%; animation: eq-a .95s ease-in-out infinite; }
.eq i:nth-child(2) { animation-name: eq-b; animation-duration: 1.15s; }
.eq i:nth-child(3) { animation-name: eq-c; animation-duration: .8s; }
.eq i:nth-child(4) { animation-name: eq-b; animation-duration: 1.35s; animation-delay: -.5s; }
@keyframes eq-a { 0%, 100% { transform: scaleY(.3); } 25% { transform: scaleY(.95); } 50% { transform: scaleY(.5); } 75% { transform: scaleY(1); } }
@keyframes eq-b { 0%, 100% { transform: scaleY(.85); } 30% { transform: scaleY(.25); } 60% { transform: scaleY(1); } 80% { transform: scaleY(.45); } }
@keyframes eq-c { 0%, 100% { transform: scaleY(.5); } 20% { transform: scaleY(1); } 45% { transform: scaleY(.3); } 70% { transform: scaleY(.8); } }
.music-meta { display: flex; align-items: end; justify-content: space-between; gap: calc(12 * var(--u)); }
.music-title { font-weight: 500; font-size: calc(20 * var(--u)); letter-spacing: -.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.music-artist { font-size: calc(13 * var(--u)); opacity: .75; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.music-text { min-width: 0; }
.play-btn { flex: none; width: calc(40 * var(--u)); height: calc(40 * var(--u)); border-radius: 50%; background: #fff; display: grid; place-items: center; transition: transform .2s var(--ease-out); }
.play-btn:hover { transform: scale(1.08); }
.play-btn svg { width: calc(18 * var(--u)); height: calc(18 * var(--u)); fill: #0E100F; }
.music-progress { position: absolute; left: 0; right: 0; bottom: 0; height: calc(4 * var(--u)); background: rgb(255 255 255 / .2); z-index: 2; display: none; }
.music-progress i { display: block; height: 100%; width: 0; background: #1ED760; }
.tile-music.is-previewing .music-progress { display: block; }

.tile-sun { background: linear-gradient(#20222A, #121318); --ring-night: #2A3566; --ring-golden: #FF8A3D; --ring-now-edge: #16181E; }
:root[data-theme="light"] .tile-sun { background: linear-gradient(#FFFFFF, #F1EEE6); color: #17150F; --edge: rgb(23 21 15 / .08); --ring-night: #DCE0EC; --ring-golden: #FF7A1A; --ring-now-edge: #F7F5EF; }
.sun-dial { position: absolute; inset: 0; width: 100%; height: 100%; }
.sun-dial circle:not(.ring-now) { fill: none; stroke-width: 15; }
.sun-dial .ring-night { stroke: var(--ring-night); }
.sun-dial .ring-day { stroke: url(#sunDay); }
.sun-dial .ring-golden { stroke: var(--ring-golden); }
.sun-dial .ring-now { fill: #fff; stroke: var(--ring-now-edge); stroke-width: 3; }
:root[data-theme="light"] .sun-dial .ring-now { fill: #17150F; }
.sun-dial .ring-mark { font: 500 8px var(--font-mono); text-anchor: middle; fill: currentColor; opacity: .45; }
.sun-centre { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.sun-centre .tile-label { color: #FFD166; opacity: 1; }
:root[data-theme="light"] .sun-centre .tile-label { color: #B85C00; }
.sun-centre .tile-value { font-size: calc(40 * var(--u)); margin-top: calc(8 * var(--u)); }
.sun-centre .tile-sub { margin-top: calc(4 * var(--u)); }

/* ── Cards ────────────────────────────────────────────────────── */
.grid {
  display: grid; gap: 20px; margin-top: 40px;
  grid-template-columns: repeat(12, 1fr);
}
.card {
  --edge: var(--hairline);
  position: relative; isolation: isolate;
  grid-column: span 3; min-height: 300px;
  container-type: inline-size;   /* inner layouts follow the card's width, not the window's */
  display: flex; flex-direction: column; justify-content: space-between; gap: 16px;
  padding: 28px; border-radius: var(--radius-card);
  background: var(--card); box-shadow: var(--card-shadow);
}
/* smoothed: the surface moves to a clipped layer behind the content (charts can still overflow) */
.card.sq { background: none; }
.card.sq::before { content: ''; position: absolute; inset: 0; z-index: -1; background: var(--card); clip-path: var(--sq-clip); }
.card.sq::after { clip-path: var(--sq-clip); }
.card-heart, .card-sleep, .card-activity { grid-column: span 4; min-height: 360px; }
.card-mobility { grid-column: 1 / -1; min-height: 0; }

.card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.card-title { display: flex; align-items: center; gap: 8px; font-family: var(--font-display); font-weight: 600; font-size: 18px; }
.card-title::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--dot, currentColor); flex: none; }
.card-meta { font-family: var(--font-mono); font-weight: 500; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-55); white-space: nowrap; }
.card-value { display: flex; align-items: baseline; gap: 8px; }
.card-value b { font-weight: 300; font-size: 56px; letter-spacing: -.04em; line-height: 1; white-space: nowrap; }
.card-heart .card-value b, .card-sleep .card-value b { font-size: 64px; }
.card-value > span:not(.pill) { font-size: 18px; color: var(--text-55); }
.card-note { font-size: 14px; color: var(--text-55); }
.pill { display: inline-flex; align-items: center; padding: 4px 10px; border-radius: 999px; font-family: var(--font-mono); font-weight: 500; font-size: 11px; letter-spacing: .04em; white-space: nowrap; }

.card-heart { --dot: var(--c-heart); }
.card-sleep { --dot: var(--c-stage-core); }
.card-activity { --dot: var(--c-ring-move); }
.card-cardio { --dot: var(--c-gauge-a); }
.card-hrv { --dot: var(--c-hrv); }
.card-steps { --dot: var(--c-steps); }
.card-spo2 { --dot: var(--c-spo2); }
.card-mobility { --dot: var(--text-55); }

/* sleep */
.stage-bar { display: flex; gap: 2px; height: 16px; margin-top: 20px; }
.stage-bar i { border-radius: 4px; }
.stage-bar i.is-empty { flex: 1; background: var(--neutral); }
.stage-legend { display: flex; justify-content: space-between; gap: 8px; }
.stage-legend div { display: grid; gap: 4px; }
.stage-legend small { display: flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-weight: 500; font-size: 10px; letter-spacing: .08em; color: var(--text-55); }
.stage-legend small::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--c); }
.stage-legend strong { font-weight: 500; font-size: 18px; white-space: nowrap; }
.score-pill { background: color-mix(in srgb, var(--c-sleep) 20%, transparent); color: var(--c-sleep); }

/* activity */
/* set like the other cards' meta labels ("8 DAYS", "LAST NIGHT") */
.day-switch { display: inline-flex; align-items: baseline; gap: 7px; font-family: var(--font-mono); font-weight: 500; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
.day-switch button { letter-spacing: inherit; text-transform: inherit; }
.day-switch span { color: rgb(var(--ink) / .22); }
.day-switch button { color: rgb(var(--ink) / .38); transition: color .2s; }
.day-switch button:hover:not(:disabled) { color: rgb(var(--ink) / .7); }
.day-switch button[aria-pressed="true"] { color: var(--text); }
.day-switch button:disabled { cursor: default; }
.day-switch button:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; border-radius: 4px; }

.activity-body { display: flex; align-items: center; gap: 28px; }
/* one day at a time (the switch picks it); a wide card shows both days side by side */
.activity-days { flex: 1; display: grid; gap: 28px; }
.activity-day { display: none; flex-direction: column; justify-content: space-between; gap: 16px; }
.activity-day.is-shown { display: flex; }
.activity-day-name { display: none; font-family: var(--font-mono); font-weight: 500; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-55); }
@container (min-width: 740px) {   /* the card's content box: two days need ~340px each */
  .activity-days { grid-template-columns: 1fr 1fr; }
  .activity-day { display: flex; }
  .activity-day + .activity-day { border-left: 1px solid var(--hairline); padding-left: 28px; }
  .activity-day-name { display: block; }
  .card-activity .day-switch { display: none; }
  .card-activity .rings { width: 150px; height: 150px; }
}

/* rings draw clockwise from 12 o'clock, outer to inner, when the card first scrolls
   into view and when the day changes (app.js toggles .rings-pending / .is-drawing) */
.ring-fill { stroke-dasharray: var(--len) 999px; }
.card-activity.rings-pending .ring-fill { stroke-dashoffset: var(--len); }
.card-activity.is-drawing .ring-fill { animation: ring-draw 1.4s cubic-bezier(.16, 1, .3, 1) both; }
.card-activity.is-drawing .ring-fill.r2 { animation-delay: .12s; }
.card-activity.is-drawing .ring-fill.r3 { animation-delay: .24s; }
@keyframes ring-draw { from { stroke-dashoffset: var(--len); } }
.rings { width: 180px; height: 180px; flex: none; }
.ring-stats .is-pending { font-size: 15px; font-weight: 500; color: var(--text-55); }
.ring-stats { display: grid; gap: 14px; }
.ring-stats small { display: block; font-family: var(--font-mono); font-weight: 500; font-size: 11px; letter-spacing: .08em; }
.ring-stats strong { font-weight: 500; font-size: 26px; letter-spacing: -.02em; }
.ring-stats span { font-size: 14px; color: var(--text-55); }

/* cardio */
.gauge { position: relative; width: 200px; height: 190px; margin-inline: auto; }
.gauge svg { position: absolute; inset: 0 0 auto; width: 200px; height: 200px; }
.gauge-value { position: absolute; left: 0; right: 0; top: 66px; text-align: center; }
.gauge-value b { display: block; font-weight: 300; font-size: 48px; letter-spacing: -.04em; line-height: 1; }
.gauge-value small { font-family: var(--font-mono); font-size: 9px; letter-spacing: .08em; color: var(--text-55); }
.measured-pill { align-self: flex-start; background: color-mix(in srgb, var(--c-spo2) 16%, transparent); color: var(--c-spo2); }
.hrv-pill { background: color-mix(in srgb, var(--c-hrv) 16%, transparent); color: var(--c-hrv); }
:root[data-theme="light"] .hrv-pill { color: var(--t-ex); }

/* mobility */
.mobility-grid { display: grid; grid-template-columns: repeat(4, 1fr); }
.mobility-grid > div { display: grid; gap: 10px; padding-inline: 24px; border-left: 1px solid var(--hairline); }
.mobility-grid > div:first-child { padding-left: 0; border-left: 0; }
.mobility-grid small { font-family: var(--font-mono); font-weight: 500; font-size: 10px; letter-spacing: .08em; color: var(--text-55); }
.mobility-grid b { font-weight: 300; font-size: 44px; letter-spacing: -.04em; line-height: 1; }
.mobility-grid .card-value > span { font-size: 15px; }
/* four columns need ~500px of content; narrower cards go 2×2 */
@container (max-width: 600px) {
  .mobility-grid { grid-template-columns: 1fr 1fr; row-gap: 28px; column-gap: 22px; }
  .mobility-grid > div, .mobility-grid > div:first-child { padding: 0; border: 0; }
  .mobility-grid b { font-size: 36px; }
}

/* ── Charts ───────────────────────────────────────────────────── */
.chart { width: 100%; height: auto; overflow: visible; display: block; }
/* chart hover/tap columns: a faint wash in the metric colour marks the day being read */
.chart .hit { fill: currentColor; opacity: 0; transition: opacity .15s; cursor: default; }
.chart .hit:hover { opacity: .07; }
.stage-bar i[data-tip] { cursor: default; }
.chart text { font-family: var(--font-mono); font-size: 10px; fill: var(--text-55); }
.chart text.today { font-weight: 500; }

/* ── Highlights + tooltips ───────────────────────────────────── */
.hl { text-decoration: none; }
.hl-sleep { color: var(--c-sleep); } .hl-move { color: var(--c-move); } .hl-listen { color: var(--c-listen); } .hl-music { color: var(--c-music); } .hl-heart { color: var(--c-heart); }
.hl-stale { color: var(--text-55); }
a.hl:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; border-radius: 6px; }

.tooltip {
  position: fixed; left: 0; top: 0; z-index: 50; pointer-events: none;
  display: grid; justify-items: center;
  opacity: 0; translate: 0 8px; transform-origin: 50% 0;
  transition: opacity .16s ease-out, translate .18s var(--ease-out);
}
.tooltip.is-on { opacity: 1; translate: 0 0; }
.tooltip.is-above { transform-origin: 50% 100%; }
.tooltip.is-above .tooltip-caret { order: 1; rotate: 180deg; }
.tooltip.is-leaving { opacity: 0; translate: 0 8px; transition-timing-function: ease-in; transition-duration: .14s; }
.tooltip-caret { width: 14px; height: 7px; background: var(--tip-bg); clip-path: path('M0 7 Q5 6 6.2 1.2 Q7 0 7.8 1.2 Q9 6 14 7 Z'); }
.tooltip-body { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 10px; padding: 12px 18px; border-radius: 15px; background: var(--tip-bg); color: #17150F; font-weight: 600; font-size: 19px; white-space: nowrap; box-shadow: 0 10px 24px -6px rgb(0 0 0 / .45); }
/* all one weight and one solid colour: dark on the bright dark-mode colours, white on the deeper light-mode ones */
.tooltip-body b { font-weight: inherit; }
.tooltip-body i { font-style: normal; }
.tooltip-body .sep { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
:root[data-theme="light"] .tooltip-body { color: #fff; }
.tooltip.is-small .tooltip-body { font-size: 14px; padding: 9px 14px; border-radius: 12px; }
.tooltip-body.sq { background: none; }
.tooltip-body.sq::before { content: ''; position: absolute; inset: 0; z-index: -1; background: var(--tip-bg); clip-path: var(--sq-clip); }

/* ── Demo state banner (preview builds, ?demo=…) ───────────────── */
.demo-banner {
  position: fixed; left: 50%; bottom: 20px; translate: -50% 0; z-index: 60;
  display: flex; align-items: center; gap: 12px; max-width: calc(100vw - 32px);
  padding: 8px 8px 8px 16px; border-radius: 999px; white-space: nowrap;
  background: #FF9F0A; color: #17150F; font-family: var(--font-mono); font-size: 12px; font-weight: 500;
  box-shadow: 0 10px 24px -6px rgb(0 0 0 / .45);
}
.demo-tag { text-transform: uppercase; letter-spacing: .08em; font-weight: 600; }
.demo-pick { min-width: 0; }
.demo-banner a { flex: none; }
.demo-pick select {
  appearance: none; -webkit-appearance: none; font: inherit; color: inherit; cursor: pointer;
  max-width: 100%; text-overflow: ellipsis;
  padding: 6px 28px 6px 12px; border: 0; border-radius: 999px;
  background: rgb(23 21 15 / .12) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2317150F' stroke-width='1.5'/%3E%3C/svg%3E") right 11px center no-repeat;
}
.demo-pick select:focus-visible, .demo-banner a:focus-visible { outline: 2px solid #17150F; outline-offset: 2px; }
.demo-banner a { color: inherit; padding-right: 8px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* narrow screens: full-width bar, the picker takes whatever room is left */
@media (max-width: 520px) {
  .demo-banner { width: calc(100vw - 32px); }
  .demo-pick { flex: 1; }
  .demo-pick select { width: 100%; }
}

/* ── 404 ──────────────────────────────────────────────────────── */
.not-found main { min-height: calc(100svh - 120px); display: flex; flex-direction: column; justify-content: center; gap: 40px; padding-bottom: 80px; }
.not-found .hero { padding-top: 0; }
.not-found-code { text-align: center; font-family: var(--font-mono); font-weight: 500; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-55); }
.not-found .headline { margin-top: 20px; text-align: center !important; }
.not-found .big-link { --w: 100%; align-self: center; margin-top: 0; font-size: clamp(36px, 7vw, 96px); }

/* ── Footer ───────────────────────────────────────────────────── */
.footer { margin-top: 72px; padding-top: 72px; border-top: 1px solid rgb(var(--ink) / .1); container-type: inline-size; }
.footer-label { font-family: var(--font-display); font-weight: 500; font-size: 28px; letter-spacing: -.02em; color: var(--text-70); }
.footer-sentence { font-family: var(--font-display); font-weight: 500; font-size: 40px; line-height: 1.2; letter-spacing: -.02em; color: var(--text-55); max-width: 1080px; margin-top: 20px; }
/* links are a weight up from the sentence, so they don't rely on colour alone */
.footer-sentence a { font-weight: 700; }
.footer-label-cta { margin-top: 68px; }
.big-link { display: flex; align-items: center; gap: .04em; margin-top: 20px; text-decoration: none; font-family: var(--font-display); font-weight: 800; font-size: clamp(36px, 11cqi, 140px); letter-spacing: -.05em; line-height: .95;
  /* the display cut at every size: with optical sizing the text widens as it shrinks, so it
     overflowed mid-size screens. Pinned, text + arrow is always ~8.97× the font size,
     and 11cqi fills the footer without passing it */
  font-variation-settings: "opsz" 96; }
.big-link-text { position: relative; transition: color .3s ease-out; }
/* hover: one gradient runs across the text and the arrow. app.js sets --w (text + arrow width)
   and the arrow's --ox (its offset), so both layers sample the same continuous gradient */
.big-link-text::after, .big-link-arrow::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--c-sleep), var(--c-listen), var(--c-move), var(--c-music), var(--c-sleep));
  background-size: calc(var(--w, 100%) * 2) 100%; background-position: calc(var(--ox, 0px) * -1) 0;
  opacity: 0; transition: opacity .3s ease-out;
}
.big-link-text::after {
  content: attr(data-text); right: -.12em;   /* room for the last glyph's overhang */
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.big-link-arrow {
  position: relative; width: .62em; height: .62em; flex: none; margin-top: .16em;
  background: currentColor;
  -webkit-mask: var(--arrow) center / contain no-repeat; mask: var(--arrow) center / contain no-repeat;
  transition: transform .4s var(--ease-out), background-color .3s ease-out;
}
:root { --arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath transform='rotate(-45 50 50)' d='M6 40 L56 45.5 L56 24 L96 50 L56 76 L56 54.5 L6 60 Z'/%3E%3C/svg%3E"); }
.big-link:is(:hover, :focus-visible) .big-link-text { color: transparent; }
.big-link:is(:hover, :focus-visible) .big-link-arrow { transform: translate(.04em, -.04em); background-color: transparent; }
.big-link:is(:hover, :focus-visible) :is(.big-link-text, .big-link-arrow)::after { opacity: 1; animation: flow 6s linear infinite; }
@keyframes flow { to { background-position: calc(var(--ox, 0px) * -1 - var(--w, 50%) * 2) 0; } }
.footer-bar { display: flex; justify-content: space-between; gap: 16px; margin-top: 20px; padding: 20px 0 48px; border-top: 1px solid var(--hairline); font-size: 13px; color: var(--text-55); }
.footer-links { display: flex; gap: 24px; }
.footer-links a { text-decoration: none; color: var(--text-70); font-weight: 500; }

/* ── Responsive ───────────────────────────────────────────────── */
@media (max-width: 1180px) {
  :root { --gutter: 40px; }
  .card { grid-column: span 6; }
  .card-heart, .card-sleep, .card-activity { grid-column: span 6; }
  .card-activity, .card-mobility { grid-column: 1 / -1; }   /* after .card, which would otherwise win */
  .fan { transform: scale(.82); transform-origin: 50% 0; margin-bottom: -70px; }
}

/* below ~1000px the fan's arc (~970px even at 82%) no longer fits: it becomes the swipe carousel */
@media (max-width: 1000px) {
  :root { --tile: 280px; }
  /* the fan becomes a swipeable carousel, same order, centred on the clock */
  .fan {
    transform: none; margin: 30px calc(var(--gutter) * -1) 0; height: auto;   /* the full gutter: tiles run off the screen edge, not a crop line inside it */
    display: flex; gap: 12px; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scrollbar-width: none;
    padding: 24px calc(50% + var(--gutter) - var(--tile) / 2) 44px;   /* % is of the parent, a gutter narrower each side: this centres the first and last cards too */
  }
  .fan::-webkit-scrollbar { display: none; }
  .fan.is-dragging { scroll-snap-type: none; cursor: grabbing; user-select: none; }
  @media (pointer: fine) { .fan { cursor: grab; } }
  .fan .tile-slot {
    position: relative; left: auto; top: auto; margin: 0; flex: none; scroll-snap-align: center;
    transform: translateY(var(--dip, 0px)) rotate(var(--tilt, 0deg)) scale(var(--s, 1));
    opacity: var(--o, 1); transition: none;
  }
  /* above every tile layer (tiles overlap the carousel's bottom padding, and rise
     through it on load); each button is a
     24px-tall target around the small visible dot */
  .fan-dots { position: relative; z-index: 6; display: flex; justify-content: center; margin-top: -33px; min-height: 24px; }   /* reserved before the buttons are added, so nothing shifts */
  .fan-dots button { display: grid; place-items: center; padding: 9px; }   /* 24px+ tap targets */
  .fan-dots button::before { content: ''; width: 6px; height: 6px; border-radius: 3px; background: rgb(var(--ink) / .3); transition: width .3s var(--ease-out), background-color .3s; }
  .fan-dots button:hover::before { background: rgb(var(--ink) / .55); }
  .fan-dots button[aria-current="true"]::before { width: 18px; background: rgb(var(--ink) / .9); }
  .fan-dots button:focus-visible { outline: 2px solid rgb(var(--ink) / .9); outline-offset: -4px; border-radius: 8px; }
}

@media (max-width: 720px) {
  :root { --gutter: 32px; }
  .topbar { padding-top: 20px; }
  .wordmark { font-size: 28px; }
  .topbar-actions { font-size: 17px; gap: 14px; }
  .sync-label { display: none; }           /* "10:13 AM · ☾ Lights off" */
  .theme-icon { width: 14px; height: 14px; }

  .hero { padding-top: 36px; }
  .headline { text-align: left; font-size: 46px; }
  .stage-legend strong { font-size: 16px; }

  .grid { gap: 12px; margin-top: 28px; }
  .card, .card-heart, .card-sleep, .card-activity, .card-mobility { grid-column: 1 / -1; min-height: 0; }
  .card-heart .card-value b, .card-sleep .card-value b { font-size: 56px; }
  .activity-body { gap: 22px; }
  .rings { width: 140px; height: 140px; }

  .footer { margin-top: 48px; padding-top: 48px; }
  .footer-label { font-size: 20px; }
  .footer-sentence { font-size: 26px; }
  .footer-label-cta { margin-top: 44px; }
  .big-link { font-size: clamp(24px, 11cqi, 40px); }
  .tooltip-body { font-size: 15px; }
}

/* ── Motion preferences ───────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; }
  .tooltip { translate: 0 0 !important; }
  .fan .tile-slot { --tilt: 0deg !important; --dip: 0px !important; }
  .reveal .headline:not(.is-ready), .reveal .hero:not(.is-in) .tile { opacity: 1; }
}
