/* ═══════════════════════════════════════════════════════════════════════
   RASTA Collective — reset, fonts, typography primitives
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Fonts ──────────────────────────────────────────────────────────────
   Self-hosted so the page survives file:// with no network. Regenerate with
   `python tools/fetch_fonts.py`.

   The -extra faces exist because Google's `latin` unicode-range stops at
   U+206F and picks up only U+20AC, which drops U+20B9 (₹) — and the stipend
   line is one of the page's strongest selling points. Declaring the narrow
   range means the 3 KB file is only ever fetched by a page that renders ₹. */

@font-face {
  font-family: "Anton";
  src: url("../fonts/anton-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Anton";
  src: url("../fonts/anton-extra.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+20B9, U+2192;
}
@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-extra.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+20B9, U+2192;
}

/* Metric-matched fallbacks. These matter more than usual here: Firefox's
   strict file:// origin policy can block self-hosted @font-face on a
   double-clicked page, so the fallback stack is a real rendering path, not a
   200 ms flash. size-adjust/ascent-override keep the swap from reflowing —
   and keep the pinned section's measured scrollWidth honest. */
@font-face {
  font-family: "Anton Fallback";
  src: local("Impact"), local("Haettenschweiler"), local("Arial Narrow Bold");
  size-adjust: 92%;
  ascent-override: 88%;
  descent-override: 22%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Segoe UI");
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}


/* ── Reset ──────────────────────────────────────────────────────────────── */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchors must not land under the fixed logo. */
  scroll-padding-top: clamp(88px, 12vh, 140px);
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--text-on-light);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  /* `clip`, never `hidden`. overflow-x:hidden turns <body> into a scroll
     container, which silently demotes every position:sticky descendant to
     static — it would kill the entire pinned About section — and it breaks
     scroll-padding-top above. `clip` suppresses the overflow without
     creating a scroll container. */
  overflow-x: clip;
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd, ol, ul { margin: 0; }
ol, ul { padding: 0; list-style: none; }

img, svg, picture, video { display: block; max-width: 100%; }
img { height: auto; }

/* Any component that sets display:flex/grid on a class outbeats the UA's
   [hidden]{display:none} on specificity, which silently un-hides error
   messages and empty panels. Assert it once, globally. */
[hidden] { display: none !important; }

button, input, textarea, select {
  font: inherit;
  color: inherit;
  margin: 0;
}

table { border-collapse: collapse; width: 100%; }

:target { scroll-margin-top: clamp(88px, 12vh, 140px); }


/* ── Typography primitives ──────────────────────────────────────────────── */

.h-display,
h1, h2 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: var(--lh-display);
  letter-spacing: var(--tracking-display);
  text-transform: uppercase;
  text-wrap: balance;
}

h3 {
  font-family: var(--font-body);
  font-size: var(--t-h3);
  font-weight: 700;
  line-height: 1.2;
}

p { text-wrap: pretty; }

strong { font-weight: 650; }

em { font-style: italic; }

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}


/* ── Links ──────────────────────────────────────────────────────────────── */

a { color: inherit; }

.link-out {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  color: var(--red);
  font-weight: 600;
  text-decoration: none;
  /* Underline drawn as a border so it can thicken on hover without shifting
     the baseline the way text-decoration-thickness does. */
  box-shadow: inset 0 -2px 0 0 currentColor;
  transition: box-shadow var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.link-out:hover { box-shadow: inset 0 -6px 0 0 var(--yellow); }


/* ── Buttons ────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap-min);
  padding: 0 clamp(20px, 2.4vw, 34px);
  border: 2px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-size: clamp(.95rem, .88rem + .3vw, 1.15rem);
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.btn:active { transform: translateY(1px); }

.btn--solid {
  background: var(--red);
  border-color: var(--red);
  color: var(--paper);
}
.btn--solid:hover {
  background: var(--yellow);
  border-color: var(--yellow);
  color: var(--ink);
}

.btn--ghost {
  background: transparent;
  border-color: currentColor;
  color: var(--text-on-dark);
}
.btn--ghost:hover {
  background: var(--paper);
  border-color: var(--paper);
  color: var(--ink);
}
/* On the light sections the ghost button needs the dark ink, not paper. */
[data-logo="light"] .btn--ghost { color: var(--text-on-light); }
[data-logo="light"] .btn--ghost:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.btn[disabled] { cursor: not-allowed; opacity: .55; }


/* ── Focus ──────────────────────────────────────────────────────────────
   One ring, two palettes, chosen by the ground it lands on.

   Yellow plus a heavy black companion ring is right over the hero: it has to
   survive flat near-black AND mid-tone sepia artwork in the same section. On
   the paper sections it was the wrong instrument — a 3px yellow rectangle
   wrapped in 6px of solid black around a quiet underlined field is louder than
   the entire form it sits in, and it was the single thing making the form look
   crude the moment anyone typed in it. There, maroon on cream already carries
   7.4:1, so the ring is thin, the halo is a soft tint of the same colour, and
   the indicator reads as part of the design rather than as an alarm. */

:root {
  --focus-ring: var(--yellow);
  --focus-halo: rgba(11, 11, 11, .85);
  --focus-halo-w: 6px;
}
[data-logo="light"] {
  --focus-ring: var(--red);
  --focus-halo: rgba(160, 14, 14, .16);
  --focus-halo-w: 5px;
}

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
  box-shadow: 0 0 0 var(--focus-halo-w) var(--focus-halo);
  border-radius: var(--radius);
}
/* Never leave a control with no affordance — only remove the default where
   :focus-visible above has already replaced it. */
:focus:not(:focus-visible) { outline: none; }


/* ── Utilities ──────────────────────────────────────────────────────────── */

/* clip-path, not display:none — a display:none file input is unfocusable,
   which would strip keyboard access from every dropzone. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Clipped rather than translated out of view. A translate keeps the box in
   flow, so .skip-h — anchored to .about rather than the viewport — surfaced
   at the bottom of the hero on short screens. Clipping cannot do that. */
.skip-link,
.skip-h {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  padding: 0;
  background: var(--yellow);
  color: var(--ink);
  font-weight: 700;
  text-decoration: none;
  border-radius: var(--radius);
}
.skip-link:focus-visible,
.skip-h:focus-visible {
  position: fixed;
  left: var(--s-4);
  top: var(--s-4);
  z-index: var(--z-skip);
  width: auto; height: auto;
  overflow: visible;
  clip-path: none;
  padding: var(--s-3) var(--s-5);
}
