/* Atlas — the front door.
 *
 * Read this before adding anything:
 *
 * 1. THE GROUND AND THE MOTION ARE MEASURED, NOT INVENTED. The radial
 *    gradient, the arc field's geometry and the ten-second draw are taken
 *    off agen.cy with a probe (the capture is in the session scratchpad),
 *    because Yusef asked for that background by name. What is ours is the
 *    artwork itself and the palette: the arcs are generated by
 *    `public/orrery.js`, and every colour below comes from the Atlas
 *    app's own tokens so the page and the product are lit the same way.
 *    The artwork has been three things: an abstract arc field copied from
 *    the reference, then the A of A.T.L.A.S in nested neon tubes, and
 *    since 2026-09-12 an orrery on a canvas (`public/orrery.js`). The
 *    ground survived all three; only the thing on it changed.
 *
 * 2. THE TYPE DIALECT IS ATLAS'S, NOT AGENCY'S. agen.cy sets every node
 *    at `letter-spacing: normal` and `text-transform: none`; all 44 of
 *    them, measured. Atlas is built the other way, on tracked-out caps
 *    (CONTROLS, DESK, A.T.L.A.S, ENTER EXECUTIVE BRIEFING), so labels
 *    here are tracked caps and running text is not. Copying their
 *    restraint is the point; copying their typography would make this
 *    page stop looking like the thing it is a door to.
 *
 * 3. NO BUILD STEP. Static HTML, this file, four woff2 files and nothing
 *    else, the same shape as `os/apps/site`. Serve the `public/` folder.
 */

@font-face { font-family: Ubuntu; src: url("/fonts/ubuntu-300.woff2") format("woff2"); font-weight: 300; font-display: swap; }
@font-face { font-family: Ubuntu; src: url("/fonts/ubuntu-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: Ubuntu; src: url("/fonts/ubuntu-500.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: Ubuntu; src: url("/fonts/ubuntu-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }

:root {
  /* the Atlas app's own tokens (os/apps/atlas/src/chrome/chrome.css) */
  --navy: #070b14;
  --bloom: #2e303f;          /* the warm end of the ground's radial */
  --ink: #eaf6fb;
  --ink-dim: #94a3b8;
  --muted: #64748b;
  --holo: #7fd8f7;
  --glass: rgba(20, 38, 62, 0.42);
  --rim: rgba(120, 205, 235, 0.28);
  --line: rgba(148, 163, 184, 0.16);

  --shell: 1180px;
  --stack: clamp(64px, 9vw, 132px);   /* the rhythm between sections */
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  min-height: 100%;
  font: 400 16px/1.6 Ubuntu, system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--ink);
  background-color: var(--navy);
  /* ⚠ THE GROUND, exactly as measured: one radial bloom pinned near the
     top right, falling to the navy by halfway. agen.cy's far stop is
     rgb(7,10,19) and the Atlas app's --navy is #070b14 — one point of
     blue apart, which is why this needed no reconciling. */
  background-image: radial-gradient(at 90% 100px, var(--bloom), var(--navy) 50%);
  /* NOT `background-attachment: fixed`: the reference does not use it, it
     repaints badly under a full-page capture, and it janks on iOS. */
  overflow-x: hidden;
}

a { color: var(--holo); text-decoration: none; transition: color .25s; }
a:hover { color: #b9ecfb; }
:focus-visible { outline: 2px solid var(--holo); outline-offset: 3px; border-radius: 4px; }

.shell { width: 100%; max-width: var(--shell); margin: 0 auto; padding: 0 28px; }

/* ——— the sky ————————————————————————————————————————————————————
   The orrery's canvas. It replaced the nested neon A on 2026-09-12 and
   keeps that envelope exactly, so nothing else on the page moved: one
   screen tall, clipped, behind everything, and untouchable.

   ⚠ THE CANVAS IS SIZED IN CSS AND THE SCRIPT READS IT BACK. Do not put
   width/height attributes on the element — /orrery.js measures the box
   and sets the backing store at the device pixel ratio itself. Giving it
   CSS dimensions AND attributes is how a canvas ends up drawing at one
   size and displaying at another. */
.sky {
  position: absolute;
  inset: 0 0 auto 0;
  /* taller than one screen on purpose: the cards sit in its lower half,
     and glass over flat colour is just a grey box */
  height: 118dvh;
  overflow: hidden;
  z-index: -50;
  pointer-events: none;
}
.orrery { display: block; width: 100%; height: 100%; }

/* ——— the nav pill ———————————————————————————————————————————————— */
.topbar { position: relative; z-index: 5; display: flex; justify-content: center; padding: 22px 20px 0; }
.pill {
  display: flex; align-items: center; gap: 34px;
  padding: 13px 26px;
  border: 1px solid var(--rim);
  border-radius: 999px;
  background: var(--glass);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  max-width: 100%;
}
.wordmark {
  font-size: 15px; font-weight: 500; letter-spacing: .28em;
  color: var(--ink); white-space: nowrap;
}
.pill nav { display: flex; gap: 26px; }
.pill nav a { color: var(--ink-dim); font-size: 14px; }
.pill nav a:hover { color: var(--ink); }

/* ——— shared pieces ——————————————————————————————————————————————— */
.eyebrow {
  margin: 0 0 18px;
  font-size: 11px; font-weight: 400; letter-spacing: .22em;
  text-transform: uppercase; color: var(--holo);
}
.lede { color: var(--ink-dim); max-width: 56ch; }
.textlink { font-size: 16px; }

/* ——— hero ———————————————————————————————————————————————————————— */
.hero { position: relative; padding: clamp(90px, 14vh, 170px) 0 clamp(56px, 8vh, 96px); }
.hero h1 {
  margin: 0 0 22px;
  font-size: clamp(38px, 5.4vw, 58px);
  font-weight: 700; line-height: 1.2; letter-spacing: -.01em;
  /* ⚠ WIDE ENOUGH FOR THREE LINES. At 15ch this headline broke to five
     and the caret orphaned onto a sixth, which read as a mistake rather
     than as a cursor. If the words change, check the break. */
  max-width: 21ch;
}
/* the caret travels with the last word or it lands on its own line */
.nb { white-space: nowrap; }
/* ⚠ ONE WORD LIT, AND ONLY ONE. The glow is two shadows rather than one
   for the same reason the card icons carry three — a single shadow reads
   as a coloured word, two read as a word with light coming off it. If a
   second word ever takes this class the effect dies, because what makes
   it work is that everything around it is not lit. */
.hi {
  color: var(--holo);
  text-shadow: 0 0 16px rgba(127, 216, 247, .70), 0 0 48px rgba(127, 216, 247, .40);
}
/* the reference parks a blinking caret after its headline; it is the one
   piece of movement in the type and it costs four lines */
.caret {
  display: inline-block; width: 3px; height: .86em;
  margin-left: .12em; vertical-align: -.06em;
  background: var(--holo);
  animation: blink 1.1s step-end infinite;
}
@keyframes blink { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .caret { animation: none; opacity: .7; } }

.hero .lede { font-size: 18px; margin: 0 0 30px; }

/* ⚠ THE THREE NAMED ROOMS WERE CUT HERE (Yusef, 2026-09-12: "I don't
   like the named rooms. simpler lander"). The Briefing, the Desk and the
   Data Vault had a column each; the page is the mark, one sentence and
   one ask now. If something goes back in, it goes in the ask block —
   do not rebuild a three-up. */

/* ——— the five ————————————————————————————————————————————————————
   Glass, on a dark ground, is four things and none of them is the blur on
   its own: a translucent fill that is LIGHTER at the top edge than the
   bottom, a one-pixel rim brighter than either, a shadow that puts the
   card above the page rather than on it, and something behind it worth
   blurring. The fourth is why this section sits high enough to overlap
   the orrery's lower half — glass over flat colour is just a grey box. */
.cards {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 14px;
  /* pulled up into the sky, which is what gives the blur something to do */
  margin-top: clamp(-40px, -3vw, -10px);
  /* ⚠ THE PERSPECTIVE LIVES ON THE ROW, NOT ON THE CARD. Put it on each
     card and every one gets its own vanishing point directly in front of
     itself, so the five tilt identically and the 3D reads as a gimmick.
     On the parent they share one viewpoint, which means the card on the
     left leans away from you differently than the one on the right —
     that difference is the whole effect. */
  perspective: 1100px;
}
.card {
  position: relative;
  display: grid;
  gap: 10px;
  /* the icon owns the top of the card and the words sit under it */
  align-content: end;
  min-height: 224px;
  overflow: hidden;
  padding: 24px 20px 26px;
  border-radius: 16px;
  border: 1px solid rgba(170, 220, 240, .13);
  background:
    linear-gradient(168deg, rgba(150, 200, 228, .115) 0%, rgba(150, 200, 228, .045) 38%, rgba(8, 15, 27, .30) 100%);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  box-shadow:
    0 20px 44px -24px rgba(0, 0, 0, .9),
    inset 0 1px 0 rgba(214, 244, 255, .17);
  /* ⚠ THE IDLE DRIFT IS ONE ANIMATION ON `transform`, AND HOVER USES THE
     SEPARATE `translate` AND `scale` PROPERTIES. That split is the whole
     reason both work at once: a running animation owns whatever property
     it animates, so if hover also set `transform` the animation would
     simply win and the card would stop answering the pointer. The
     individual properties resolve BEFORE `transform` in the chain, so the
     two compose rather than fight — the same problem the icon's bloom
     had, solved the same way.

     Each card carries its own amplitudes and its own duration, so no two
     trace the same path or come back to the start together. Durations are
     near-coprime for the reason they always are here: ones that divide
     into each other re-sync and the row starts breathing as a block. */
  animation: suspend var(--drift, 10s) ease-in-out var(--drift-lag, 0s) infinite;
  transition: translate .4s cubic-bezier(.2, .7, .3, 1), scale .4s cubic-bezier(.2, .7, .3, 1), border-color .4s, box-shadow .4s;
}
@keyframes suspend {
  0%, 100% {
    transform:
      translateY(0)
      rotateX(calc(var(--ax) *  1))
      rotateY(calc(var(--ay) * -1))
      rotateZ(calc(var(--az) * -1));
  }
  33% {
    transform:
      translateY(calc(var(--lift) * -1))
      rotateX(calc(var(--ax) * -0.85))
      rotateY(calc(var(--ay) *  0.9))
      rotateZ(calc(var(--az) *  0.75));
  }
  66% {
    transform:
      translateY(calc(var(--lift) * -0.4))
      rotateX(calc(var(--ax) *  0.55))
      rotateY(calc(var(--ay) *  1))
      rotateZ(calc(var(--az) *  0.35));
  }
}
.card:nth-child(1) { --ax: 1.1deg; --ay: 1.5deg; --az: .40deg; --lift: 7px; --drift:  9.1s; --drift-lag: -0.7s; }
.card:nth-child(2) { --ax: 1.4deg; --ay: 1.1deg; --az: .28deg; --lift: 6px; --drift: 11.3s; --drift-lag: -4.1s; }
.card:nth-child(3) { --ax: 0.9deg; --ay: 1.7deg; --az: .50deg; --lift: 8px; --drift:  8.3s; --drift-lag: -2.2s; }
.card:nth-child(4) { --ax: 1.6deg; --ay: 0.9deg; --az: .34deg; --lift: 5px; --drift: 12.7s; --drift-lag: -6.5s; }
.card:nth-child(5) { --ax: 1.2deg; --ay: 1.3deg; --az: .45deg; --lift: 7px; --drift: 10.1s; --drift-lag: -3.4s; }

/* the specular edge: a hairline that catches light across the top only */
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(150deg, rgba(214, 244, 255, .42), rgba(214, 244, 255, 0) 42%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}
.card:hover, .card:focus-within {
  /* NOT `transform` — see the note above. These are the separate
     properties, which compose with the drift instead of replacing it. */
  translate: 0 -9px;
  scale: 1.02;
  border-color: rgba(127, 216, 247, .42);
  box-shadow:
    0 30px 56px -26px rgba(0, 0, 0, .95),
    0 0 34px -12px rgba(127, 216, 247, .34),
    inset 0 1px 0 rgba(214, 244, 255, .30);
}
/* ⚠ THE ICON IS THE CARD'S BACKGROUND, NOT AN ORNAMENT IN THE CORNER.
   It was a 42px tile above the heading until 2026-09-12; Yusef: "make the
   whole glassmorphic cards the icon background slightly frost blurred
   with glowing bloom no nested icon tile."

   Three things make it read as frosted glass with something lit behind it
   rather than as a big faint drawing:

   1. it sits at 70% of the card's width in the top right, bleeding a
      little off two edges, so it is clearly BEHIND the glass rather than
      placed on it, and the words keep the bottom left;
   2. a small blur — five pixels, not ten — because frost softens an
      edge, it does not dissolve it;
   3. THREE drop-shadows, each roughly triple the radius of the last: a
      hot core, the tube's own light, and the haze it throws on the glass.
      One shadow reads as a glow effect and two are barely better; three
      read as a light source.

   The stroke is 1.05 in a 24-unit viewBox, which is a scaling problem and
   not a taste one: the smaller the icon renders, the heavier the stroke
   has to be written to land at the same thickness on the glass. */

/* ⚠ THE BLOOM BREATHES ON ITS OWN, AND THAT IS WHY THE FILTER IS BUILT
   FROM VARIABLES (Yusef, 2026-09-13: "can we make each one bloom
   automatically randomly instead of waiting for hover only?").

   The obvious version — an @keyframes that animates `filter` — kills
   hover, because a running animation outranks the hovered rule and the
   card stops responding to the pointer entirely. So the filter is written
   ONCE and the animation drives a registered custom property inside it,
   while hover drives two others. They compose instead of fighting.

   @property is what makes `--bloom` interpolate at all; an unregistered
   custom property jumps between keyframes rather than easing. Where it is
   not supported the property keeps its initial value, the filter is
   simply static, and the card still looks right — which is the correct
   way for this to degrade.

   The five durations are near-coprime ON PURPOSE, the same trick the
   orrery's orbits use: durations that divide into one another re-sync
   every few seconds and the row starts pulsing as one block, which is the
   opposite of random. These five do not line up again for minutes. */
@property --bloom { syntax: "<number>"; inherits: false; initial-value: .55; }
@property --gain  { syntax: "<number>"; inherits: false; initial-value: 1; }
@property --floor { syntax: "<number>"; inherits: false; initial-value: .22; }

.card .ic {
  position: absolute;
  inset: -9% -11% auto auto;
  width: 70%;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  color: var(--holo);
  opacity: calc(var(--floor) + var(--bloom) * .22);
  filter:
    blur(5px)
    drop-shadow(0 0  calc(5px + var(--bloom) *  7px) rgba(214, 244, 255, calc(var(--bloom) * .95 * var(--gain))))
    drop-shadow(0 0 calc(16px + var(--bloom) * 18px) rgba(127, 216, 247, calc(var(--bloom) * .80 * var(--gain))))
    drop-shadow(0 0 calc(44px + var(--bloom) * 46px) rgba(127, 216, 247, calc(var(--bloom) * .52 * var(--gain))));
  animation: ic-bloom var(--dur, 6s) ease-in-out var(--lag, 0s) infinite;
  transition: --gain .45s, --floor .45s, transform .55s cubic-bezier(.2, .7, .3, 1);
  pointer-events: none;
}
@keyframes ic-bloom {
  0%, 100% { --bloom: .18; }
  50%      { --bloom: 1; }
}
.card:nth-child(1) .ic { --dur: 5.3s; --lag: -0.4s; }
.card:nth-child(2) .ic { --dur: 6.7s; --lag: -2.9s; }
.card:nth-child(3) .ic { --dur: 4.9s; --lag: -1.6s; }
.card:nth-child(4) .ic { --dur: 7.3s; --lag: -4.2s; }
.card:nth-child(5) .ic { --dur: 6.1s; --lag: -3.3s; }

.card .ic svg {
  width: 100%; height: 100%;
  fill: none; stroke: currentColor;
  stroke-width: 1.05; stroke-linecap: round; stroke-linejoin: round;
}
/* hover does not replace the bloom, it multiplies it and lifts the floor,
   so a card caught mid-pulse still reacts */
.card:hover .ic, .card:focus-within .ic {
  --gain: 1.75;
  --floor: .34;
  transform: scale(1.07);
}
@media (prefers-reduced-motion: reduce) {
  .card .ic { animation: none; }
}

.card h3, .card p { position: relative; z-index: 1; }
.card h3 { margin: 0; font-size: 1.02rem; font-weight: 500; letter-spacing: .01em; }
.card p { margin: 0; font-size: .84rem; line-height: 1.55; color: var(--ink-dim); }

@media (prefers-reduced-motion: reduce) {
  .card { animation: none; }
  .card:hover, .card:focus-within { translate: none; scale: none; }
}
@media (max-width: 1040px) { .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 0; } }
@media (max-width: 720px)  { .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* ⚠ STAYS TWO-UP ON A PHONE. One column meant five cards at 248px each,
   which put twelve hundred pixels of feature list between the headline
   and the only ask on the page — the page went from 1.6 screens to 2.7.
   They are shorter and tighter here instead. */
@media (max-width: 430px) {
  .card { min-height: 196px; padding: 18px 15px 20px; }
  .card h3 { font-size: .96rem; }
  .card p { font-size: .79rem; }
}

/* ——— why this exists ——————————————————————————————————————————————
   ⚠ THE ARGUMENT LIVES DOWN HERE, NOT IN THE HERO. Six entries, each the
   same five parts in the same order: a number, the problem as a heading,
   the complaint in the reader's own voice, why the obvious fix fails, and
   what Atlas does instead. The order is the point — a reader who agrees
   with the first two parts has already agreed with the fifth.

   The voice line is NOT quoted and NOT attributed, deliberately. Quotation
   marks on an invented sentence imply a customer said it, and we have no
   customer who did. It is the complaint stated plainly, in italics, as
   what it is. */
.why { padding-top: var(--stack); }
.why-head { margin: 0 0 18px; font-size: clamp(28px, 3.6vw, 38px); font-weight: 500; line-height: 1.2; max-width: 16ch; }
.why > .lede { font-size: 17px; margin: 0 0 clamp(42px, 6vw, 72px); }
.entries {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(34px, 4.5vw, 60px) clamp(34px, 5vw, 72px);
}
.entry { display: grid; gap: 11px; align-content: start; max-width: 50ch; }
.entry .num {
  margin: 0; font-size: 11px; letter-spacing: .24em; color: var(--holo);
  font-variant-numeric: tabular-nums;
}
.entry h3 { margin: 0; font-size: clamp(19px, 2vw, 22px); font-weight: 500; line-height: 1.3; }
.entry p { margin: 0; font-size: .94rem; line-height: 1.65; color: var(--ink-dim); }
/* the complaint, set apart by a rule rather than by quotation marks */
.entry .voice {
  padding-left: 16px;
  border-left: 2px solid rgba(127, 216, 247, .30);
  font-style: italic;
  color: #b9cbd8;
}
.entry .fix { color: var(--ink); }
.entry .fix strong { color: var(--holo); font-weight: 500; }

/* ——— none of this is your job ——————————————————————————————————— */
.nots {
  margin-top: var(--stack);
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: clamp(24px, 4vw, 56px);
  padding: clamp(30px, 4vw, 52px);
  border: 1px solid var(--line);
  border-radius: 14px;
  background: linear-gradient(160deg, rgba(20, 38, 62, .34), rgba(7, 11, 20, .46));
}
.nots h2 { margin: 0; font-size: clamp(22px, 2.8vw, 28px); font-weight: 500; line-height: 1.25; max-width: 14ch; }
.nots ul { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px 26px; }
.nots li { position: relative; padding-left: 28px; font-size: .92rem; color: var(--ink-dim); line-height: 1.5; }
/* the cross is drawn, not a character: a font's ✕ sits at a different
   height in every fallback and the column comes out ragged */
.nots li::before,
.nots li::after {
  content: ""; position: absolute; left: 4px; top: .62em;
  width: 12px; height: 1.5px; border-radius: 2px;
  background: rgba(127, 216, 247, .55);
}
.nots li::before { rotate: 45deg; }
.nots li::after  { rotate: -45deg; }

/* ——— the honest answers ————————————————————————————————————————— */
.faq { padding-top: var(--stack); }
.faq h2 { margin: 0 0 clamp(26px, 3.5vw, 44px); font-size: clamp(26px, 3.2vw, 34px); font-weight: 500; }
.qs { max-width: 74ch; }
/* native details/summary: no script, keyboard-operable for free */
.qs details { border-top: 1px solid var(--line); }
.qs details:last-child { border-bottom: 1px solid var(--line); }
.qs summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 19px 2px; font-size: 1rem; color: var(--ink);
  transition: color .25s;
}
.qs summary::-webkit-details-marker { display: none; }
.qs summary:hover { color: var(--holo); }
.qs summary::after {
  content: "+"; flex: none;
  font-size: 1.15rem; line-height: 1; color: var(--holo);
  transition: rotate .3s ease;
}
.qs details[open] summary::after { rotate: 45deg; }
.qs details p { margin: -4px 0 22px; padding-right: 44px; font-size: .94rem; line-height: 1.68; color: var(--ink-dim); }

@media (max-width: 900px) {
  .entries { grid-template-columns: minmax(0, 1fr); }
  .nots { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .nots ul { grid-template-columns: minmax(0, 1fr); }
}

/* ——— the ask ————————————————————————————————————————————————————— */
.ask {
  margin-top: clamp(34px, 4.5vw, 64px);
  border: 1px solid var(--line);
  border-radius: 14px;
  background: linear-gradient(160deg, rgba(20, 38, 62, .38), rgba(7, 11, 20, .5));
  padding: clamp(34px, 5vw, 62px);
}
/* ⚠ THE CARD IS TWO COLUMNS ON A WIDE SCREEN. One column left two thirds
   of it empty, which made the page read as unfinished rather than as
   spare. The heading holds the left, everything else the right. */
.ask h2 { margin: 0; font-size: clamp(24px, 3vw, 30px); font-weight: 500; line-height: 1.28; max-width: 14ch; }
.ask p { margin: 0 0 18px; color: var(--ink-dim); max-width: 54ch; }
.ask p:last-child { margin-bottom: 0; }
@media (min-width: 900px) {
  .ask { display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: clamp(28px, 4vw, 56px); align-items: start; }
}

/* ——— footer —————————————————————————————————————————————————————— */
.foot { margin-top: var(--stack); border-top: 1px solid var(--line); padding: 40px 0 60px; }
.foot .rows { display: flex; flex-wrap: wrap; gap: 32px 60px; align-items: flex-start; justify-content: space-between; }
.foot .mark { font-size: 13px; letter-spacing: .26em; color: var(--ink); }
.foot .mark small { display: block; margin-top: 8px; font-size: 10px; letter-spacing: .16em; color: var(--muted); line-height: 1.7; }
.foot nav { display: flex; gap: 26px; flex-wrap: wrap; }
.foot nav a, .foot .legal a { font-size: 14px; }
.foot .legal { width: 100%; margin: 0; padding-top: 26px; color: var(--muted); font-size: 13px; }

/* ——— narrow ————————————————————————————————————————————————————— */
@media (max-width: 860px) {
  .pill { gap: 20px; flex-wrap: wrap; justify-content: center; border-radius: 20px; }
  .pill nav { gap: 18px; flex-wrap: wrap; justify-content: center; }
}
@media (max-width: 768px) {
  /* ⚠ THIS BLOCK ONCE SAID `.mark`, WHICH IS THE FOOTER'S WORDMARK. It was
     left behind when the artwork stopped being an SVG, and it would have
     put `width: 92%` and `opacity: .8` on a div in the footer for the
     second time in two days. The artwork's rules are `.sky` and
     `.orrery`; the footer owns `.mark`. Check for a class before claiming
     one, and delete the rules when you delete the element. */
  .sky { height: 74dvh; opacity: .85; }
}
