/* ============================================================
   Typography System
   Font: Geist — Regular (400) & SemiBold (600), Google Fonts.
   Regular is the default; SemiBold is opt-in for emphasis.

   A neutral typographic scale: an ordered set of sizes, named
   only by relative size (xs → 7xl) — NOT by role. A size does
   not "belong" to a heading or a caption; use any size wherever
   it reads well, exactly as a print compositor picks a point
   size for a passage.

   Scale: base 12px, ×1.25 throughout (xs–5xl),
   built with "round-and-carry, snapped to even" — each step is
   multiplied, snapped to the nearest even number (2px grid), and
   that value is carried forward, so every size is divisible by 2.
   Sizes expressed in rem against a 16px root so they respect
   the user's browser font-size preference.
   ============================================================ */

:root {
  /* Font family */
  --font-sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;

  /* --- Type scale -------------------------------------------------
     token          px        ratio to previous step
     ---------------------------------------------------------------- */
  --text-xs:  0.75rem;  /* 12 px               */
  --text-sm:  1rem;     /* 16 px    ×1.25       */
  --text-md:  1.25rem;  /* 20 px    ×1.25       */
  --text-lg:  1.5rem;   /* 24 px    ×1.25       */
  --text-xl:  1.875rem; /* 30 px    ×1.25       */
  --text-2xl: 2.375rem; /* 38 px    ×1.25       */
  --text-3xl: 3rem;     /* 48 px    ×1.25       */
  --text-4xl: 3.75rem;  /* 60 px    ×1.25      */
  --text-5xl: 4.75rem;  /* 76 px    ×1.25      */
  --text-6xl: 6rem;     /* 96 px    ×1.25      */
  --text-7xl: 7.5rem;   /* 120 px   ×1.25      */

  /* --- Line heights — snapped to the 8px baseline grid -----------
     Each size's leading is a whole multiple of 8px (expressed in
     rem, so it's an absolute grid distance, not size-relative).
     The (n) is how many 8px grid cells tall each line is.        */
  --lh-xs:  1rem;    /* 16px  (2)  · 12 */
  --lh-sm:  1.5rem;  /* 24px  (3)  · 16 */
  --lh-md:  2rem;    /* 32px  (4)  · 20 */
  --lh-lg:  2rem;    /* 32px  (4)  · 24 */
  --lh-xl:  2.5rem;  /* 40px  (5)  · 30 */
  --lh-2xl: 3rem;    /* 48px  (6)  · 38 */
  --lh-3xl: 3.5rem;  /* 56px  (7)  · 48 */
  --lh-4xl: 4rem;    /* 64px  (8)  · 60 */
  --lh-5xl: 5rem;    /* 80px  (10) · 76 */
  --lh-6xl: 6.5rem;  /* 104px (13) · 96 */
  --lh-7xl: 8rem;    /* 128px (16) · 120 */

  /* Single-line UI labels (nav, byline, chips, buttons) want tight
     leading — the reading --lh-* above are tuned for running text and
     look far too airy on a one-line label. This is a RATIO, not a grid
     value: use it only for single-line labels, never for body copy. */
  --lh-tight: 1.2;

  /* --- Letter spacing — tracking tightens as type grows (optical).
     Uppercase labels loosen; body sits at zero; display pulls in.  */
  --tracking-wide:     0.06em;  /* uppercase labels, eyebrows        */
  --tracking-normal:   0;       /* body & small text (xs–lg)         */
  --tracking-tight:   -0.02em;  /* heading (xl) + 16px body labels   */
  --tracking-snug:    -0.03em;  /* heading (2xl)                     */
  --tracking-tighter: -0.05em;  /* large headings & display (3xl–7xl) · Figma −6px@120 */

  /* --- Weights — Regular is the default; SemiBold is opt-in ----- */
  --weight-regular:  400;
  --weight-semibold: 600;
}

/* One ×1.25 scale everywhere — a single ratio end to end, no
   desktop/mobile split. The largest steps (96, 120) are hero sizes;
   on narrow screens keep them to short words, or clamp() them.

   =================================================================
   HOW TO USE — every page links this file and sets type ONLY from
   here. Apply a .text-* utility class (preferred), or reference the
   raw --text-* / --lh-* tokens in component CSS. Never hard-code a
   px font-size or line-height anywhere else.
   ================================================================= */

/* Base: Geist is the document font wherever this file is loaded. */
body { font-family: var(--font-sans); }

/* Type utilities — each pairs a size with its baseline-grid leading
   AND its optical tracking (tighter as the size grows). */
.text-xs  { font-size: var(--text-xs);  line-height: var(--lh-xs);  letter-spacing: var(--tracking-normal); }
.text-sm  { font-size: var(--text-sm);  line-height: var(--lh-sm);  letter-spacing: var(--tracking-normal); }
.text-md  { font-size: var(--text-md);  line-height: var(--lh-md);  letter-spacing: var(--tracking-normal); }
.text-lg  { font-size: var(--text-lg);  line-height: var(--lh-lg);  letter-spacing: var(--tracking-normal); }
.text-xl  { font-size: var(--text-xl);  line-height: var(--lh-xl);  letter-spacing: var(--tracking-tight); }
.text-2xl { font-size: var(--text-2xl); line-height: var(--lh-2xl); letter-spacing: var(--tracking-snug); }
.text-3xl { font-size: var(--text-3xl); line-height: var(--lh-3xl); letter-spacing: var(--tracking-tighter); }
.text-4xl { font-size: var(--text-4xl); line-height: var(--lh-4xl); letter-spacing: var(--tracking-tighter); }
.text-5xl { font-size: var(--text-5xl); line-height: var(--lh-5xl); letter-spacing: var(--tracking-tighter); }
.text-6xl { font-size: var(--text-6xl); line-height: var(--lh-6xl); letter-spacing: var(--tracking-tighter); }
.text-7xl { font-size: var(--text-7xl); line-height: var(--lh-7xl); letter-spacing: var(--tracking-tighter); }

/* Weight utilities — Regular is the document default; add .font-semibold
   to emphasise (labels, active states, a heavier hero line). */
.font-regular  { font-weight: var(--weight-regular); }
.font-semibold { font-weight: var(--weight-semibold); }

/* Tracking overrides — the .text-* classes already carry optical
   tracking by size; use these only for exceptions, chiefly for
   UPPERCASE labels (wide) or to reset a heading to neutral. */
.tracking-wide   { letter-spacing: var(--tracking-wide); }
.tracking-normal { letter-spacing: var(--tracking-normal); }

/* Leading override — tight line-height for single-line UI labels
   (nav, byline, chips, buttons), where the reading --lh-* is too airy. */
.leading-tight { line-height: var(--lh-tight); }

/* Line-wrapping — the title rule -----------------------------------
   TITLES: never let a single word drop alone onto the last line.
   `balance` evens the line lengths of a short heading, so the last
   line always carries its weight (no orphan word). Meant for
   titles/headings only — the browser caps it to a handful of lines.
   Apply .text-balance to any display/heading element.

   For long-form BODY copy, use .text-pretty instead: it keeps normal
   line-breaking and only steps in to prevent a lone last word. */
.text-balance { text-wrap: balance; }
.text-pretty  { text-wrap: pretty; }

/* ============================================================
   Section headings — one step down on small screens.

   Every section header on About and Work shares one recipe: --text-3xl
   (48px) on --lh-tight with --tracking-tighter. At 48px those run to two
   and three lines on a phone and crowd the content under them, so below
   640px they drop one step of the scale, to --text-2xl (38px).

   Tracking steps WITH the size: the scale pairs 2xl with --tracking-snug
   (−0.03em), so keeping --tracking-tighter (−0.05em, the 3xl step) would
   leave 38px text over-tightened. Line-height stays --lh-tight, which is
   a ratio for single-line labels and so scales on its own.

   640px is the page's existing small-screen step — the hero headline
   already drops a size there (about.html / work.html).

   HEADERS COME IN PAIRS — a black `__title`/`__name` and a grey
   `__subject`/`__link` sitting on the same line, BOTH on the 3xl recipe. Miss
   one half and the pair renders at two different sizes on the same line, so
   every pair is listed together below. That is also why this covers Home and
   Essays: the contact and archive headers are shared components, and stepping
   one page's copy of them would split the pair or split the site.

   THE LIST IS ENUMERATED BY CLASS NAME, like the one in media.css: a new
   section-header class must be added here or it keeps the desktop size.

   THE `html` PREFIX IS DELIBERATE. This file is a BASE layer, linked before
   every component stylesheet, and each of the rules below is overriding is a
   plain class (0,1,0) — the same weight. On equal specificity the later
   sheet wins, so archive.css, profile.css, quotes.css and about.html's own
   <style> would all beat a bare `:is(…)` here. `html` adds an element to the
   selector (0,1,1) so this lands regardless of link order, without resorting
   to !important or duplicating the rule into six component files.
   ============================================================ */
@media (max-width: 640px) {
  html :is(
    .section-heading,                        /* About — "History", "Background"   */
    .gallery__label,                         /* Work — "Recent personal work" …   */
    .archive__title,     .archive__subject,  /* About + Work — "Photography"      */
    .profile__name,      .profile__subject,  /* About — "About me / by Gallup"    */
    .quotes__title,      .quotes__subject,   /* About — "About me / by others"    */
    .ledger__name,       .ledger__subject,   /* Work — the numbers header         */
    .contact__title,     .contact__link,     /* Work + Home — "Get in touch"      */
    .essays__title,      .essays__subject,   /* Essays                            */
    .recent__name,       .recent__subject    /* Home — "Recent"                   */
  ) {
    font-size: var(--text-2xl);          /* 38px — one step down from 3xl */
    letter-spacing: var(--tracking-snug); /* the 2xl step (−0.03em)        */
  }
}

