/* terminal-lib.com
 *
 * Design system ported from terminal-lift/Design/TerminalTheme.swift.
 * Colours L12-49, Spacing L52-65, Radius L67-72. pt maps 1:1 to px.
 *
 * Two deliberate deviations from the app, both documented at their token:
 * type scale (web viewing distance) and block spacing (web page rhythm).
 * Colours, borders and radii are exact — do not "improve" them.
 */

/* ── font ───────────────────────────────────────────────────────────────── */
/* JetBrains Mono, OFL 1.1 (see fonts/OFL.txt). Variable weight axis, so one
   31KB file covers 400/500/700. Self-hosted rather than served from the
   Google Fonts CDN: it's a third-party request on a page that claims third
   parties don't get your data, and the CDN is a GDPR grey area in the EU. */
@font-face {
  font-family: 'JetBrains Mono';
  src: url('../fonts/jetbrains-mono-latin-var.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2212;
}

:root {
  /* ── colour: exact from TerminalTheme.swift ────────────────────────── */
  --amber-1: #ffb84d;   /* L1 primary — one element per screen, maximum */
  --amber-2: #d4941a;   /* L2 secondary, titles */
  --amber-3: #b8935f;   /* L3 tertiary, body, meta */
  --amber-4: #8a6b2e;   /* L4 ghost, tracks */

  --bg-primary: #0e0b06;
  --bg-secondary: #120d04;
  --bg-deep: #0a0700;

  --border-active: #c87c10;
  --border-default: #2a1e0a;
  --border-ghost: #1a1208;

  --tag-bg-active: #2e1f00;
  --tag-bg-default: #1e1208;
  --tag-bg-ghost: #1a1208;
  --tag-border-default: #3a2810;

  --tint-soft: rgba(255, 184, 77, .10);
  --tint-medium: rgba(255, 184, 77, .20);

  /* The app's placeholderText (#6b5a3d) is 2.95:1 against bg-primary, which
     fails WCAG AA. Web uses amber-3 (6.9:1) instead — accessibility wins over
     fidelity here, and Lighthouse a11y >=95 is a stated target. */
  --placeholder: var(--amber-3);

  /* ── spacing: exact from TerminalTheme.Spacing ─────────────────────── */
  --gap-card: 16px;
  --gap-card-half: 8px;
  --gap-section: 20px;
  --edge: 14px;
  --pad-primary: 12px;
  --pad-secondary: 10px;
  --pad-ghost: 8px;
  --pad-control: 8px;

  /* Web-only additions. The app's 20px sectionGap is right for a phone screen
     and far too tight for a scrolling page, so major blocks get their own
     rhythm. Not pretending these are app tokens. */
  --gap-block: clamp(48px, 9vw, 88px);
  --measure: 720px;

  /* ── radius: exact ─────────────────────────────────────────────────── */
  --r-modal: 12px;
  --r-card: 8px;
  --r-control: 6px;
  --r-tag: 2px;

  /* Border width is 1px everywhere. There are no exceptions in the app and
     there are none here. */
  --bw: 1px;

  /* ── type ──────────────────────────────────────────────────────────── */
  /* The app's 12px body is correct at phone viewing distance but cramped on a
     desktop landing page, and small type is an accessibility flag. Sizes are
     scaled up; the hierarchy and ratios are preserved. */
  --fs-hero: clamp(27px, 6.6vw, 43px);
  --fs-lead: clamp(15px, 2.4vw, 18px);
  --fs-body: clamp(15px, 1.6vw, 16px);
  --fs-h2: clamp(19px, 3vw, 23px);
  --fs-path: 14px;      /* exact: terminalHeader */
  --fs-label: 13px;     /* exact: terminalSectionLabel */
  --fs-btn: 13px;       /* exact: terminalButton */
  --fs-small: 13px;
  --fs-tag: 10px;       /* app is 9px; +1 for web legibility */
}

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

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

body {
  margin: 0;
  background: var(--bg-primary);
  color: var(--amber-3);
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.55;   /* matches wrappedLineSpacing 6.5 on 12pt */
  -webkit-font-smoothing: antialiased;
}

/* All user-facing copy is lowercase. Enforced rather than trusted, because
   it's the single easiest convention to break by accident. */
h1, h2, h3, p, li, a, button, label, dt, dd, figcaption, small {
  text-transform: lowercase;
}
/* Escape hatch for proper nouns: <span class="proper">Apple Health</span> */
.proper { text-transform: none; }

h1, h2, h3 { margin: 0; font-weight: 700; }
p { margin: 0; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }
img, video { display: block; max-width: 100%; height: auto; }

a {
  color: var(--amber-2);
  text-decoration: none;
  border-bottom: var(--bw) solid var(--border-default);
}
a:hover { color: var(--amber-1); border-bottom-color: var(--border-active); }

/* Visible focus is non-negotiable for keyboard users. amber-1 is 11.4:1 here. */
:focus-visible {
  outline: 2px solid var(--amber-1);
  outline-offset: 2px;
  border-radius: var(--r-tag);
}

/* Hide scrollbars, as the app does — but never at the cost of scrollability. */
.no-bar { scrollbar-width: none; -ms-overflow-style: none; }
.no-bar::-webkit-scrollbar { display: none; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ── layout ─────────────────────────────────────────────────────────────── */
.wrap {
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  padding-inline: var(--edge);
}
.wrap--wide { max-width: 1180px; }

.block { margin-top: var(--gap-block); }
.block:last-of-type { margin-bottom: var(--gap-block); }

/* ── path header: ~/kebab-case, always ──────────────────────────────────── */
.topbar {
  background: var(--bg-primary);
  border-bottom: var(--bw) solid var(--border-ghost);
  position: sticky;
  top: 0;
  z-index: 10;
}
.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-card);
  min-height: 44px;            /* tap target */
  padding-block: var(--pad-control);
}
.path {
  font-size: var(--fs-path);
  font-weight: 500;
  color: var(--amber-1);
  text-transform: none;        /* it's a path, not prose */
  border: 0;
}
.topbar .path:hover { color: var(--amber-1); }

/* ── section label: literally "— label" ─────────────────────────────────── */
.section-label {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: .011em;      /* kerning(0.14) at 13px, per the code */
  color: var(--amber-3);
  margin-bottom: var(--gap-card-half);
}
.section-label::before { content: '— '; }

/* ── cards: three levels, never mixed ───────────────────────────────────── */
.card {
  border: var(--bw) solid var(--border-default);
  border-radius: var(--r-card);
  background: var(--bg-primary);
  padding: var(--pad-secondary);
}
.card--primary {
  border-color: var(--border-active);
  background: var(--bg-secondary);
  padding: var(--pad-primary);
}
.card--ghost {
  border-color: var(--border-ghost);
  background: var(--bg-primary);
  padding: var(--pad-ghost);
  opacity: .55;
}
.card__title {
  font-size: var(--fs-body);
  font-weight: 500;
  color: var(--amber-2);
  margin-bottom: 4px;
}
.card__meta { font-size: var(--fs-small); color: var(--amber-3); }

/* A whole card that is a link. Suppresses the default link underline so the
   card border stays the only edge in play. */
a.card {
  display: block;
  border-bottom-width: var(--bw);
  color: inherit;
}
a.card:hover {
  border-color: var(--border-active);
  background: var(--bg-secondary);
}
a.card:hover .card__title { color: var(--amber-1); }

.grid {
  display: grid;
  gap: var(--gap-card);
  grid-template-columns: 1fr;
}
@media (min-width: 620px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
}

/* ── stack: vertical rhythm helper ──────────────────────────────────────── */
.stack > * + * { margin-top: var(--gap-card); }
.stack-tight > * + * { margin-top: var(--gap-card-half); }

/* ── tags ───────────────────────────────────────────────────────────────── */
.tag {
  display: inline-block;
  font-size: var(--fs-tag);
  letter-spacing: .005em;
  padding: 2px 6px;
  border-radius: var(--r-tag);
  border: var(--bw) solid var(--tag-border-default);
  background: var(--tag-bg-default);
  color: var(--amber-2);
}
.tag--active {
  background: var(--tag-bg-active);
  border-color: var(--border-active);
  color: var(--amber-1);
}
.tag--ghost {
  background: var(--tag-bg-ghost);
  border-color: var(--border-default);
  color: var(--amber-3);
}

/* ── buttons ────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 100%;
  min-height: 44px;
  font-family: inherit;
  font-size: var(--fs-btn);
  font-weight: 700;
  letter-spacing: .008em;      /* kerning(0.1) at 13px */
  padding: 10px 0;
  border-radius: var(--r-control);
  border: var(--bw) solid var(--amber-1);
  background: var(--amber-1);
  color: var(--bg-primary);
  cursor: pointer;
}
/* The app defines no hover state (buttonStyle(.plain)); web needs one. */
.btn:hover { background: #ffc466; border-color: #ffc466; }
.btn:disabled { opacity: .55; cursor: not-allowed; }

.btn--secondary {
  padding: 8px 0;
  background: transparent;
  border-color: var(--border-default);
  color: var(--amber-2);
}
.btn--secondary:hover {
  background: var(--tint-soft);
  border-color: var(--border-active);
  color: var(--amber-1);
}

/* ── cursor ─────────────────────────────────────────────────────────────── */
/* The typewriter's underscore uses a 0.53s half-period / 1.06s full cycle,
   matching `BlinkDriver(interval: 0.53)` in terminal-lift. */
.cursor {
  display: inline-block;
  margin-left: 4px;
  opacity: 0;
}
.cursor.is-active {
  animation: blink 1.06s step-end infinite;
}
@keyframes blink {
  0%, 50% { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

/* ── control surface / inputs ───────────────────────────────────────────── */
.field {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  border: var(--bw) solid var(--border-default);
  border-radius: var(--r-control);
  background: var(--bg-secondary);
  padding: var(--pad-control);
}
.field:focus-within { border-color: var(--border-active); }
.field__prompt { color: var(--amber-2); flex: none; }
.field input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 28px;
  font-family: inherit;
  font-size: var(--fs-body);
  color: var(--amber-1);
  background: transparent;
  border: 0;
  outline: 0;
}
.field input::placeholder { color: var(--placeholder); opacity: 1; }
/* When JavaScript is available, the native caret hands off to this terminal
   underscore. It is positioned from the input's live selection, rather than
   pinned to the edge of the field, so it follows typed text and edits. */
.field--cursor-active input { caret-color: transparent; }
.field--cursor-active input::placeholder { color: transparent; }
.field__cursor {
  position: absolute;
  left: var(--field-cursor-x, 0px);
  top: 50%;
  display: none;
  color: var(--amber-1);
  line-height: 1;
  pointer-events: none;
  transform: translateY(-50%);
}
.field--cursor-active .field__cursor {
  display: block;
  animation: blink 1.06s step-end infinite;
}

.form__row { display: grid; gap: var(--gap-card-half); }
@media (min-width: 520px) {
  .form__row { grid-template-columns: 1fr auto; align-items: stretch; }
  .form__row .btn { width: auto; padding-inline: var(--gap-card); }
}
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Turnstile mounts here on first interaction with the form (js/signup.js). With
   interaction-only appearance it takes no visible space unless a challenge is
   genuinely required, so no spacing is reserved for it — the widget's own iframe
   carries its own when it does appear. */
.turnstile,
.turnstile iframe { max-width: 100%; }

/* Receipt shown in place of the form after a successful signup. Echoes the
   in-app typewriter log. */
.receipt {
  border: var(--bw) solid var(--border-active);
  border-radius: var(--r-card);
  background: var(--bg-secondary);
  padding: var(--pad-primary);
  color: var(--amber-2);
  font-size: var(--fs-small);
}
.receipt li::before { content: '> '; color: var(--amber-3); }
.form__error { font-size: var(--fs-small); color: var(--amber-1); }

/* ── media frames ───────────────────────────────────────────────────────── */
/* Flat 1px frames, never a phone bezel — a bezel needs a drop shadow, and the
   design system forbids shadows. */
.frame {
  border: var(--bw) solid var(--border-default);
  border-radius: var(--r-card);
  background: var(--bg-deep);
  overflow: hidden;
}
.frame video, .frame img { width: 100%; display: block; }
/* Reserve aspect so media loading never shifts layout. */
.frame--phone { aspect-ratio: 9 / 19.5; max-width: 320px; }

/* Placeholder standing in for media that hasn't been captured yet. Occupies
   the exact final footprint, so dropping real media in causes no reflow.
   Delete these along with the last placeholder. */
.frame--empty {
  display: grid;
  place-items: center;
  border-style: dashed;
  border-color: var(--border-default);
  color: var(--amber-4);
  font-size: var(--fs-small);
}

.mb-card { margin-bottom: var(--gap-card); }

.shots {
  display: flex;
  gap: var(--gap-card);
  overflow-x: auto;
  padding-bottom: 4px;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.shots > figure { flex: 0 0 200px; scroll-snap-align: start; margin: 0; }
.shots figcaption {
  font-size: var(--fs-small);
  color: var(--amber-3);
  margin-top: var(--gap-card-half);
}

.media-row { display: grid; gap: var(--gap-card); align-items: center; }
@media (min-width: 700px) {
  .media-row { grid-template-columns: 320px 1fr; gap: var(--gap-block); }
}

/* ── hero ───────────────────────────────────────────────────────────────── */
.hero { padding-top: var(--gap-block); }
.hero h1 {
  font-size: var(--fs-hero);
  line-height: 1.12;
  color: var(--amber-1);
  letter-spacing: -.01em;
  margin-bottom: var(--gap-card);
}
.hero__lead {
  font-size: var(--fs-lead);
  color: var(--amber-3);
  max-width: 34em;
  margin-bottom: var(--gap-card);
}
.hero__note { font-size: var(--fs-small); color: var(--amber-3); margin-top: var(--gap-card-half); }

/* ── lift landing page ─────────────────────────────────────────────────── */
/* The product app is intentionally dense: a utility used one-handed in the
   gym. Its marketing page needs a different composition — a larger canvas and
   more room for the product to make its own case. The colour, type, borders,
   radius, and controls are still the same system. */
.lift-page main { overflow: hidden; }
.hero--lift {
  display: grid;
  gap: clamp(32px, 6vw, 88px);
  align-items: center;
  min-height: min(740px, calc(100vh - 44px));
  padding-top: clamp(46px, 8vw, 108px);
  padding-bottom: clamp(32px, 6vw, 72px);
}
.hero--lift > * { min-width: 0; }
.hero--lift h1 {
  /* Leave space for the live " _" cursor on the final line. */
  max-width: 15ch;
  font-size: clamp(37px, 4.55vw, 61px);
  line-height: 1.04;
  letter-spacing: -.035em;
  margin-bottom: 20px;
}
.hero--lift .hero__lead {
  max-width: 35em;
  font-size: clamp(16px, 1.55vw, 19px);
  line-height: 1.55;
  margin-bottom: 14px;
}
.hero--lift .hero__lead span { display: block; }
.hero--lift .hero__lead b { color: var(--amber-2); font-weight: 500; }
.eyebrow {
  margin-bottom: var(--gap-card-half);
  color: var(--amber-4);
  font-size: var(--fs-small);
  font-weight: 500;
}
.eyebrow::before { content: '— '; }
.hero--lift .signup { max-width: 540px; }
.hero--lift .hero__note { max-width: 55ch; }

/* A flat product composition, not a phone mockup. Capture and substitute the
   actual app screens before launch; this preserves the visual hierarchy while
   media is being recorded. */
.product-stage {
  position: relative;
  width: min(100%, 540px);
  min-height: 490px;
  margin-inline: auto;
}
.product-stage::before {
  content: '';
  position: absolute;
  inset: 11% 5% 6% 16%;
  border: var(--bw) solid var(--border-ghost);
  background:
    linear-gradient(var(--border-ghost) 1px, transparent 1px),
    linear-gradient(90deg, var(--border-ghost) 1px, transparent 1px);
  background-size: 26px 26px;
  opacity: .45;
}
.app-preview {
  position: absolute;
  overflow: hidden;
  border: var(--bw) solid var(--border-default);
  border-radius: var(--r-modal);
  background: var(--bg-primary);
}
.app-preview--workout {
  z-index: 2;
  width: clamp(228px, 29vw, 302px);
  right: 17%;
  top: 0;
}
.app-preview--progress {
  z-index: 1;
  width: clamp(205px, 26vw, 270px);
  left: 0;
  bottom: 28px;
  background: var(--bg-secondary);
}
.app-preview__bar {
  display: flex;
  justify-content: space-between;
  min-height: 36px;
  padding: 9px 10px;
  border-bottom: var(--bw) solid var(--border-default);
  color: var(--amber-2);
  font-size: 10px;
}
.app-preview__body { padding: 14px; }
.app-preview__label {
  margin-bottom: 4px;
  color: var(--amber-4);
  font-size: 9px;
}
.app-preview__title {
  margin-bottom: 12px;
  color: var(--amber-2);
  font-size: 15px;
  font-weight: 700;
}
.app-preview__title--next {
  margin-top: 15px;
  margin-bottom: 8px;
  font-size: 12px;
}
.set-head, .set-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 18px;
  column-gap: 5px;
  align-items: center;
}
.set-head {
  margin-bottom: 4px;
  color: var(--amber-4);
  font-size: 8px;
}
.set-row {
  min-height: 30px;
  margin-top: 5px;
  padding: 5px 7px;
  border: var(--bw) solid var(--border-default);
  border-radius: var(--r-tag);
  color: var(--amber-3);
  font-size: 11px;
}
.set-row b { color: var(--amber-2); text-align: right; }
.set-row--active { border-color: var(--border-active); color: var(--amber-1); }
.set-row--muted { border-color: var(--border-ghost); color: var(--amber-4); }
.timer {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-top: 12px;
  padding: 8px;
  border-top: var(--bw) solid var(--border-ghost);
  color: var(--amber-3);
  font-size: 9px;
}
.timer strong { color: var(--amber-1); font-size: 15px; }
.chart-number { color: var(--amber-1); font-size: 28px; font-weight: 700; }
.chart-number small { color: var(--amber-3); font-size: 11px; font-weight: 400; }
.chart { display: block; width: 100%; margin: 12px 0; overflow: visible; }
.chart__grid { fill: none; stroke: var(--border-ghost); stroke-width: 1; }
.chart__line { fill: none; stroke: var(--amber-2); stroke-width: 2; }
.chart__dot { fill: var(--amber-1); }
.record {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 8px;
  border-top: var(--bw) solid var(--border-default);
  color: var(--amber-4);
  font-size: 9px;
}
.record strong { color: var(--amber-2); font-size: 12px; }
.product-stage__label {
  position: absolute;
  right: 0;
  bottom: 0;
  color: var(--amber-4);
  font-size: 10px;
}

.outcomes { display: grid; gap: 30px; }
.outcomes__intro h2 { max-width: 14ch; font-size: clamp(27px, 3.3vw, 42px); line-height: 1.13; }
.outcome-grid { display: grid; gap: var(--gap-card); }
.outcome {
  display: flex;
  min-height: 250px;
  flex-direction: column;
  padding: clamp(18px, 2.4vw, 30px);
  border: var(--bw) solid var(--border-default);
  border-radius: var(--r-card);
  background: var(--bg-primary);
}
.outcome--wide { border-color: var(--border-active); background: var(--bg-secondary); }
.outcome--ownership { background: var(--bg-deep); }
.outcome__number { margin-bottom: auto; color: var(--amber-4); font-size: var(--fs-small); }
.outcome h3 { margin: 30px 0 8px; color: var(--amber-2); font-size: clamp(19px, 2vw, 25px); line-height: 1.2; }
.outcome > p:not(.outcome__number):not(.outcome__tags) { max-width: 37ch; }
.outcome__tags { margin-top: 18px; color: var(--amber-4); font-size: 11px; }
.outcome__tags i, .capability-strip i { color: var(--border-active); font-style: normal; }
.capability-strip {
  padding: clamp(22px, 4vw, 42px);
  border-block: var(--bw) solid var(--border-default);
}
.capability-strip .section-label { margin-bottom: 14px; }
.capability-strip > p:last-child { max-width: 63ch; color: var(--amber-2); font-size: clamp(17px, 2.1vw, 24px); line-height: 1.55; }
.questions { display: grid; gap: 20px; }
.questions .faq { max-width: 710px; }

@media (min-width: 760px) {
  .hero--lift { grid-template-columns: minmax(0, 1fr) minmax(390px, .9fr); }
  .outcomes { grid-template-columns: minmax(220px, .55fr) minmax(0, 1.45fr); align-items: start; }
  .outcome-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .outcome--wide { grid-column: span 2; min-height: 290px; }
  .questions { grid-template-columns: 190px minmax(0, 1fr); }
}
@media (max-width: 759px) {
  .hero--lift { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .product-stage { max-width: 400px; min-height: 440px; margin-top: 6px; }
  .app-preview--workout { right: 0; }
  .app-preview--progress { bottom: 34px; }
}

/* Typewriter reveal. The text is always in the DOM and merely clipped, so it
   survives JS-off and stays indexable. .tw-run is added by hero.js only when
   it intends to animate; without it, everything renders instantly. */
[data-typewriter] {
  display: grid;
}
/* An invisible copy owns the layout. It is deliberately in normal grid flow:
   an absolute copy would not reserve the completed heading's height. */
[data-typewriter]::before {
  content: attr(data-typewriter-copy);
  grid-area: 1 / 1;
  visibility: hidden;
  white-space: pre-line;
}
.tw__line {
  display: block;
  grid-area: 1 / 1;
  white-space: pre-line;
}
.tw__cursor {
  color: var(--amber-1);
  opacity: 0;
  user-select: none;
}
.tw-typing .tw__cursor {
  opacity: 1;
  animation: blink 1.06s step-end infinite;
}
/* The typewriter and primary CTA hand this single cursor between themselves. */
.tw-done .tw__cursor { opacity: 0; animation: none; }

h2 { font-size: var(--fs-h2); color: var(--amber-2); margin-bottom: var(--gap-card-half); }

/* ── faq ────────────────────────────────────────────────────────────────── */
.faq dt {
  font-size: var(--fs-body);
  font-weight: 500;
  color: var(--amber-2);
  margin-top: var(--gap-card);
}
.faq dt:first-child { margin-top: 0; }
.faq dd { color: var(--amber-3); margin-top: 4px; }

/* ── prose (privacy / support) ──────────────────────────────────────────── */
.prose { max-width: 62ch; }
.prose h2 { margin-top: var(--gap-block); }
.prose h2:first-of-type { margin-top: var(--gap-section); }
.prose p, .prose li { margin-top: var(--gap-card-half); }
.prose ul { margin-top: var(--gap-card-half); }
.prose li { padding-left: 1.2em; position: relative; }
.prose li::before { content: '·'; position: absolute; left: 0; color: var(--amber-4); }
.prose .updated { font-size: var(--fs-small); color: var(--amber-4); }

/* ── footer ─────────────────────────────────────────────────────────────── */
.footer {
  border-top: var(--bw) solid var(--border-ghost);
  margin-top: var(--gap-block);
  padding-block: var(--gap-card) var(--gap-block);
  font-size: var(--fs-small);
}
.footer ul { display: flex; flex-wrap: wrap; gap: var(--gap-card); }
.footer a { border: 0; color: var(--amber-3); }
.footer a:hover { color: var(--amber-1); }

/* ── motion ─────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  /* A cursor frozen mid-blink could land invisible. Pin it on. */
  .tw-typing .tw__cursor, .cursor.is-active, .field--cursor-active .field__cursor {
    opacity: 1 !important;
  }
}
