/* Design tokens. Palette derived from Ahmed's own logo artwork.
   Every text colour below is verified against both grounds by
   test/tokens-contrast.test.js. Do not edit a colour without re-running it. */

:root {
  /* Type. Source Serif 4 for prose, Public Sans for metadata,
     Amiri for the Arabic name only. */
  --font-prose: "Source Serif 4", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --font-meta: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-arabic: "Amiri", "Noto Naskh Arabic", "Segoe UI", serif;

  --text-xs: 0.8125rem;
  --text-sm: 0.9375rem;
  --text-base: 1.0625rem;
  --text-lg: 1.1875rem;
  --text-xl: clamp(1.375rem, 1.2rem + 0.9vw, 1.75rem);
  --text-2xl: clamp(2rem, 1.55rem + 2.2vw, 3.25rem);

  --leading-prose: 1.62;
  --leading-tight: 1.18;

  /* Space */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-12: 3rem;
  --space-16: clamp(3rem, 2rem + 5vw, 6rem);
  /* Section boundaries only. --space-16 pins to 96px top AND bottom above
     1280px, so every boundary was 192px of empty page with a hairline
     floating at its exact midpoint, belonging to neither section. Capping
     the ceiling at 4rem takes each desktop boundary from 192px to 128px. Both
     clamps resolve identically at 640px and below, so the token leaves mobile
     alone, where the boundary was already right. */
  --space-section: clamp(3rem, 2rem + 5vw, 4rem);

  /* Measure and gutters */
  --measure-prose: 34rem;
  --measure-wide: 46rem;
  --measure-nav: 58rem;
  --gutter: clamp(1.25rem, 0.5rem + 3vw, 4rem);

  /* Every photograph's height ceiling, wherever it appears. One number rather
     than three: the timeline capped singles at 30rem and Selected Work at
     26rem, and grid photographs had no ceiling at all, so a portrait rendered
     480px tall beside a landscape at 379 and the column alternated between
     wide-and-short and narrow-and-tall. 24rem is the height a landscape
     naturally reaches at the reading measure, so both shapes now land on the
     same line and only their widths differ — which is the most two different
     aspect ratios can agree on without cropping one of them. */
  --photo-cap: 24rem;

  --rule-width: 1px;
  --focus-width: 2px;

  /* Tells the user agent which form controls, scrollbars and default
     selection colours to render. Without it the UA assumes light, which is
     invisible in light mode and gives dark mode a light scrollbar track down
     a very long near-black page. */
  color-scheme: light;

  /* Light is the default and the primary theme.

     The accent is blue at hue ~218-224, which is the family the logo's own ink
     navy #1c1f32 (hue 232) already sits in — so it is still derived from the
     artwork rather than being a generic tech blue, and it is nowhere near the
     banned teals at hue 191. Worth knowing, since it was a deliberate trade:
     the earlier terracotta was the less predictable choice for a data
     scientist's page, and blue is the first colour anyone would guess for one.
     What buys it back is that this blue is his, and the warm skin tones in the
     logo now read as a deliberate contrast against it rather than as a match. */
  /* Was the warm #fafaf9. A warm off-white under a cool wash reads as cream,
     which the palette has never been allowed to be. Same lightness rotated
     onto the accent's side of neutral (C* 1.08, still near-zero), so every
     contrast figure is unchanged to three decimals. */
  --ground: #f9fafc;
  /* The wash: --ground pulled 6.1 dE toward the accent's own hue, painted
     over the document's first 46rem and fading out. The introduction sits on
     tinted air; the document below it is plain paper.

     It is the darkest ground any text sits on, so it is the one that has to
     clear AA, and test/tokens-contrast.test.js checks it as a ground in its
     own right. Worst case is accent at 5.86:1. The near-zero-chroma law is
     amended narrowly: chroma toward the accent hue only, never warm. */
  --ground-tint: #eaf0fb;
  --ground-wash: linear-gradient(180deg, var(--ground-tint) 0, var(--ground) 46rem);
  --ground-raised: #ffffff;
  --ink: #1c1f32;
  --ink-muted: #585b6b;
  --accent: #2959ae;
  --accent-strong: #21488c;
  /* Was the warm #e2e2df, which drew every hairline on the page — dividers,
     the timeline rail, pill and table borders — in the one colour family the
     design law bans elsewhere. Same weight (L* 89.80 against 89.81) rotated
     onto the accent's hue: nothing got heavier, it just stopped being beige. */
  --rule: #dee2ea;
  /* One step up from --rule, for the two outlined shapes that belong to the
     accent system rather than to page furniture: the hero pills and the year
     badges. At 1.54:1 on white it is unmistakably blue and still a hairline —
     too faint to make a pill look like a button, which is what DESIGN.md's
     "outlined rather than filled" protects. Never carries text. */
  --rule-accent: #c4d1e8;
  /* The plate under the availability line. One step deeper than --ground-tint
     so it reads as a raised object on the wash rather than a lighter patch of
     it: L* 91.3 against 94.6, at the accent's own hue. --ink clears 13.04:1
     on it. */
  --accent-plate: #dce7f9;
  /* Behind a third-party organisation mark that ships in one colourway only.
     On the light ground it is not needed, so it is not drawn; in dark mode the
     marks that need it are Khalifa (2.55:1 bare) and Daman (1.70:1).

     Three constraints, and the value is where they meet. Below --ink, so a
     decorative third-party chip is never the lightest thing on the page: it
     sits 14% of luminance under it. Near-zero chroma, which is the palette's
     stated law and where an earlier warm value at C* 4.47 went wrong. And a
     plate all three marks read on: Al Nahda 3.08:1, Khalifa 4.98:1, Daman
     7.36:1. Al Nahda is the one that pays, clearing 3.66:1 unplated, which is
     the known cost of one rule for three marks rather than a rule per mark.
     Never carries text, so it is exempt from the AA check the way --rule is. */
  --logo-ground: transparent;
  /* The hero portrait's ring. It used to be a 5px band of --ground-raised,
     which is #ffffff in light — byte-identical to the photograph's own studio
     backdrop — so the band merged into the picture and the shirt dissolved
     into the page with no boundary at all. It only ever read as the "two
     rings" DESIGN.md describes in dark, by accident. Decided: the band is
     the page ground in both themes and the ring is this, a hairline with real
     contrast. Rotated off the old warm #a5a49e onto --rule's blue-grey axis at
     the same lightness (L* 67.40 against 67.29). */
  --portrait-ring: #a0a4b0;
  /* The site itself never errs, so it never needed these; the admin does.
     Not derived from the accent hue like the rest of the palette — red is
     red regardless of a site's chosen blue, and test/tokens-contrast.test.js
     checks these for contrast, not for hue, for exactly that reason. Worst
     case across all six grounds is 5.71:1; against --ground itself, 6.26:1
     and 8.67:1. Darker is the emphasis step in light, matching --accent /
     --accent-strong. */
  --danger: #b3261e;
  --danger-strong: #8e1b16;
}

[data-theme="dark"] {
  color-scheme: dark;
  --ground: #15171f;
  /* The dark wash is the same gesture in the other direction: the ground
     lifted 7.6 dE toward the accent, as if the top of the page were catching
     a little light. Lighter is the risky direction for dark-mode contrast, so
     it is the ground every dark text token is measured against: ink 13.25:1,
     ink-muted 5.88:1, accent 7.50:1, accent-strong 9.05:1. A dark ground needs
     a bigger delta than a light one to read as tinted at all, which is why
     this number is not the light one. */
  --ground-tint: #1a1f30;
  --ground-raised: #1c1f2a;
  --ink: #e9e7e2;
  --ink-muted: #9a9aa6;
  --accent: #90b2df;
  --accent-strong: #a8c3e6;
  /* Already blue-grey, unlike the light one, so this is a small lift rather
     than a rotation: hsl 226, and 1.36:1 on the ground where it was 1.31:1.
     Dark hairlines were the fainter half of the pair. */
  --rule: #2b3040;
  --rule-accent: #374561;
  --accent-plate: #232b42;
  --portrait-ring: #52576b;
  --logo-ground: #d8d8d6;
  /* Lighter is the emphasis step in dark, matching --accent / --accent-strong.
     Against the ground, 9.00:1 and 10.53:1. */
  --danger: #f2a49d;
  --danger-strong: #ffb4ab;
}

/* The page is rendered by JavaScript, so js/theme.js always sets
   data-theme on <html> before paint. No prefers-color-scheme duplicate
   block is needed, which keeps the palette defined exactly twice. */

@media (prefers-contrast: more) {
  :root {
    --ink-muted: #3d4050;
    --rule: #93979f;
    /* The portrait's hairline used to be --rule, so it was strengthened here
       with every other hairline. Giving it its own token silently dropped it
       out of this block, leaving high-contrast readers a weaker ring than
       before. These track --rule: 2.81:1 light, 3.64:1 dark. */
    --portrait-ring: #93979f;
    /* A reader asking for more contrast wants fewer near-identical surfaces,
       so the plate stops being a tint and becomes the raised surface, bounded
       by the full accent that --rule-accent already becomes here. */
    --accent-plate: var(--ground-raised);
    /* The wash is the ground with a tint on it, and a reader asking for more
       contrast is asking for fewer near-identical surfaces, not more. Collapse
       it: the whole page goes to the flat ground, and the accent typography —
       which is what this proposal actually rests on — keeps every ratio it had.
       --rule-accent goes the other way and becomes the full accent, so a pill
       outline at 6.41:1 is the strongest it can be while staying blue. */
    --ground-tint: var(--ground);
    --rule-accent: var(--accent);
  }
  [data-theme="dark"] {
    --ink-muted: #c8c8d2;
    --accent-plate: var(--ground-raised);
    --rule: #6a7086;
    --portrait-ring: #6a7086;
    --ground-tint: var(--ground);
    --rule-accent: var(--accent);
  }
}

/* Print's ink-on-paper palette. Deliberately not the screen palette (which
   stays a warm off-white with earthy accents): a printed page is a different
   medium, and a recruiter's printer/toner budget wants plain black-on-white.
   These are consumed by css/print.css, which assigns them to the screen
   token names inside a `media="print"`-only stylesheet, so this is the only
   other place raw hex is allowed to live. */
:root {
  --print-ground: #ffffff;
  --print-ink: #111111;
  --print-ink-muted: #444444;
  --print-accent: #111111;
  --print-rule: #bbbbbb;
  /* .hero-portrait is the one image print keeps (css/print.css), so its ring
     needs a paper value or the dark one leaks onto the page: data-theme stays
     on <html> while printing. .entry-logo is hidden in print, so --logo-ground
     needs no print value. */
  --print-portrait-ring: #bbbbbb;
}
