/* AKINTADE production base: reset, focus, type roles, masks and the nav. Tokens are in tokens.css.
   Ported from 05-Motion-Prototype/css/base.css; changes: type sizes in rem (tokens), the nav band height is a
   token (it grows on 2560+ screens), and reading text is capped at --measure. */


*, *::before, *::after { box-sizing: border-box; }
/* hidden means gone, whatever layout a component sets for itself (the phone "Provly, opened." block is a flex column) */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100svh; color: var(--ink); font-family: var(--sans); font-weight: 400;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; overflow-x: clip;
  /* paper: fibre noise and slow mineral mottling, drawn once as tiles, no blend modes. The mottling was a 1400 x 1000
     SVG noise tile whose edges did not meet (its noise was stitched to a filter region 10 percent larger than the
     tile), leaving a faint seam every 1000 px. It is now that same tile, rasterised as drawn, with only a band along
     each edge blended so the edges meet: _build/make_paper_tile.py */
  background-color: var(--paper);
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='420' height='420'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.24  0 0 0 0 0.21  0 0 0 0 0.17  0 0 0 0.10 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"),
    url("/assets/paper-mottle.webp");
  background-size: 420px 420px, 1400px 1000px;
  transition: background-color 0s;              /* the world changes as a cut, never a fade */
}
img, video, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
p, h1, h2, h3, ol, ul, dl, dd, figure { margin: 0; padding: 0; }
h1, h2, h3 { font-size: inherit; font-weight: inherit; }
ol, ul { list-style: none; }

/* focus: always visible, drawn as a hairline frame in the ink, never a browser glow */
:focus { outline: none; }
:focus-visible { outline: 1.5px solid var(--accent); outline-offset: 4px; border-radius: 2px; }
[data-world="cinema"] :focus-visible { outline-color: var(--on-cinema); }
/* headings and regions that receive focus only so a screen reader starts there: no frame */
h1[tabindex="-1"]:focus-visible, h2[tabindex="-1"]:focus-visible, main:focus-visible, section[tabindex="-1"]:focus-visible { outline: none; }

/* white-space: pre, not nowrap (P06 fix pack): it still never wraps, but it keeps a space at the edge of a hidden span
   (" by email", "Hire me on "), which nowrap collapsed, so a screen reader's browse mode joined the words ("briefby") */
.sr-only { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: pre; border: 0; }
.skip { position: absolute; left: var(--m); top: 8px; z-index: 100; padding: 8px 12px; background: var(--ink); color: var(--paper);
  font: 500 0.8125rem/1 var(--sans); transform: translateY(-160%); transition: transform var(--t-micro) var(--expo); }
.skip:focus-visible { transform: none; }

/* the grid: 12 columns, lines at the gutter centres at about 6 percent ink */
.grid-bg { position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background-image: linear-gradient(to right, var(--grid) 0 1px, transparent 1px);
  background-size: calc((100% - 2 * var(--m) + var(--g)) / 12) 100%;
  background-position: calc(var(--m) - var(--g) / 2) 0; }
[data-world="cinema"] .grid-bg { background-image: linear-gradient(to right, rgba(232, 226, 213, 0.045) 0 1px, transparent 1px); }
.cross { position: absolute; width: 11px; height: 11px; transform: translate(-5px, -5px); pointer-events: none; }
.cross::before, .cross::after { content: ''; position: absolute; background: rgba(31, 30, 27, 0.38); }
.cross::before { left: 5px; top: 0; width: 1px; height: 11px; }
.cross::after { top: 5px; left: 0; height: 1px; width: 11px; }
.rule-h { position: absolute; left: 0; right: 0; height: 1px; background: var(--grid); pointer-events: none; }

/* type */
.display { font-family: var(--serif); font-weight: 600; letter-spacing: -0.05em; line-height: 0.9; margin: 0; }
.display em, .h em { font-style: italic; font-weight: 400; letter-spacing: -0.055em; }
.h { font-family: var(--serif); font-weight: 600; letter-spacing: -0.045em; line-height: 1.0; }
.label { font-family: var(--mono); font-weight: 400; font-size: var(--fs-label); letter-spacing: 0.15em; text-transform: uppercase; line-height: 1.55; }
.label.dim, .label .dim { color: var(--ink-3); }
.body { font-family: var(--sans); font-size: var(--fs-body); line-height: 1.5; letter-spacing: -0.006em; color: var(--ink-2); max-width: var(--measure); }
.small { font-family: var(--sans); font-size: var(--fs-small); line-height: 1.45; color: var(--ink-2); }
.wordmark { font-family: var(--sans); font-weight: 600; font-size: var(--fs-wordmark); letter-spacing: 0.26em; text-transform: uppercase; }
.link { font-family: var(--sans); font-weight: 500; font-size: var(--fs-link); letter-spacing: -0.005em; color: var(--ink);
  background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat; padding-bottom: 3px; white-space: nowrap;
  transition: background-size var(--t-micro) var(--expo); }
.link:hover { background-size: 0% 1px; background-position: 100% 100%; }
/* a unit of metadata that may move to the next line but never breaks inside */
.nw { white-space: nowrap; }
/* protected phrases (P06 200% text fix, 7 Oct 2026): when a [data-fit] text does not fit its column (enlarged text,
   zoom, text spacing), js/keep.js sets each phrase its copy joins with no-break spaces as a .keep run: an inline-block,
   placed whole while it fits and wrapping at its own spaces when it is wider than the column, never inside a word. */
.flow .keep { display: inline-block; }
/* hit areas: small links keep their look but answer to a 44 px tall target (WCAG 2.5.8 asks 24; 44 is the aim) */
.nav a, .link { position: relative; }
.nav a::after, .link::after { content: ''; position: absolute; left: -6px; right: -6px; top: 50%; height: 44px; transform: translateY(-50%); }
.placeholder { font-family: var(--mono); font-size: 0.6875rem; letter-spacing: 0.08em; color: var(--accent); }

/* type that rises from a mask */
/* the reveal mask. Top headroom (Newsreader, 7 Oct 2026): its ascenders reach 0.744 em above the baseline and a 0.9 line box
   ends 0.685 em above it, so the mask cut the tops off "I", "f", "k". 0.08 em of padding is cancelled by margins so no glyph
   and no box moves: -0.08 em on top, -0.24 em below (two negative sibling margins collapse to the larger one), and the last
   line keeps -0.16 em so each heading keeps its height. */
.line { display: block; overflow: hidden; padding: 0.08em 0.06em 0.16em 0; margin: -0.08em 0 -0.24em; }
.line:last-child { margin-bottom: -0.16em; }
.line > span, .line > em { display: inline-block; will-change: transform; }
.mask-pre .line > * { transform: translateY(135%); opacity: 0; }
.mask-in .line > * { transform: none; opacity: 1; transition: transform var(--t-type) var(--expo), opacity 240ms var(--expo); transition-delay: calc(var(--i, 0) * var(--stagger)); }
.mask-out .line > * { transform: translateY(-135%); opacity: 0; transition: transform var(--t-type-out) var(--expo), opacity 320ms var(--expo); transition-delay: calc(var(--i, 0) * 50ms); }
.mask-out-down .line > * { transform: translateY(135%); opacity: 0; transition: transform var(--t-type-out) var(--expo), opacity 320ms var(--expo); transition-delay: calc(var(--i, 0) * 50ms); }

/* fade up for metadata, rules that draw left to right */
.fade-pre { opacity: 0; transform: translateY(10px); }
.fade-in { opacity: 1; transform: none; transition: opacity 700ms var(--expo), transform 900ms var(--expo); transition-delay: calc(var(--i, 0) * 70ms + var(--d, 0ms)); }
.draw { transform-origin: 0 50%; }
.draw-pre { transform: scaleX(0); }
.draw-in { transform: scaleX(1); transition: transform var(--t-rule) var(--expo); transition-delay: var(--d, 0ms); }

/* nav: wordmark, two places, one action. Scrolls with the page. */
.nav { position: absolute; top: 0; left: 0; right: 0; height: var(--nav-h); z-index: 30; display: flex; align-items: center; padding: 0 var(--m); }
.nav .wordmark { margin-right: auto; }
.nav .places { position: absolute; left: calc(var(--m) + 6 * var(--u) - var(--g) / 2 + 12px); display: flex; gap: 40px; }
.nav .places a, .nav .places span { color: var(--ink-3); transition: color var(--t-micro) var(--expo); }
.nav .places a[aria-current="page"], .nav .places .here, .nav .places a:hover { color: var(--ink); }
.nav .places .num { color: var(--ink); }
.nav-rule { position: absolute; left: 0; right: 0; top: var(--nav-h); height: 1px; background: var(--grid); }
@media (max-width: 819px) {
  /* at normal sizes one row, as before; with enlarged text the brief link may drop to a second line (WCAG 1.4.4) */
  .nav { height: auto; min-height: 64px; flex-wrap: wrap; row-gap: 4px; }
  .nav .places { position: static; margin-right: 18px; gap: 18px; }
  .nav .wordmark { font-size: 0.6875rem; letter-spacing: 0.22em; }
  .nav .brief { font-size: 0.8125rem; }
  .nav .places .opt, .nav .places .num { display: none; }
  .nav-rule { top: 64px; }
}

.view { position: relative; z-index: 1; }
.view[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0ms !important; transition-delay: 0ms !important; animation: none !important; }
  .mask-pre .line > *, .fade-pre, .draw-pre { transform: none; opacity: 1; }
}
