/* ═══════════════════════════════════════════════════════════════════════════
   CIRRUS DROP · SOFT DEPTH

   The app is bright air, and everything in it is a cushion resting on another
   cushion. You are looking at a stack of physical cards; the game is the one
   window cut through them, and through that window it is dusk.

   Rules this sheet keeps, without exception:
     · Radius is 20 on a card, 16 on anything nested inside a card, and 999 on
       every single control. There is no other value and there is never a 0.
     · Elevation, not lines, does the separating. Shadows are multi-stop and
       blue-tinted, because a soft daylight never casts a grey shadow. A
       hairline appears only where two white planes actually touch.
     · Everything sits on something else. Page (air) carries a card (white),
       a card carries a tile (--card-2), a tile carries a control (pill).
       Repeated items inside a card are always tiles, never ruled rows.
     · Depth is the layout. Down the home stack the elevation drops off, so
       the cards recede the way the cloud decks do under the seed.
     · Type is rounded geometric, everywhere, no exceptions and no mono.
       Weight carries the hierarchy: 500 reads, 800 labels, 700 display.
     · Motion is one spring, 300ms. Press scales to .96. Tappable cards rise.
       Nothing slides in from off-screen and nothing loops except the air.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Written from JS by applySafeArea(). 0 outside Telegram fullscreen, so
     every utility that reads them collapses on its own. */
  --tg-safe-top: 0px;
  --tg-safe-bottom: 0px;

  /* Duplicated from brand.js so the splash paints correctly on frame one,
     before shell.js has stamped the palette onto <html>. */

  /* the air, and the cushions in it */
  --air:      #E7EDF8;
  --card:     #FFFFFF;
  --card-2:   #F1F5FC;
  --card-3:   #E2EAF7;
  --edge:     #E4EBF6;
  --ink-d:    #16203A;
  --ink-m:    #5A6784;
  --ink-l:    #8B97B4;
  --spot:     #5850E0;
  --spot-2:   #ECEAFE;
  --good:     #12855C;
  --good-2:   #DDF3E9;
  --warn:     #D93B5C;

  /* The window. These seven are read by game.js off the root element, so the
     sky the seed falls through can never drift away from the cards it is set
     into. They are the only dark values in the build. */
  --bg:       #0B1026;
  --tint:     #1A2247;
  --tint-2:   #2C3465;
  --ink:      #F2F5FF;
  --ink-3:    #8F9AC4;
  --accent:   #8C7CFF;
  --accent-d: #C6BDFF;

  /* Baloo 2 for figures and titles: pillowy, generous, round counters. Nunito
     underneath it for everything that is read rather than glanced at. ui-rounded
     stands in on iOS before the webfonts land, so the first frame is already
     soft rather than snapping from a grotesque. */
  --f-display: "Baloo 2", ui-rounded, "SF Pro Rounded", "Quicksand", system-ui, sans-serif;
  --f-text: "Nunito", ui-rounded, "SF Pro Rounded", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --r: 20px;              /* a card */
  --r-in: 16px;           /* a tile inside a card */
  --r-p: 999px;           /* every control, without exception */

  /* Three steps of lift. Multi-stop, blue, and each one a contact shadow plus
     a wide soft body: a single blur reads like a sticker, two read like an
     object with air under it. */
  --lift-1: 0 1px 2px rgba(24, 43, 84, .05), 0 4px 10px -3px rgba(24, 43, 84, .07);
  --lift-2: 0 1px 2px rgba(24, 43, 84, .05), 0 8px 18px -6px rgba(24, 43, 84, .10),
            0 26px 42px -22px rgba(24, 43, 84, .18);
  --lift-3: 0 2px 5px rgba(24, 43, 84, .07), 0 14px 30px -8px rgba(24, 43, 84, .15),
            0 40px 64px -28px rgba(24, 43, 84, .26);
  /* The cushion: a light catch along the top edge and a whisper of contact at
     the bottom. Applied inside the fill, so it survives on colour. */
  --gloss: inset 0 1px 0 rgba(255, 255, 255, .9);
  --press: inset 0 2px 5px rgba(24, 43, 84, .10), inset 0 1px 0 rgba(24, 43, 84, .05);

  --sp: 12px;             /* the rhythm, everywhere */
  --nav-h: 62px;
  --t: 300ms cubic-bezier(.34, 1.32, .5, 1);   /* the spring */
  --t-lin: 260ms cubic-bezier(.3, .8, .3, 1);  /* for width and colour, no bounce */
}

/* Every figure that changes on screen holds its column, so a fast-ticking
   altimeter never shoves the pills next to it sideways. */
.alt-n, .hud-n, .fig-n, .goal-v, .rw-sc, .rw-pos, .streak-n, .revive span,
.go-n, .cn-v {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

*, *::before, *::after { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Overlays set their own display, which outranks the UA rule for [hidden]. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--air);
  overscroll-behavior: none;
  -webkit-overflow-scrolling: touch;
}

body {
  font-family: var(--f-text);
  font-weight: 500;
  color: var(--ink-d);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, p, ol, ul { margin: 0; padding: 0; }
ol, ul { list-style: none; }
button, input { font: inherit; color: inherit; }
button { border: 0; background: none; padding: 0; cursor: pointer; text-align: left; }

/* The icon sprite itself never renders. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── icons ───────────────────────────────────────────────────────────────────
   One family: 2px strokes, round caps, round joins, and a generous radius
   built into every glyph so a corner is never a point. */

.ic {
  display: block; flex: none;
  width: 24px; height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ic-s { width: 18px; height: 18px; stroke-width: 2.1; }

/* The tinted rounded square an icon sits in. Always on a card, never loose. */
.pod {
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center;
  background: var(--spot-2);
  color: var(--spot);
  border-radius: var(--r-in);
}
.pod--sm { width: 32px; height: 32px; border-radius: 11px; }
.pod--sm .ic { width: 17px; height: 17px; }
.pod--lg { width: 60px; height: 60px; border-radius: 22px; }
.pod--lg .ic { width: 30px; height: 30px; }
/* On a --card-2 tile the quiet pod goes white, so it still sits on something. */
.pod--quiet { background: var(--card); color: var(--ink-m); box-shadow: var(--gloss), var(--lift-1); }

/* ── the one press gesture ───────────────────────────────────────────────── */

.spring { transition: transform var(--t), box-shadow var(--t), background var(--t-lin); }
.spring:active { transform: scale(.96); }
/* A card you can tap rises instead of shrinking: it is a physical thing being
   picked up, not a key being pushed down. */
.riser { transition: transform var(--t), box-shadow var(--t); }
.riser:active { transform: translateY(-3px) scale(1.008); box-shadow: var(--lift-3); }

/* ── controls: pill, filled, no border, a catch of light along the top ───── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 50px;
  padding: 0 22px;
  border-radius: var(--r-p);
  font-family: var(--f-text);
  font-size: 15px; font-weight: 800;
  letter-spacing: -0.005em;
  color: var(--ink-d);
  background: var(--card-2);
  box-shadow: var(--gloss);
}
.btn .ic { width: 20px; height: 20px; }
.btn--go {
  background: var(--spot);
  color: #fff;
  box-shadow: var(--gloss), 0 6px 14px -6px rgba(88, 80, 224, .70),
              0 16px 26px -14px rgba(88, 80, 224, .60);
}
.btn--quiet { background: var(--card-2); color: var(--ink-d); box-shadow: var(--gloss); }
.btn--ghost { background: transparent; color: var(--ink-m); box-shadow: none; }
.btn--sm { min-height: 40px; padding: 0 16px; font-size: 13.5px; gap: 7px; }
.btn--sm .ic { width: 17px; height: 17px; }
.btn--wide { width: 100%; }

/* Round icon control. Same pill rule, just square-ish in the box. */
.knob {
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-p);
  background: var(--card-2);
  color: var(--ink-m);
  box-shadow: var(--gloss);
}
.knob .ic { width: 21px; height: 21px; }

/* A small stated fact: goal state, shield, combo, rank. */
.tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  border-radius: var(--r-p);
  background: var(--card-2);
  color: var(--ink-m);
  font-size: 12px; font-weight: 800;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.tag .ic { width: 15px; height: 15px; }
.tag--spot { background: var(--spot-2); color: var(--spot); }
.tag.is-done { background: var(--good-2); color: var(--good); }

/* ── type roles ──────────────────────────────────────────────────────────── */

.k {
  display: block;
  font-size: 11px; font-weight: 800;
  letter-spacing: 0.10em; text-transform: uppercase;
  color: var(--ink-l);
}
.card-t {
  display: block;
  font-size: 16px; font-weight: 800; letter-spacing: -0.012em;
  color: var(--ink-d);
}
.card-s {
  display: block; font-style: normal;
  font-size: 13px; font-weight: 600; line-height: 1.4;
  color: var(--ink-m);
  margin-top: 2px;
}
.fine {
  font-size: 12.5px; font-weight: 600; line-height: 1.5;
  color: var(--ink-l);
  padding: 2px 8px 0;
}

/* ── the card, the tile ──────────────────────────────────────────────────── */

.card {
  background: var(--card);
  border-radius: var(--r);
  box-shadow: var(--lift-2);
  padding: 18px;
}
.card + .card, .card + .fine { margin-top: var(--sp); }

.card-h { display: flex; align-items: center; gap: 12px; }
.tx { flex: 1; min-width: 0; }

.tile {
  background: var(--card-2);
  border-radius: var(--r-in);
  padding: 12px;
}

/* ── splash ──────────────────────────────────────────────────────────────── */

#splash {
  position: fixed; inset: 0; z-index: 90;
  background: var(--air);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 6px;
  transition: opacity 240ms cubic-bezier(.3, .8, .3, 1);
}
#splash.out { opacity: 0; }
.sp-mark {
  position: relative;
  width: 92px; height: 92px;
  display: grid; place-items: center;
  background: var(--card);
  border-radius: 30px;
  box-shadow: var(--gloss), var(--lift-3);
  color: var(--spot);
  margin-bottom: 20px;
  animation: cushion 3.6s ease-in-out infinite;
}
.sp-mark .ic { width: 46px; height: 46px; }
/* The mark breathes the way a canopy does: it lifts, it settles. Opacity and
   transform only, so the shadow is never re-rasterised. */
@keyframes cushion {
  0%, 100% { transform: translateY(0) scale(1); }
  50%      { transform: translateY(-7px) scale(1.02); }
}
.sp-name {
  font-family: var(--f-display);
  font-size: 36px; font-weight: 700; line-height: 1; letter-spacing: -0.015em;
  animation: settle 520ms cubic-bezier(.34, 1.32, .5, 1) both;
}
.sp-sub {
  font-size: 13.5px; font-weight: 700; color: var(--ink-m);
  animation: settle 520ms cubic-bezier(.34, 1.32, .5, 1) 90ms both;
}

/* The one entrance in the app: it drops a few pixels and settles, like
   something being set down on the pile. */
@keyframes settle {
  from { opacity: 0; transform: translateY(-9px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

/* ── frame ───────────────────────────────────────────────────────────────── */

#app {
  position: fixed; inset: 0;
  display: flex; flex-direction: column;
  background: var(--air);
}

/* The air behind the cards: three very soft blooms over the ground, drifting
   once, slowly. This is the entire ambient motion budget of the app. */
#app::before {
  content: ""; position: absolute; inset: -18% -12%;
  pointer-events: none; z-index: 0;
  background:
    radial-gradient(54% 32% at 78% 4%,  rgba(255, 255, 255, .95), transparent 72%),
    radial-gradient(58% 30% at 14% 22%, rgba(160, 190, 255, .32), transparent 74%),
    radial-gradient(74% 36% at 52% 98%, rgba(140, 124, 255, .16), transparent 76%);
  animation: air 78s ease-in-out infinite alternate;
}
@keyframes air {
  from { transform: translate3d(-2%, -1.5%, 0) scale(1); }
  to   { transform: translate3d(2.5%, 2%, 0) scale(1.07); }
}
.crown, main, .navbar, .launch { position: relative; z-index: 1; }

/* ── crown: the floating brand capsule ───────────────────────────────────────
   Carries the fullscreen top inset for the whole app, then sets one white
   capsule on the air with the mark, the name and the rank you have reached. */
.crown {
  flex: none;
  padding-top: max(var(--tg-safe-top), env(safe-area-inset-top, 0px));
}
/* Fullscreen already reserves the chrome inset; trim a cosmetic sliver so the
   capsule does not float too low, floored at the inset itself. */
[data-fullscreen="1"] .crown {
  padding-top: max(var(--tg-safe-top),
    calc(max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) - 1.4vh));
}
.crown-in {
  display: flex; align-items: center; gap: 10px;
  margin: 10px 14px 4px;
  padding: 8px 10px 8px 8px;
  background: var(--card);
  border-radius: var(--r-p);
  box-shadow: var(--gloss), var(--lift-1);
}
.crown-mark {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-p);
  background: var(--spot-2);
  color: var(--spot);
}
.crown-mark .ic { width: 21px; height: 21px; }
.crown-name {
  font-family: var(--f-display);
  font-size: 18.5px; font-weight: 700; line-height: 1.1; letter-spacing: -0.012em;
}
.crown-rank { margin-left: auto; }

/* ── bottom nav: four tabs, standard mobile position ─────────────────────────
   A flex child of #app, so it pins under the scrolling content with a fixed
   height the floating Play pill can measure itself against. */
.navbar {
  flex: none;
  display: flex; align-items: stretch;
  gap: 4px;
  height: calc(var(--nav-h) + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  padding: 7px 10px;
  padding-bottom: calc(7px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  background: var(--card);
  border-radius: 24px 24px 0 0;
  box-shadow: 0 -1px 0 var(--edge), 0 -10px 26px -18px rgba(24, 43, 84, .34);
}
.navtab {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  border-radius: var(--r-p);
  color: var(--ink-l);
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.02em;
  transition: color var(--t-lin), background var(--t-lin);
}
.navtab .ic { width: 22px; height: 22px; }
.navtab.is-on { color: var(--spot); background: var(--spot-2); }

/* Play is the game and nothing else: the crown, the nav and the launch pill
   all step aside so the window owns the screen. */
[data-screen="play"] .crown,
[data-screen="play"] .navbar { display: none; }

main { flex: 1; min-height: 0; position: relative; }

.screen {
  position: absolute; inset: 0;
  display: none;
  flex-direction: column;
  overflow-y: auto;
  padding: 8px 14px 22px;
}
.screen.is-active { display: flex; }
.screen--play { overflow: hidden; padding: 0 12px 10px; }
/* Home clears the floating Play pill, which overlaps the scroll. */
.screen--home { padding-bottom: 96px; }

/* Each block of a screen settles into place as the screen becomes active.
   Toggling display re-runs it, so every tab change gets the same short
   cascade rather than a hard cut. */
.screen.is-active > * { animation: settle 340ms cubic-bezier(.34, 1.28, .5, 1) both; }
.screen.is-active > *:nth-child(1) { animation-delay: 0ms; }
.screen.is-active > *:nth-child(2) { animation-delay: 40ms; }
.screen.is-active > *:nth-child(3) { animation-delay: 80ms; }
.screen.is-active > *:nth-child(4) { animation-delay: 120ms; }
.screen.is-active > *:nth-child(n+5) { animation-delay: 150ms; }
/* The play screen is the exception: the canvas must be live on frame one. */
.screen--play > * { animation: none; }

/* ── the launch pill: Play, floating over the nav ────────────────────────────
   Absolutely placed inside #app rather than inside the scroll, so it stays put
   while the card stack moves under it. left/right 0 with auto margins centres
   it without a transform, which leaves the press scale free. */
.launch {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(14px + var(--nav-h) + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  margin-inline: auto;
  width: max-content;
  z-index: 6;
  display: flex; align-items: center; gap: 12px;
  min-height: 58px;
  padding: 0 12px 0 26px;
  border-radius: var(--r-p);
  background: var(--spot);
  color: #fff;
  box-shadow: var(--gloss),
              0 8px 16px -6px rgba(88, 80, 224, .55),
              0 20px 34px -14px rgba(88, 80, 224, .50),
              0 2px 6px rgba(24, 43, 84, .14);
}
.launch-tx { display: flex; flex-direction: column; line-height: 1.15; }
.launch-tx b { font-family: var(--f-display); font-size: 20px; font-weight: 700; letter-spacing: -0.01em; }
.launch-tx i { font-style: normal; font-size: 11.5px; font-weight: 700; opacity: .82; }
.launch-ic {
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-p);
  background: rgba(255, 255, 255, .18);
}
.launch-ic .ic { width: 22px; height: 22px; }
/* Only Home offers it; every other screen has its own job. */
.launch { display: none; }
[data-screen="home"] .launch { display: flex; }

/* ═════════════════════ HOME ═════════════════════════════════════════════════
   A stack of cushions. The top card carries the most lift and each one below
   carries less, so the stack recedes the way the cloud decks do underneath a
   falling seed. That is the whole ornament budget: there is no illustration. */

.deck-1 { box-shadow: var(--lift-3); }
.deck-2 { box-shadow: var(--lift-2); }
.deck-3 { box-shadow: var(--lift-1); }

/* ── hero: the deepest descent ───────────────────────────────────────────── */

.alt { padding: 20px 20px 16px; }
.alt-top { display: flex; align-items: flex-start; gap: 12px; }
.alt-top .k { margin-top: 3px; }
.alt-fig {
  display: flex; align-items: baseline; gap: 8px;
  margin: 2px 0 0;
}
.alt-n {
  font-family: var(--f-display);
  font-size: clamp(56px, 19vw, 70px);
  font-weight: 700; line-height: 1; letter-spacing: -0.03em;
  color: var(--ink-d);
}
.alt-u { font-size: 19px; font-weight: 800; color: var(--ink-l); }
.alt-sub { font-size: 13px; font-weight: 700; color: var(--ink-m); margin-top: 2px; }
/* The plain sentence, folded into the hero instead of floating above it. */
.alt-say {
  margin-top: 14px;
  font-size: 13.5px; font-weight: 600; line-height: 1.5;
  color: var(--ink-m);
}
.alt-say b { color: var(--ink-d); font-weight: 800; }

/* ── canopy budget: the module only a parachute game has ─────────────────────
   Holding is a loan. Two proportional tracks show the exact terms: a full
   canopy buys 2.5 seconds open, and buying it back costs 3.5 seconds of
   falling. Both figures come straight off game.js. */

.cn-bars { display: flex; gap: 8px; margin-top: 16px; }
.cn-bar { min-width: 0; }
.cn-bar--open  { flex: 25; }
.cn-bar--fill  { flex: 35; }
.cn-track {
  height: 14px;
  border-radius: var(--r-p);
  background: var(--card-2);
  box-shadow: var(--press);
}
.cn-bar--open .cn-track {
  background: linear-gradient(90deg, var(--spot), #7B72F0);
  box-shadow: var(--gloss);
}
.cn-meta { display: flex; align-items: baseline; gap: 5px; margin-top: 8px; }
.cn-v {
  font-family: var(--f-display);
  font-size: 19px; font-weight: 700; line-height: 1; letter-spacing: -0.01em;
}
.cn-bar--open .cn-v { color: var(--spot); }
.cn-l { font-size: 11.5px; font-weight: 700; color: var(--ink-l); }
.cn-note {
  margin-top: 14px;
  font-size: 12.5px; font-weight: 600; line-height: 1.45;
  color: var(--ink-m);
}
.cn-note b { color: var(--ink-d); font-weight: 800; }

/* ── streak, and the three small counts ──────────────────────────────────── */

.streak-top { display: flex; align-items: center; gap: 12px; }
.streak-n {
  font-family: var(--f-display);
  font-size: 34px; font-weight: 700; line-height: 1; letter-spacing: -0.02em;
  margin-left: auto;
}
.figs { display: flex; gap: 8px; margin-top: 14px; }
.fig { flex: 1; text-align: center; padding: 11px 4px; }
.fig-n {
  display: block;
  font-family: var(--f-display);
  font-size: 22px; font-weight: 700; line-height: 1;
  color: var(--ink-d);
}
.fig-l {
  display: block;
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.04em;
  color: var(--ink-l);
  margin-top: 4px;
}

/* ── daily goal ──────────────────────────────────────────────────────────── */

.goal-top { display: flex; align-items: center; gap: 12px; }
.goal-l { flex: 1; min-width: 0; font-size: 15px; font-weight: 800; letter-spacing: -0.01em; }
.goal-track {
  height: 12px;
  margin-top: 14px;
  border-radius: var(--r-p);
  background: var(--card-2);
  box-shadow: var(--press);
  overflow: hidden;
}
.goal-track > i {
  display: block; height: 100%; width: 0;
  border-radius: var(--r-p);
  background: linear-gradient(90deg, var(--spot), #8C7CFF);
  box-shadow: var(--gloss);
  transition: width var(--t-lin), background var(--t-lin);
}
.goal-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 9px; }
.goal-v { font-family: var(--f-display); font-size: 15px; font-weight: 700; color: var(--ink-d); }
.goal-hint { font-size: 11.5px; font-weight: 700; color: var(--ink-l); }

/* ── the boost offer, one element so it vanishes whole ───────────────────── */

.offer { display: flex; align-items: center; gap: 12px; padding: 14px; }
.offer-tx { flex: 1; min-width: 0; }
.offer-tx i { display: block; font-style: normal; font-size: 12px; font-weight: 700; color: var(--ink-l); margin-top: 2px; }
.offer-tx i span:empty { display: none; }

/* ═════════════════════ PLAY ═════════════════════════════════════════════════
   A white readout bar and a canopy gauge, both cushions, sitting on the air.
   Under them, the only dark thing in the whole app: the window. */

.deckbar {
  flex: none;
  display: flex; align-items: center; gap: 10px;
  margin: 8px 0 var(--sp);
  margin-top: calc(max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) + 8px);
  padding: 8px;
  background: var(--card);
  border-radius: var(--r-p);
  box-shadow: var(--gloss), var(--lift-2);
}
.hud-read { display: flex; align-items: baseline; gap: 6px; margin-right: auto; padding-left: 4px; }
.hud-n {
  font-family: var(--f-display);
  font-size: 32px; font-weight: 700; line-height: 1; letter-spacing: -0.025em;
}
.hud-u { font-size: 12px; font-weight: 800; color: var(--ink-l); }

/* Combo: a clean centre through a gap. It arrives with a small spring rather
   than a fade, so it registers in peripheral vision while you are falling. */
.combo {
  background: var(--spot); color: #fff;
  box-shadow: var(--gloss), 0 4px 12px -4px rgba(88, 80, 224, .7);
  font-size: 13px;
  opacity: 0; transform: scale(.7);
  transition: opacity var(--t-lin), transform var(--t);
}
.combo.is-on { opacity: 1; transform: scale(1); }
.combo:empty { display: none; }
.shield { background: var(--good-2); color: var(--good); }

/* The canopy gauge: the one resource in the game, so it is the one gauge. */
.gauge {
  flex: none;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px;
  margin-bottom: var(--sp);
  background: var(--card);
  border-radius: var(--r-p);
  box-shadow: var(--gloss), var(--lift-1);
}
.gauge .k { flex: none; }
.gauge-track {
  flex: 1;
  height: 12px;
  border-radius: var(--r-p);
  background: var(--card-3);
  box-shadow: var(--press);
  overflow: hidden;
}
.gauge-track > i {
  display: block; height: 100%; width: 100%;
  border-radius: var(--r-p);
  background: linear-gradient(90deg, var(--spot), #8C7CFF);
  box-shadow: var(--gloss);
  transition: width 120ms linear, background var(--t-lin);
}
/* Below a quarter the canopy is about to collapse, and the gauge says so. */
.gauge-track > i.is-low { background: linear-gradient(90deg, var(--warn), #F2647F); }

/* ── the window ──────────────────────────────────────────────────────────── */

.window {
  flex: 1; min-height: 0; position: relative;
  border-radius: var(--r);
  background: var(--bg);
  box-shadow: 0 2px 6px rgba(24, 43, 84, .14),
              0 18px 34px -14px rgba(24, 43, 84, .38),
              0 44px 70px -34px rgba(11, 16, 38, .55);
  overflow: hidden;
}
#stage { display: block; width: 100%; height: 100%; touch-action: none; }

/* The pre-round panel: one white cushion set down on the sky, with the sky
   still drawing behind it. The whole panel is the start target. */
.brief {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  overflow-y: auto;
  /* Barely a veil. The sky is already drawing behind it and that first glimpse
     of a seed under a half-open canopy is the whole hook. */
  background: rgba(11, 16, 38, .30);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  animation: settle 320ms cubic-bezier(.34, 1.28, .5, 1) both;
}
.brief-card {
  width: 100%; max-width: 320px;
  background: var(--card);
  border-radius: var(--r);
  box-shadow: var(--gloss), var(--lift-3);
  padding: 18px;
}
.brief-t {
  display: block; text-align: center;
  font-family: var(--f-display);
  font-size: 23px; font-weight: 700; line-height: 1.15; letter-spacing: -0.02em;
  margin: 12px 0 4px;
}
.brief-card .pod--lg { margin: 0 auto; }
.brief-s { text-align: center; font-size: 13px; font-weight: 600; color: var(--ink-m); margin-bottom: 16px; }
.steps { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.step { display: flex; align-items: flex-start; gap: 11px; }
.step .pod { margin-top: 1px; }
.step-tx { min-width: 0; }
.step-tx b { display: block; font-size: 14px; font-weight: 800; letter-spacing: -0.01em; }
.step-tx i { display: block; font-style: normal; font-size: 12.5px; font-weight: 600; line-height: 1.35; color: var(--ink-m); margin-top: 1px; }

/* ═════════════════════ RANK ═════════════════════════════════════════════════ */

/* The scope switch: two pills inside one recessed capsule. */
.seg {
  display: flex; gap: 4px;
  padding: 4px;
  background: var(--card-3);
  border-radius: var(--r-p);
  box-shadow: var(--press);
}
.seg-btn {
  flex: 1;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 40px;
  border-radius: var(--r-p);
  color: var(--ink-m);
  font-size: 13.5px; font-weight: 800;
  transition: background var(--t-lin), color var(--t-lin), box-shadow var(--t-lin);
}
.seg-btn.is-on { background: var(--card); color: var(--spot); box-shadow: var(--gloss), var(--lift-1); }

.board { padding: 10px; }
/* Rows are tiles, because everything in here sits on something. */
.rw {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px 9px 9px;
  border-radius: var(--r-in);
  background: var(--card-2);
}
.rw + .rw { margin-top: 6px; }
.rw-pos {
  width: 22px; flex: none; text-align: center;
  font-size: 13px; font-weight: 800;
  color: var(--ink-l);
}
.rw-av {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-p);
  /* shell.js writes --h per name, so the pastels are stable per player. */
  background: hsl(var(--h, 240) 72% 88%);
  color: hsl(var(--h, 240) 46% 34%);
  font-size: 15px; font-weight: 800;
  box-shadow: var(--gloss);
}
.rw-nm { flex: 1; min-width: 0; font-size: 14.5px; font-weight: 700; letter-spacing: -0.01em;
         overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rw-sc { font-family: var(--f-display); font-size: 16px; font-weight: 700; color: var(--ink-d); }
.rw--top .rw-pos { color: var(--spot); }
/* Your row lifts clean out of the stack. */
.rw--me {
  background: var(--card);
  box-shadow: var(--gloss), var(--lift-2);
}
.rw--me .rw-nm { font-weight: 800; }
.rw--me .rw-sc { color: var(--spot); }

/* ═════════════════════ MORE ═════════════════════════════════════════════════ */

.rows { display: flex; flex-direction: column; gap: 6px; padding: 10px; }
.row {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 9px 14px 9px 9px;
  border-radius: var(--r-in);
  background: var(--card-2);
  transition: background var(--t-lin);
}
/* :not(.pod) matters: the icon pod is a span too, and must keep its flex:none. */
.row > span:not(.pod) { flex: 1; min-width: 0; font-size: 14.5px; font-weight: 700; }
.row:active { background: var(--card-3); }
.row .chev { width: 19px; height: 19px; flex: none; color: var(--ink-l); }

/* The switch: a pill, a white knob with real contact shadow, nothing else. */
.sw {
  appearance: none; -webkit-appearance: none;
  position: relative; flex: none;
  width: 48px; height: 29px; margin: 0;
  border-radius: var(--r-p);
  background: var(--card-3);
  box-shadow: var(--press);
  transition: background var(--t-lin);
}
.sw::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 23px; height: 23px;
  border-radius: var(--r-p);
  background: #fff;
  box-shadow: 0 1px 2px rgba(24, 43, 84, .18), 0 3px 6px -1px rgba(24, 43, 84, .22);
  transition: transform var(--t);
}
.sw:checked { background: var(--spot); }
.sw:checked::after { transform: translateX(19px); }

/* A section label sitting on the air, above the card it names. */
.sect { margin: 18px 0 8px; padding: 0 8px; }
.screen > .sect:first-child { margin-top: 4px; }

/* ═════════════════════ OVERLAYS ═════════════════════════════════════════════ */

.scrim { position: fixed; inset: 0; z-index: 40; background: rgba(16, 26, 52, .48); }

.sheet {
  position: fixed; z-index: 50;
  left: 12px; right: 12px;
  bottom: calc(12px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  background: var(--card);
  border-radius: var(--r);
  box-shadow: var(--gloss), var(--lift-3);
  display: flex; flex-direction: column;
  max-height: calc(100dvh - max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) - 26px);
  /* Deliberately NOT animated. A sheet that slides up from below sits, for the
     length of the animation, with its own Close button under the fold, and if
     a client throttles animations it stays there. The sheet just appears. */
}
.sheet-head {
  flex: none;
  display: flex; align-items: center; gap: 12px;
  padding: 14px 14px 12px;
}
.sheet-head b {
  flex: 1; min-width: 0;
  font-family: var(--f-display);
  font-size: 20px; font-weight: 700; letter-spacing: -0.015em;
}
.sheet-body {
  flex: 1; min-height: 0;
  overflow-y: auto;
  margin: 0 12px;
  padding: 14px;
  background: var(--card-2);
  border-radius: var(--r-in);
  font-size: 14px; font-weight: 600; line-height: 1.55;
  color: var(--ink-m);
}
.sheet-body p { margin: 0 0 12px; }
.sheet-body ul { margin: 0 0 12px; }
.sheet-body li { position: relative; padding-left: 20px; margin-bottom: 10px; }
.sheet-body li::before {
  content: ""; position: absolute; left: 2px; top: 8px;
  width: 8px; height: 8px;
  border-radius: var(--r-p);
  background: var(--spot);
}
.sheet-body b { font-weight: 800; color: var(--ink-d); }
.sheet-foot { flex: none; padding: 12px; }

.modal {
  position: fixed; inset: 0; z-index: 55;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  pointer-events: none;
}
.modal-card {
  pointer-events: auto;
  width: 100%; max-width: 330px;
  background: var(--card);
  border-radius: var(--r);
  box-shadow: var(--gloss), var(--lift-3);
  padding: 22px 18px 18px;
  text-align: center;
  animation: settle 300ms cubic-bezier(.34, 1.32, .5, 1);
}
.modal-card .pod--lg { margin: 0 auto 12px; }
.modal-t {
  display: block;
  font-family: var(--f-display);
  font-size: 23px; font-weight: 700; line-height: 1.2; letter-spacing: -0.02em;
}
.modal-s { font-size: 13.5px; font-weight: 600; color: var(--ink-m); margin-top: 6px; }
.go-n {
  font-family: var(--f-display);
  font-size: 58px; font-weight: 700; line-height: 1; letter-spacing: -0.03em;
  margin: 10px 0 2px;
}
.modal-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 16px; }
.modal-btns .btn { padding: 0 8px; font-size: 13.5px; gap: 7px; min-height: 48px; }
.modal-btns .ic { width: 18px; height: 18px; }
.modal .btn--wide { margin-top: 12px; }
/* The ad route prints its terms before the tap, with the free route under it. */
.ad-tx { display: block; text-align: left; line-height: 1.35; }
.ad-tx b { display: block; font-size: 14px; font-weight: 800; }
.ad-tx i { display: block; font-style: normal; font-size: 11.5px; font-weight: 700; color: var(--ink-l); margin-top: 2px; }
.ad-tx i:empty { display: none; }
.btn--ad { min-height: 62px; justify-content: flex-start; text-align: left; padding: 0 18px; }

.revive {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  pointer-events: none;
}
.revive span {
  display: grid; place-items: center;
  width: 138px; height: 138px;
  background: var(--card);
  border-radius: var(--r-p);
  box-shadow: var(--gloss), var(--lift-3);
  font-family: var(--f-display);
  font-size: 66px; font-weight: 700; color: var(--spot);
  animation: bounce 300ms cubic-bezier(.34, 1.4, .5, 1);
}
@keyframes bounce { from { transform: scale(.8); opacity: 0; } to { transform: scale(1); opacity: 1; } }

.toast {
  position: fixed; z-index: 70;
  left: 16px; right: 16px;
  bottom: calc(104px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  background: var(--card);
  border-radius: var(--r-p);
  box-shadow: var(--gloss), var(--lift-3);
  padding: 14px 20px;
  font-size: 13.5px; font-weight: 700;
  text-align: center;
}

/* ── reduce motion: kill all of it ───────────────────────────────────────── */

[data-reduce-motion="1"] *,
[data-reduce-motion="1"] *::before,
[data-reduce-motion="1"] *::after {
  animation: none !important;
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* Short phones: the two biggest figures give first, then the padding. */
@media (max-height: 690px) {
  .alt-n { font-size: 52px; }
  .go-n { font-size: 48px; }
  .card { padding: 15px; }
  .alt { padding: 16px 16px 14px; }
  .alt-say { margin-top: 11px; }
  .sp-mark { width: 78px; height: 78px; margin-bottom: 14px; }
}
