/* World Teachers' Day — darjus.dev/teachers-day/
 *
 * A hand-written page, served as-is from public/, so nothing here is processed
 * by Vite or Tailwind. It keeps the site's one typeface, Outfit, and nothing
 * else of the site's palette: the ground is a deep indigo night (#0f1226) and
 * the colour is a full set rather than one accent — marigold, mint, sky and
 * blossom. That is a deliberate break from /programmers-day/'s single phosphor
 * amber on near-black, and from an earlier revision of THIS page that ran a
 * chalkboard green with one coral accent. The owner asked for a warmer, more
 * positive scheme on 2026-10-05 and this is it; see docs/teachers-day.md.
 *
 * Four hues sounds like a lot, and the rule that keeps it a system rather than
 * a bag of colours is: MARIGOLD IS THE ONLY ONE THAT CARRIES WEIGHT. It is the
 * hot colour — the eyebrow, the headline figure, the globe's spikes, the
 * primary button. Mint, sky and blossom only ever distinguish members of a set
 * from each other (the four school levels, the flowers in the garden, the
 * drifting glyphs). Give one of them a job marigold already has and the page
 * stops reading.
 *
 * Measured against the ground (#0f1226, relative luminance 0.0133), every text
 * token clears AA with room: marigold 10.9:1, mint 10.9:1, sky 8.7:1, blossom
 * 8.6:1, ink 14.8:1, muted 9.0:1, dim 5.4:1 (small uppercase labels only).
 * Nothing here sits on translucent glass over a photograph, so the site's
 * composited-glass table does not apply; the ground is flat and the numbers
 * above are the whole check.
 *
 * CSP: style-src 'self'. No inline <style>, no style="" in the markup. Every
 * per-element value (tilt angles, bar widths, tooltip position) is written by
 * page.js through the CSSOM, which style-src does not govern.
 *
 * WARNING, same trap as global.css: never write a path glob that ends in an
 * asterisk followed by a slash inside a comment in this file — it closes the
 * comment early and silently drops the next rule.
 */

@font-face {
  font-family: "Outfit";
  src: url("outfit.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --ground: #0f1226;
  --ink: #f2f3f8;
  --muted: #b9bfd6;
  --dim: #8f98b8;

  --sun: #ffc94a;
  --sun-hi: #ffe9a8;
  --sun-deep: #c8891a;
  --mint: #6ee7b7;
  --sky: #7cc4ff;
  --blossom: #ff9ecb;
  --on-sun: #231604;

  --line: rgb(242 243 248 / 0.12);
  --line-2: rgb(242 243 248 / 0.2);

  /* The strip along the bottom the garden grows in, reserved by `.page`'s
     bottom padding. It SCALES with viewport height, and has to: a fixed
     5.25rem pushed the 1440x900 layout 6px past one screen, which is the one
     thing this page is supposed to do. page.js measures the band at runtime
     and sizes every flower as a fraction of it, so this is the only place the
     number lives and nothing clips when it shrinks. */
  --garden-band: clamp(3.75rem, 8vh, 5.25rem);

  --font: "Outfit", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --pad-x: clamp(1.25rem, 4vw, 4rem);

  color-scheme: dark;
}

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

[hidden] {
  display: none !important;
}

html {
  background: var(--ground);
}

/* Four washes, one per accent, well below the strength where any of them
   could move a contrast ratio — they give the indigo somewhere to go rather
   than tinting the text that sits on it. */
body {
  position: relative; /* the containing block for .garden — see below */
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  overflow-x: hidden;
  background:
    radial-gradient(900px 560px at 86% -12%, rgb(255 201 74 / 0.1), transparent 62%),
    radial-gradient(760px 580px at -8% 102%, rgb(110 231 183 / 0.08), transparent 62%),
    radial-gradient(620px 520px at 104% 78%, rgb(255 158 203 / 0.07), transparent 64%),
    radial-gradient(700px 500px at 30% 112%, rgb(124 196 255 / 0.06), transparent 64%),
    var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* A soft vignette, and nothing else over the page. The chalk-dust smears and
   the CRT scanlines both belonged to schemes this one replaced. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 25;
  pointer-events: none;
  background: radial-gradient(ellipse at center, transparent 58%, rgb(4 5 14 / 0.52));
}

h1,
h2,
h3,
p,
dl,
dd,
ul,
ol {
  margin: 0;
}

h1,
h2,
h3 {
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.02;
  text-wrap: balance;
}

a {
  color: var(--mint);
  text-underline-offset: 3px;
}

a:hover {
  color: var(--sun-hi);
}

:focus-visible {
  outline: 2px solid var(--sun);
  outline-offset: 3px;
}

/* ---- Atmosphere canvases ------------------------------------------------- */

.field {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* The garden sits above the vignette as well as above the content, because a
   flower dimmed by the vignette looks like a mistake rather than depth. That
   is only safe because `--garden-band` keeps text out of the strip it grows
   in — the same arrangement `Foliage.astro` uses on the main site, where the
   Footer's padding reserves the band.
   It is ABSOLUTE, anchored to the bottom of the document, and that is the
   whole point. `fixed` was tried first and is wrong: it pins the flowers to
   the bottom of the SCREEN, so on any viewport the page scrolls in — every
   phone — they ride over whatever copy happens to be passing. Only the
   document's own bottom is guaranteed clear, because only that is what the
   padding reserves. `body` carries `position: relative` so `bottom: 0` means
   the end of the page rather than the end of the initial containing block. */
.garden {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: var(--garden-band);
  z-index: 30;
  pointer-events: none;
}

/* ---- Header -------------------------------------------------------------- */

.bar {
  position: absolute;
  inset: 0 0 auto;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: max(0.9rem, env(safe-area-inset-top)) var(--pad-x) 0.9rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  white-space: nowrap;
  line-height: 1;
  font-weight: 500;
  font-size: 1.125rem;
  letter-spacing: -0.025em;
  color: var(--ink);
  text-decoration: none;
}

.brand-mark {
  flex: none;
  width: 1.8em;
  height: 1.2em;
}

.wordmark-dot {
  color: inherit;
}

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: rgb(15 18 38 / 0.7);
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}

.icon-btn svg {
  width: 1.15rem;
  height: 1.15rem;
}

.icon-btn:hover {
  border-color: var(--sun);
  color: var(--sun-hi);
}

/* ---- Shared type and controls ------------------------------------------- */

.eyebrow {
  font: 600 0.75rem/1.2 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sun);
}

.lede {
  max-width: 36ch;
  font-size: clamp(1rem, 0.92rem + 0.3vw, 1.18rem);
  line-height: 1.45;
  color: var(--muted);
}

.btn {
  justify-self: start;
  font: 600 0.8rem/1 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.8rem 1.1rem;
  border-radius: 8px;
  border: 1px solid var(--line-2);
  background: rgb(242 243 248 / 0.05);
  color: var(--ink);
  cursor: pointer;
  transition:
    transform 0.15s,
    border-color 0.2s,
    background 0.2s;
}

.btn:hover {
  border-color: var(--sun);
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  padding: 0.95rem 1.4rem;
  border-color: var(--sun);
  background: linear-gradient(135deg, var(--sun-hi), var(--sun) 55%, #ffb01f);
  color: var(--on-sun);
  box-shadow:
    0 12px 30px -10px rgb(255 201 74 / 0.6),
    inset 0 1px 0 rgb(255 255 255 / 0.5);
}

.btn-primary:hover {
  border-color: var(--sun-hi);
  background: var(--sun-hi);
}

/* The press effect. A ring expands out of the button and the button recoils —
   pure CSS off a class, so there is no inline style for the CSP to object to,
   and `.btn-pop` is a real element rather than a pseudo so several can overlap
   and each can clean itself up on animationend.
   It is deliberately NOT a particle burst: that was the confetti this page
   replaced with a garden, and repeating it at the button would undo the point.

   The ring hangs off `.btn-wrap`, NOT off the button. A <button> is an
   unreliable containing block for an absolutely positioned child: inside one,
   `width: 100%` resolved against the text rather than the button, so the ring
   came out 106px wide on a 178px button. The wrapper is an ordinary inline-flex
   box and behaves. `inset` rather than width/height keeps it glued to the
   button's edges at any label length. */
.btn-wrap {
  position: relative;
  display: inline-flex;
}

.btn-pop {
  position: absolute;
  inset: -2px;
  border-radius: 10px;
  border: 2px solid var(--sun);
  pointer-events: none;
  /* NOT --ease. That token is ease-out-expo (0.16, 1, 0.3, 1), which is almost
     a step: the ring was down to 0.41 opacity by 103ms and invisible by 200ms,
     so the effect read as a flicker. A plain ease-out spends the 620ms where
     the eye can follow it. */
  animation: pop 620ms ease-out forwards;
}

@keyframes pop {
  from {
    opacity: 0.85;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(1.9);
  }
}

@keyframes recoil {
  0% {
    transform: scale(1);
  }
  30% {
    transform: scale(0.94);
  }
  100% {
    transform: scale(1);
  }
}

.btn-primary.is-thanked {
  animation: recoil 420ms var(--ease);
}

/* Settled, not greyed out. The press succeeded, so the button says so rather
   than looking broken — and it keeps the marigold it had, at a weight that no
   longer asks to be pressed. */
.btn-primary:disabled,
.btn-primary:disabled:hover {
  cursor: default;
  border-color: rgb(255 201 74 / 0.45);
  /* Longhands on purpose. The `background` shorthand here has to both clear
     .btn-primary's gradient and set a fill, and leaning on it for both is how
     the settled state ended up with no fill at all. Say each one. */
  background-image: none;
  background-color: rgb(255 201 74 / 0.12);
  color: var(--sun);
  box-shadow: none;
}

/* The label is its own element so page.js can swap the text without wiping
   the ring, which is a child of the button too. */
.btn-label {
  position: relative;
}

/* ---- Layout: one screen, three columns ---------------------------------- */

.page {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) minmax(0, 0.92fr);
  align-items: center;
  gap: clamp(1.25rem, 2.5vw, 2.5rem);
  max-width: 1600px;
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0 auto;
  padding: 4.25rem var(--pad-x) var(--garden-band);
}

/* ---- The congratulations ------------------------------------------------ */

.hello {
  display: grid;
  gap: 0.9rem;
}

.hello-copy {
  display: grid;
  gap: 0.85rem;
}

.hello-art {
  position: relative;
  justify-self: start;
}

.hello-art::before {
  content: "";
  position: absolute;
  inset: -10% -15%;
  z-index: -1;
  background: radial-gradient(closest-side, rgb(255 201 74 / 0.22), transparent);
  filter: blur(24px);
}

.hello-art-cap {
  margin-top: 0.3rem;
  font: 500 0.7rem/1.3 var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}

.hello-title {
  font-size: clamp(2.1rem, 1rem + 2.3vw, 3.4rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 0.98;
}

.facts {
  display: grid;
  max-width: 34rem;
}

.facts div {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  gap: 0.75rem;
  padding: 0.4rem 0;
  border-top: 1px solid var(--line);
}

.facts dt {
  padding-top: 0.15rem;
  font: 600 0.68rem/1.4 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}

.facts dd {
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--muted);
}

/* ---- The worldwide stat strip -------------------------------------------
   Three numbers that count up once, on load. The values are written by
   page.js; the markup is built there too. */

.stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem;
  max-width: 34rem;
  padding: 0;
  list-style: none;
}

.stats li {
  display: grid;
  gap: 0.15rem;
  padding: 0.6rem 0 0;
  border-top: 2px solid rgb(255 201 74 / 0.4);
}

.stat-v {
  font: 700 clamp(1.1rem, 0.95rem + 0.5vw, 1.45rem) / 1.05 var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--sun);
}

.stat-k {
  font-size: 0.72rem;
  line-height: 1.3;
  color: var(--muted);
}

.hello-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

.today {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  max-width: 100%;
  padding: 0.65rem 0.9rem;
  border-radius: 8px;
  border: 1px solid var(--line-2);
  background: rgb(19 23 48 / 0.6);
  font: 500 0.82rem/1.45 var(--mono);
  color: var(--ink);
}

.today-led {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dim);
}

.today.is-today {
  border-color: rgb(255 201 74 / 0.55);
}

.today.is-today .today-led {
  background: var(--sun);
  box-shadow: 0 0 10px var(--sun);
  animation: blink 1.4s steps(2, jump-none) infinite;
}

@keyframes blink {
  to {
    opacity: 0.25;
  }
}

/* The shared flower count under the button. It is deliberately quiet — the
   garden is the thing to look at, and this only says how big it is. */
.tally {
  font: 500 0.78rem/1.4 var(--mono);
  color: var(--dim);
}

.tally b {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--sun);
}

/* ---- 3D extruded "60" ---------------------------------------------------
   page.js clones the face into N layers stepped back along Z. The depth is in
   em, so the extrusion scales with the type. */

.x-wrap {
  perspective: 900px;
}

.x {
  position: relative;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  white-space: nowrap;
}

.x-face {
  position: relative;
  display: block;
  color: transparent;
  -webkit-background-clip: text;
  background-clip: text;
}

.x-layer {
  position: absolute;
  inset: 0;
  display: block;
  transform: translateZ(calc(var(--i) * -0.012em));
}

.x-hello {
  font-size: clamp(4.5rem, 1rem + 6vw, 8.5rem);
  font-weight: 900;
  line-height: 0.9;
  letter-spacing: -0.06em;
}

.x-hello .x-face {
  background-image: linear-gradient(180deg, #fff2cd 0%, var(--sun-hi) 24%, var(--sun) 62%, #f5942c 100%);
}

.x-hello .x-layer {
  color: #8a5a12;
  color: color-mix(in oklab, #1a1230 calc(var(--k) * 100%), var(--sun-deep));
}

/* ---- The globe ----------------------------------------------------------
   One metric, so there is no switch to style — an earlier revision had two
   and a toggle; see the note in teachermap.js. */

.globe-wrap {
  display: grid;
  justify-items: center;
  gap: 0.4rem;
}

.globe-stage {
  position: relative;
  width: min(100%, 58vh);
  aspect-ratio: 1;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  cursor: grab;
}

.globe-stage.is-grabbing {
  cursor: grabbing;
}

.globe {
  display: block;
  width: 100%;
  height: 100%;
}

.globe-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 1.1rem;
}

.globe-hint,
.legend {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font: 500 0.68rem var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}

/* The ramp is drawn from the same two endpoint colours page.js interpolates
   between, so the key cannot drift from the map. */
.legend-ramp {
  width: 4.5rem;
  height: 7px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--ramp-lo, #2b3157), var(--ramp-hi, #ffc94a));
}

.globe-tip {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  padding: 0.45rem 0.6rem;
  border-radius: 6px;
  border: 1px solid var(--line-2);
  background: rgb(19 23 48 / 0.92);
  font: 600 0.78rem var(--mono);
  white-space: nowrap;
  color: var(--ink);
  pointer-events: none;
  transform: translate(-50%, calc(-100% - 14px));
}

.globe-tip b {
  font-weight: 700;
  color: var(--sun);
}

/* ---- Side column: the card, the growth panel ---------------------------- */

.side {
  display: grid;
  align-content: center;
  gap: 0.75rem;
}

.side-head {
  display: grid;
  gap: 0.45rem;
}

.side-title {
  font-size: clamp(1.35rem, 1rem + 1vw, 1.9rem);
}

.country-card,
.growth-card {
  display: grid;
  align-content: start;
  gap: 0.55rem;
  padding: 0.95rem 1.05rem 1rem;
  border-radius: 14px;
  border: 1px solid var(--line-2);
  background: linear-gradient(165deg, rgb(28 32 64 / 0.92), rgb(13 16 36 / 0.94));
  box-shadow: 0 30px 60px -35px rgb(0 0 0 / 0.9);
}

.country-card .btn {
  padding: 0.55rem 0.8rem;
  font-size: 0.7rem;
}

.cc-k {
  font: 600 0.66rem/1.3 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}

.cc-name {
  font-size: clamp(1.25rem, 1.05rem + 0.6vw, 1.6rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.cc-big {
  display: grid;
  gap: 0.2rem;
  font: 700 clamp(1.45rem, 1.15rem + 1vw, 2.1rem) / 1.05 var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--sun);
}

.cc-big small {
  font: 500 0.78rem/1.4 var(--font);
  color: var(--muted);
}

.cc-row {
  display: grid;
  gap: 0.35rem;
}

.cc-text {
  font-size: 0.84rem;
  line-height: 1.45;
  color: var(--muted);
}

/* A key/value grid for the figures that are not the headline one. */
.cc-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.4rem 0.75rem;
}

.cc-cell {
  display: grid;
  gap: 0.1rem;
  padding-top: 0.35rem;
  border-top: 1px solid var(--line);
}

.cc-cell b {
  font: 700 0.95rem/1.1 var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--mint);
}

.cc-cell span {
  font-size: 0.7rem;
  line-height: 1.25;
  color: var(--dim);
}

/* The level split: one bar, primary against secondary. */
.split {
  display: flex;
  height: 8px;
  overflow: hidden;
  border-radius: 999px;
  background: rgb(242 243 248 / 0.08);
}

.split i {
  display: block;
  height: 100%;
  width: var(--w, 0%);
  transition: width 0.5s var(--ease);
}

.split-prm {
  background: var(--sun);
}

.split-sec {
  background: var(--sky);
}

.split-key {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.8rem;
  font: 500 0.7rem var(--mono);
  color: var(--muted);
}

.split-key i {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 0.35rem;
  border-radius: 2px;
  vertical-align: 0.05em;
}

.cc-src {
  font: 500 0.68rem/1.5 var(--mono);
  color: var(--dim);
}

.cc-src a {
  color: var(--muted);
}

/* ---- The growth panel ---------------------------------------------------
   Ten columns, one per year, grown from zero on load. The last column is the
   latest year and is the only one that carries a label, so the chart reads as
   one number arriving rather than ten competing for attention. */

.growth-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.growth-delta {
  font: 600 0.7rem var(--mono);
  color: var(--mint);
}

.bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 4rem;
  padding: 0;
  list-style: none;
}

.bars li {
  position: relative;
  flex: 1;
  height: 100%;
  display: flex;
  align-items: flex-end;
}

.bars i {
  display: block;
  width: 100%;
  height: var(--h, 0%);
  border-radius: 3px 3px 1px 1px;
  background: linear-gradient(180deg, rgb(255 201 74 / 0.8), rgb(255 201 74 / 0.3));
  transition: height 0.8s var(--ease);
}

.bars li:last-child i {
  background: linear-gradient(180deg, var(--sun-hi), var(--sun) 55%, rgb(255 201 74 / 0.45));
  box-shadow: 0 0 14px -2px rgb(255 201 74 / 0.6);
}

.bars-axis {
  display: flex;
  justify-content: space-between;
  font: 500 0.66rem var(--mono);
  color: var(--dim);
}

.bars-axis b {
  font-weight: 600;
  color: var(--sun);
}

/* The four school levels, each in its own hue — this is the one place the
   full set is used, and only to tell four members of a set apart. */
.levels {
  display: grid;
  gap: 0.3rem;
  padding: 0;
  list-style: none;
}

.level {
  display: grid;
  grid-template-columns: 0.55rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  color: var(--muted);
}

.level i {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 2px;
}

.level-pre i {
  background: var(--blossom);
}

.level-prm i {
  background: var(--sun);
}

.level-sec i {
  background: var(--sky);
}

.level-ter i {
  background: var(--mint);
}

.level b {
  font: 600 0.78rem var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* ---- The ranking -------------------------------------------------------- */

/* Under the globe, two columns: rank order reads down the first, then the
   second. */
.ranks {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(5, auto);
  grid-auto-flow: column;
  gap: 2px 0.9rem;
  width: 100%;
  max-width: 40rem;
  margin: 0.3rem 0 0;
  padding: 0;
  list-style: none;
}

.rank {
  position: relative;
  display: grid;
  grid-template-columns: 1.6rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.26rem 0.55rem;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.rank::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--w, 0%);
  border-radius: 6px;
  background: linear-gradient(90deg, rgb(255 201 74 / 0.2), rgb(255 201 74 / 0.04));
  pointer-events: none;
  transition: width 0.45s var(--ease);
}

.rank > span {
  position: relative;
}

.rank:hover {
  color: var(--ink);
}

.rank[aria-pressed="true"] {
  color: var(--ink);
  box-shadow: inset 0 0 0 1px rgb(255 201 74 / 0.55);
}

.rank-n {
  font: 600 0.72rem var(--mono);
  color: var(--dim);
}

.rank-name {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 0.9rem;
}

.rank-v {
  font: 600 0.8rem var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--sun);
}

.ranks-foot {
  grid-column: 1 / -1;
  grid-row: 6;
  padding: 0.4rem 0.55rem 0;
  font: 500 0.68rem/1.45 var(--mono);
  color: var(--dim);
}

/* ---- Responsive --------------------------------------------------------- */

/* Two columns: the congratulations becomes a banner across the top. */
@media (max-width: 1240px) {
  .page {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    align-content: center;
  }

  .hello {
    grid-column: 1 / -1;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: clamp(1.5rem, 4vw, 3rem);
  }

  .x-hello {
    font-size: clamp(5rem, 2rem + 8vw, 8.5rem);
  }
}

@media (max-width: 760px) {
  .page {
    grid-template-columns: minmax(0, 1fr);
    padding-top: 4.5rem;
  }

  .hello {
    grid-template-columns: minmax(0, 1fr);
  }

  .globe-stage {
    width: min(100%, 30rem);
  }

  .ranks {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-auto-flow: row;
  }

  .ranks-foot {
    grid-row: auto;
  }

  .facts div {
    grid-template-columns: 4.75rem minmax(0, 1fr);
  }

  .stats {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
  }

  .stats li {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: baseline;
    gap: 0.5rem;
    padding-top: 0.45rem;
  }
}

/* ---- Preferences -------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .today.is-today .today-led {
    animation: none;
  }

  /* page.js skips the ring entirely; the recoil is stopped here because it
     rides on a class that is added either way. */
  .btn-primary.is-thanked {
    animation: none;
  }

  .split i,
  .bars i,
  .rank::before {
    transition: none;
  }
}

/* No JavaScript: the congratulations and the facts still read. The globe, the
   counted stats and the panels that only exist through script are hidden
   rather than left as dead furniture. */
@media (scripting: none) {
  .globe-wrap,
  .growth-card,
  .stats,
  #fs,
  #celebrate,
  .field,
  .garden {
    display: none;
  }

  /* No garden, so nothing needs the band reserved for it. */
  .page {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    padding-bottom: 1.75rem;
  }
}
