/* ==========================================================================
   Datum — a design-led architecture / interior-architecture studio template
   A Templatorium template · https://templatorium.com

   The idea in one line: a studio filed like a drawing set. Graphite on plaster,
   a visible drafting grid, projects catalogued as title-block plates, the red
   pencil used exactly once.

   HOW TO RE-THEME (the 30-second version — full guide in docs/README.md):
   every color, font, and size is a custom property in the :root block below.
   Change the values there and the whole site follows. Everything under the
   tokens is structure; you rarely need to touch it.

   A promise this template keeps: every text/background pair in the shipped
   palette meets WCAG 2.2 AA, computed (not eyeballed). Graphite on plaster is
   15.58:1; the red-pencil annotation on plaster is 5.34:1. If you change a
   color, re-check it: https://webaim.org/resources/contrastchecker/
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS — the re-theme contract (the color surface the builder rewrites)
   -------------------------------------------------------------------------- */
:root {
  /* Color story: an achromatic drawing sheet — light plaster, drafted in
     graphite, corrected once in red pencil. The ONE warm accent (--redline)
     is rationed to hairline drawing-markup and NEVER paints a button or a
     fill: the buy-action is ink, on purpose (see docs/README.md § "the red
     pencil"). If more than ~3% of a screen is red, something is wrong. */
  --plaster:      #F4F2ED; /* page ground — "the sheet" */
  --surface:      #EAE7DF; /* alt bands, title-block field fills */
  --ink:          #1A1A18; /* graphite — body, headings, PRIMARY CTA fill (15.58 on plaster) */
  --concrete:     #655F58; /* secondary text, register minor columns (5.63 on plaster · 5.10 on surface) */
  --rule:         #C9C4B8; /* drafting-grid lines, sheet frame, dividers, registration marks (decorative) */
  --redline:      #B23A1E; /* ANNOTATION ONLY, <3% — active-row underline, dimension ticks, section-cut mark (5.34 on plaster) */

  /* The one dark pacing ground (CTA bands, the footer, next-sheet). Text
     reverses to plaster (15.58 on ink). */
  --ink-ground:   #1A1A18;
  --ink-line:     #3A3834; /* hairlines/dividers on the ink ground (decorative) */
  --ink-muted:    #B4AFA5; /* secondary text on the ink ground (7.98 on ink) */
  --redline-tint: #E3B4A8; /* the red-pencil mark, lightened to read on the ink ground (9.43 on ink) */

  /* Form input borders need >= 3:1 against the page; the hairline --rule is too
     faint, so inputs use --concrete (5.63). Graphite on focus. */
  --input-border: #655F58;

  /* Type. Three vendored faces, self-hosted as woff2 — zero runtime requests.
     Big Shoulders Display: a CONDENSED-tall monumental grotesque drawn for
     civic wayfinding (deliberately the opposite width axis from Interval's
     Archivo Expanded). Archivo: regular-width body. IBM Plex Mono: the machine
     data — title blocks, sheet numbers, coordinates, areas, status. */
  --font-display: "Big Shoulders Display", "Arial Narrow", sans-serif;
  --font-body:    "Archivo", system-ui, -apple-system, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;

  /* Scale. The display-to-body jump is >= 3x on purpose — the masthead runs to
     132px against 16px body, with the mono data as a third register. */
  --t-display: clamp(48px, 9vw, 132px);  /* masthead wordmark, UPPERCASE */
  --t-h2:      clamp(30px, 4.5vw, 60px); /* section heads */
  --t-h3:      20px;
  --t-body:    16px;
  --t-small:   14px;
  --t-data:    12px;  /* mono title-block / register data */
  --t-label:   11px;  /* mono uppercase eyebrow / sheet code */

  /* Space & structure. --max is wider (1320) and more technical than the house
     default — a drawing sheet is a wide field. */
  --sp-section: clamp(72px, 10vw, 120px); /* section rhythm */
  --gutter:     24px;
  --max:        1320px;
  --sheet-pad:  clamp(20px, 3.2vw, 48px); /* air inside the sheet frame */

  /* Radius is 0 EVERYWHERE. Technical drawings are square; a rounded corner
     breaks the drafted register instantly. */
}

/* --------------------------------------------------------------------------
   2. FONT FACES — vendored variable woff2, one file per family with a weight
      RANGE (md5-verified distinct; Google often serves identical files per
      named weight — a variable range avoids the duplicate download).
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Big Shoulders Display";
  src: url("../fonts/big-shoulders-display-variable.woff2") format("woff2");
  font-weight: 500 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-variable.woff2") format("woff2");
  font-weight: 400 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/ibm-plex-mono-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/ibm-plex-mono-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

/* --------------------------------------------------------------------------
   3. RESET & BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }
/* Sticky-nav lesson: in-page anchors must clear the solid nav */
[id] { scroll-margin-top: 92px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  /* full-bleed plates use 100vw; clip (not hidden — keeps sticky nav working)
     stops that from creating a horizontal scrollbar */
  overflow-x: clip;
  background-color: var(--plaster);
  /* Subtle paper grain — a texture layer BEHIND content (not a fixed overlay
     over text), so it never taxes text contrast. Zero gradients anywhere. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.025'/%3E%3C/svg%3E");
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.6;
  font-variant-numeric: tabular-nums; /* every column snaps to the digit */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { max-width: 100%; display: block; }
a { color: inherit; }

/* Focus is visible on EVERY ground. Light grounds: 3px graphite (15.58 as a
   non-text indicator). The ink ground overrides to plaster below. The redline
   may appear only as a decorative inner hairline, never the sole indicator.
   Never outline:none — anywhere. */
:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}
.band--ink :focus-visible,
.site-footer :focus-visible { outline-color: var(--plaster); }

/* Layout primitives */
.wrap { max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--sp-section); }

/* Builder grounds — the browser editor flips a section's background band. A
   section with NO data-ground renders exactly as its class always has; the
   element+attribute selector (specificity 0,1,1) overrides a section's own
   background. The two light grounds keep graphite text, so every readable pair
   is palette-independent and clears AA (verified in pipeline/builder/contrast.mjs). */
section[data-ground="plaster"] { background-color: var(--plaster); }
section[data-ground="surface"] { background-color: var(--surface); }
section[data-ground="ink"] { background-color: var(--ink-ground); color: var(--plaster); }

.skip-link {
  position: absolute; left: var(--gutter); top: -100px; z-index: 100;
  background: var(--ink); color: var(--plaster);
  font: 500 var(--t-small) var(--font-body);
  padding: 10px 18px; text-decoration: none;
}
.skip-link:focus { top: 12px; }

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

/* --------------------------------------------------------------------------
   4. THE SHEET FRAME + DRAFTING GRID — the "we are inside a drawing" signal.
      Every page's main column sits in a 1px rule border with L-bracket corner
      registration marks and a faint 12-column drafting underlay.
   -------------------------------------------------------------------------- */
/* The sheet is <main> itself (so every section stays a direct child of <main>,
   which the builder requires). Sections own their vertical rhythm; the sheet
   owns the frame, the corner marks, the drafting underlay, and the horizontal
   air. Full-bleed plates break OUT of it with margin-inline: calc(50% - 50vw). */
.sheet {
  position: relative;
  max-width: var(--max);
  margin-inline: auto;
  border: 1px solid var(--rule);
  padding-inline: var(--sheet-pad);
  /* faint drafting underlay: two anchor axes (cols 3 and 9) kept just visible,
     like a drawing sheet showing its grid. Behind content, very low contrast. */
  background-image:
    linear-gradient(90deg, transparent calc(25% - 0.5px), color-mix(in srgb, var(--rule) 55%, transparent) 25%, transparent calc(25% + 0.5px)),
    linear-gradient(90deg, transparent calc(75% - 0.5px), color-mix(in srgb, var(--rule) 55%, transparent) 75%, transparent calc(75% + 0.5px));
  background-repeat: no-repeat;
}
/* L-bracket crop marks at the four corners */
.sheet::before { content: ""; position: absolute; top: -1px; left: -1px; width: 14px; height: 14px; border-top: 2px solid var(--ink); border-left: 2px solid var(--ink); pointer-events: none; }
.sheet::after  { content: ""; position: absolute; bottom: -1px; right: -1px; width: 14px; height: 14px; border-bottom: 2px solid var(--ink); border-right: 2px solid var(--ink); pointer-events: none; }
.crop-tr { position: absolute; top: -1px; right: -1px; width: 14px; height: 14px; border-top: 2px solid var(--ink); border-right: 2px solid var(--ink); pointer-events: none; }
.crop-bl { position: absolute; bottom: -1px; left: -1px; width: 14px; height: 14px; border-bottom: 2px solid var(--ink); border-left: 2px solid var(--ink); pointer-events: none; }

/* The datum line — a single horizontal hairline across every masthead, THE
   reference the wordmark is named for. Small dimension ticks hang from it; a
   redline tick is a sanctioned <3% moment. */
.datum-line {
  position: relative;
  height: 1px; background: var(--rule);
  margin: clamp(20px, 3vw, 34px) 0;
}
.datum-line::before {
  /* a short redline dimension tick — the red pencil, used once, on the datum */
  content: ""; position: absolute; left: 0; top: -4px;
  width: 1px; height: 9px; background: var(--redline);
}
.datum-line .tick {
  position: absolute; top: -3px; width: 1px; height: 7px; background: var(--concrete);
}
.datum-line .tick:nth-of-type(1) { left: 16%; }
.datum-line .tick:nth-of-type(2) { left: 50%; }
.datum-line .tick:nth-of-type(3) { left: 84%; }

/* --------------------------------------------------------------------------
   5. TYPE ROLES — Big Shoulders display (uppercase), Archivo body, Plex Mono
      data. No italics anywhere: emphasis is structural (the grid, the frame,
      the redline mark), never a slanted word.
   -------------------------------------------------------------------------- */
h1, .h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-display);
  line-height: 0.92;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}
h2, .h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-h2);
  line-height: 0.98;
  letter-spacing: -0.005em;
  text-transform: uppercase;
}
h3, .h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--t-h3);
  line-height: 1.3;
}
p { max-width: 68ch; }
.lede { font-size: 19px; line-height: 1.55; color: var(--ink); max-width: 56ch; }
.muted { color: var(--concrete); }

/* Mono sheet code / eyebrow — "A-101 · GENERAL ARRANGEMENT" */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--concrete);
  display: block;
  margin-bottom: 20px;
}
/* Mono utility label (case per author) */
.mono {
  font-family: var(--font-mono);
  font-size: var(--t-data);
  letter-spacing: 0;
}
.mono-label {
  font-family: var(--font-mono);
  font-size: var(--t-label);
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--concrete);
}
/* Data / figures — always mono, tabular */
.fig { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* The section-cut / revision mark beside a heading — a sanctioned redline
   moment (a small glyph, well under 3%). */
.cut-mark { color: var(--redline); font-family: var(--font-mono); font-weight: 500; }

/* --------------------------------------------------------------------------
   6. BUTTONS — the buy-action is INK. There is no coloured button anywhere.
      Primary: solid graphite, plaster text (15.58). On the ink ground it
      inverts: plaster fill, graphite text. Secondary: 1px graphite outline.
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  font: 600 15px/1.1 var(--font-body);
  letter-spacing: 0.01em;
  padding: 14px 24px;
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.btn .arrow { font-family: var(--font-mono); }
.btn--primary { background: var(--ink); color: var(--plaster); border-color: var(--ink); }
.btn--primary:hover { background: #000; border-color: #000; }
.btn--secondary { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn--secondary:hover { background: var(--ink); color: var(--plaster); }
/* On the ink ground the primary inverts to plaster fill / graphite text */
.btn--inverse { background: var(--plaster); color: var(--ink); border-color: var(--plaster); }
.btn--inverse:hover { background: var(--surface); border-color: var(--surface); }

.btn-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

.arrow-link {
  font: 500 14px/1.3 var(--font-body);
  color: var(--ink);
  text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px;
}
.arrow-link:hover { text-decoration-color: var(--redline); }
.arrow-link .arrow { font-family: var(--font-mono); }
.band--ink .arrow-link { color: var(--plaster); }

/* --------------------------------------------------------------------------
   7. NAV — solid plaster, 1px rule border, registration marks in the top
      corners, DATUM in Big Shoulders, an ink "Enquire" button. No glass.
   -------------------------------------------------------------------------- */
.nav {
  position: sticky; top: 0; z-index: 40;
  background: var(--plaster);
  border-bottom: 1px solid var(--rule);
}
.nav .wrap { display: flex; align-items: center; gap: 28px; min-height: 72px; position: relative; }
/* registration marks in the nav's top corners */
.nav .wrap::before, .nav .wrap::after {
  content: ""; position: absolute; top: 6px; width: 9px; height: 9px; pointer-events: none;
}
.nav .wrap::before { left: var(--gutter); border-top: 1px solid var(--rule); border-left: 1px solid var(--rule); }
.nav .wrap::after  { right: var(--gutter); border-top: 1px solid var(--rule); border-right: 1px solid var(--rule); }
.wordmark {
  font-family: var(--font-display);
  font-weight: 700; font-size: 26px; letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink); text-decoration: none; margin-right: auto;
}
.nav-links { display: flex; gap: 26px; list-style: none; }
.nav-links a {
  font: 500 14px/1 var(--font-body); color: var(--ink); text-decoration: none; padding-block: 8px;
}
.nav-links a:hover, .nav-links a[aria-current="page"] {
  text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px;
}
.nav-actions { display: flex; align-items: center; gap: 18px; }
.nav-toggle {
  display: none; background: none; border: 1px solid var(--ink);
  min-width: 44px; min-height: 44px; padding: 0 12px;
  align-items: center; justify-content: center; cursor: pointer;
}
.nav-toggle .bars { display: block; width: 18px; height: 2px; background: var(--ink); box-shadow: 0 6px 0 var(--ink), 0 -6px 0 var(--ink); }

/* --------------------------------------------------------------------------
   8. THE TITLE-BLOCK SYSTEM — a boxed corner block in Plex Mono holding sheet
      metadata. The recurring structural motif, bottom-right of mastheads and
      on every project page.
   -------------------------------------------------------------------------- */
.titleblock {
  border: 1px solid var(--rule);
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: var(--t-data);
  line-height: 1.5;
  max-width: 340px;
}
.titleblock .tb-head {
  border-bottom: 1px solid var(--rule);
  padding: 10px 14px;
  font-weight: 500; letter-spacing: 0.10em; text-transform: uppercase; color: var(--ink);
}
.titleblock dl { display: grid; grid-template-columns: auto 1fr; }
.titleblock dt {
  padding: 7px 14px; color: var(--concrete);
  letter-spacing: 0.06em; text-transform: uppercase; font-size: var(--t-label);
  border-bottom: 1px solid var(--rule);
}
.titleblock dd {
  padding: 7px 14px; color: var(--ink); text-align: right;
  border-bottom: 1px solid var(--rule); border-left: 1px solid var(--rule);
}
.titleblock .row-last dt, .titleblock .row-last dd { border-bottom: 0; }

/* --------------------------------------------------------------------------
   9. MASTHEAD — the monumental wordmark overshoots the grid into the margin;
      the datum line spans below it; the title block sits alone bottom-right.
      Intentional asymmetry (gate item).
   -------------------------------------------------------------------------- */
.masthead { padding-block: clamp(40px, 6vw, 84px) var(--sp-section); }
.masthead .display {
  font-family: var(--font-display);
  font-weight: 700; font-size: var(--t-display); line-height: 0.9;
  letter-spacing: -0.01em; text-transform: uppercase;
  margin-left: -0.04em; /* overshoot the grid edge */
}
.masthead .lede { margin-top: clamp(20px, 3vw, 30px); }
.masthead-foot {
  display: grid; grid-template-columns: 1fr auto; gap: 28px; align-items: end;
  margin-top: clamp(28px, 4vw, 44px);
}
.masthead-foot .titleblock { justify-self: end; }

/* Interior page mastheads — same structure, smaller stakes */
.page-head { padding-block: clamp(36px, 5vw, 64px) clamp(28px, 4vw, 44px); }
.page-head .display { font-size: clamp(40px, 7vw, 96px); }

/* --------------------------------------------------------------------------
   10. PLATE — the image module. Sparse, large, austere. 1px rule frame, 0
       radius, a corner FIG./sheet caption in Plex Mono. Ships as an
       art-directed PLACEHOLDER that is itself a designed drawing plate (a
       faint plan/section motif + PLATE · ratio · slot name). Never a white box
       with a soft shadow; never bundled stock. Buyer photos render duotone.
   -------------------------------------------------------------------------- */
.plate {
  position: relative;
  border: 1px solid var(--rule);
  background: var(--surface);
  overflow: hidden;
}
/* The empty-state is a REAL drafting plate, never a bare centred box: a faint
   plan/section line drawing — a ground line, a stepped building section, two
   column axes, a dimension line with end ticks, and a grid bubble (the same
   line-art vocabulary as the project-page .plan-drawing). It is masked out of
   --rule, so it re-themes with the palette and never touches text contrast; it
   sits BEHIND everything and retires the instant a buyer photo fills the plate.
   ~12% effective (low-value --rule at 0.6 alpha over --surface). */
.plate::before {
  content: "";
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-color: var(--rule);
  opacity: 0.6;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 260' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke-width='1' d='M96 44V214M224 44V214'/%3E%3Cpath d='M40 190H280'/%3E%3Cpath d='M64 190V128L128 96L192 132V190M192 132L232 112V190M232 112L280 136'/%3E%3Cpath stroke-width='1' d='M40 190V206M280 190V206M40 202H280M46 199L40 202L46 205M274 199L280 202L274 205'/%3E%3Ccircle cx='128' cy='72' r='9' stroke-width='1'/%3E%3C/svg%3E") center / cover no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 260' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke-width='1' d='M96 44V214M224 44V214'/%3E%3Cpath d='M40 190H280'/%3E%3Cpath d='M64 190V128L128 96L192 132V190M192 132L232 112V190M232 112L280 136'/%3E%3Cpath stroke-width='1' d='M40 190V206M280 190V206M40 202H280M46 199L40 202L46 205M274 199L280 202L274 205'/%3E%3Ccircle cx='128' cy='72' r='9' stroke-width='1'/%3E%3C/svg%3E") center / cover no-repeat;
}
/* a dropped-in photo (the injector swaps the placeholder for an <img>) hides the
   motif so it never bleeds through the image */
.plate:has(img)::before { display: none; }
.plate--45 { aspect-ratio: 4 / 5; }
.plate--32 { aspect-ratio: 3 / 2; }
.plate--169 { aspect-ratio: 16 / 9; }
.plate--11 { aspect-ratio: 1 / 1; }
/* the placeholder spec label — anchored to the TOP-LEFT corner as a drawing
   annotation (never place-items:center / text-align:center, the named
   "centred-label-in-empty-box" generic tell). The FIG. caption tab holds the
   opposite bottom-left corner. Set on a solid --surface chip so the mono label
   reads at full --concrete contrast over the motif. */
.plate .plate-spec {
  position: absolute; left: 0; top: 0; z-index: 1;
  max-width: min(82%, 300px); padding: 10px 12px;
  font-family: var(--font-mono); font-size: var(--t-label); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--concrete); line-height: 1.7;
}
.plate .plate-spec span {
  background: var(--surface); padding: 5px 9px;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
/* full-bleed EDITORIAL photo plates (home featured, project hero, studio) are
   HEIGHT-CAPPED so they read as wide cinematic plates, not tall bands. (A 16:9
   full-bleed would run ~810px at 1440; a 3:2, ~960px.) object-fit:cover fills
   the capped frame. Non-bleed plates keep their aspect ratio. */
.plate--bleed.plate--natural { aspect-ratio: auto; height: clamp(340px, 42vw, 580px); }
/* the mono corner caption — "FIG. 01", "A-104 · SOUTH ELEVATION" */
.plate-cap {
  position: absolute; left: 0; bottom: 0; z-index: 2;
  background: var(--plaster); border-top: 1px solid var(--rule); border-right: 1px solid var(--rule);
  font-family: var(--font-mono); font-size: var(--t-label); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink); padding: 6px 12px;
}
/* a buyer photo, dropped in, renders as a graphite DUOTONE at index scale — the
   register viewport and the work-grid thumbnails keep this, so the INDEX stays
   achromatic (Datum's monochrome lock). Richness comes from the editorial plates. */
.plate img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) contrast(1.05); }
/* the large EDITORIAL plates (featured / project hero + figures / studio) carry
   austere, heavily-desaturated NATURAL colour — the whisper of dusk-blue or
   timber-warm the achromatic UI deliberately withholds. Still restrained: the
   subjects are low-chroma concrete, timber and dusk, so at 0.6 saturation the
   plate reads as a warm/cool duotone, never a colour photo. */
.plate--natural img { filter: saturate(0.6) contrast(1.02); }
/* mount = a positioned wrapper so the FIG. corner caption sits OVER the plate
   as a sibling and survives a photo being dropped into the image slot */
.plate-mount { position: relative; }

/* full-bleed / grid-broken plate — deliberately violates the sheet frame */
.plate--bleed { margin-inline: calc(50% - 50vw); max-width: 100vw; border-inline: 0; }

/* the AI editorial figure preview (the /edit builder inserts .plate-figure) */
.plate-figure { border: 1px solid var(--rule); margin-top: 24px; }
.plate-figure img, .manifesto-figure img { display: block; width: 100%; height: auto; filter: saturate(0.6) contrast(1.02); }
.manifesto-figure { border: 1px solid var(--rule); margin-top: 24px; }

/* one ink plate-band for pacing on the project page — a full-bleed dark strip
   holding a single figure */
.plate-band--ink { background: var(--ink-ground); margin-inline: calc(50% - 50vw); padding-block: clamp(32px, 5vw, 64px); margin-block: clamp(36px, 5vw, 60px); }
.plate-band--ink .band-inner { max-width: var(--max); margin-inline: auto; padding-inline: max(var(--gutter), calc(50vw - var(--max) / 2)); }
.plate-band--ink .figtag { color: var(--ink-muted); }
.plate-band--ink .plate-cap { background: var(--ink-ground); border-color: var(--ink-line); color: var(--plaster); }

/* plan / section line drawing — an SVG line-art placeholder, ink on plaster */
.plan-drawing { border: 1px solid var(--rule); background: var(--plaster); padding: clamp(20px, 3vw, 40px); }
.plan-drawing svg { width: 100%; height: auto; display: block; }
.plan-drawing svg [stroke] { stroke: var(--ink); }

/* FIG. caption above/below a plate */
.figtag {
  display: block;
  font-family: var(--font-mono); font-size: var(--t-label); letter-spacing: 0.10em;
  text-transform: uppercase; color: var(--concrete); margin-bottom: 10px;
}

/* --------------------------------------------------------------------------
   11. THE DRAWING REGISTER — the signature. An architect's drawing-sheet
       schedule: NO · PROJECT · LOCATION · YEAR · TYPOLOGY · STATUS, ruled with
       hairlines, tabular figures snapping every column. Reads finished at
       three rows. On hover the corner title-block viewport crossfades to the
       row's plate, the active row gets a redline hairline underline, and a
       dimension line draws to the viewport. On click, a dependency-free FLIP
       (see js/main.js) scales the plate toward the hero, then navigates.
       Resting state (no-JS / reduced-
       motion / touch): every row keeps a static inline plate, the viewport
       holds the featured project, the row is a plain link. Nothing is hidden.
   -------------------------------------------------------------------------- */
.register-layout { display: grid; grid-template-columns: 1fr; gap: clamp(28px, 4vw, 44px); }
.register-layout.has-viewport { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); align-items: start; }

/* the register is a link-list styled like a drawing-sheet schedule (each row is
   a real <a> to the project); the header row carries the column names. */
.register { position: relative; }
.register-head {
  display: grid;
  grid-template-columns: 3.2rem 2fr 1.4fr 4.2rem 1.4fr auto;
  gap: 12px; padding: 10px 12px; border-bottom: 1px solid var(--ink);
  font-family: var(--font-mono); font-size: var(--t-label); font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--concrete);
}
.register-head span:last-child { text-align: right; }
.register-row {
  border-bottom: 1px solid var(--rule);
  display: grid;
  grid-template-columns: 3.2rem 2fr 1.4fr 4.2rem 1.4fr auto;
  gap: 12px; align-items: baseline;
  padding: 16px 12px;
  color: var(--ink); text-decoration: none;
  position: relative;
}
.register-row:hover, .register-row:focus-visible { background: var(--surface); outline-offset: -3px; }
.register-row .r-no { font-family: var(--font-mono); font-size: var(--t-data); color: var(--concrete); }
.register-row .r-project {
  font-family: var(--font-display); font-weight: 600; font-size: 22px; line-height: 1.05;
  text-transform: uppercase; letter-spacing: 0.01em;
}
.register-row .r-loc, .register-row .r-year, .register-row .r-type, .register-row .r-status {
  font-family: var(--font-mono); font-size: var(--t-data); color: var(--concrete);
}
.register-row .r-status { text-align: right; white-space: nowrap; }
.register-row .r-status.is-live { color: var(--ink); }
/* the active row's redline hairline underline — the register's headline <3%
   redline moment (draws under the row on hover) */
.register-row::after {
  content: ""; position: absolute; left: 12px; right: 12px; bottom: -1px;
  height: 2px; background: var(--redline); transform: scaleX(0); transform-origin: left;
  transition: transform 0.18s ease;
}
.register-row:hover::after, .register-row.is-active::after, .register-row:focus-visible::after { transform: scaleX(1); }

/* the fixed corner title-block VIEWPORT that receives hover crossfades */
.viewport { position: sticky; top: 96px; }
.viewport .plate { aspect-ratio: 4 / 5; }
.viewport .vp-meta {
  border: 1px solid var(--rule); border-top: 0;
  font-family: var(--font-mono); font-size: var(--t-data);
  display: grid; grid-template-columns: auto 1fr;
}
.viewport .vp-meta dt { padding: 7px 12px; color: var(--concrete); font-size: var(--t-label); letter-spacing: 0.06em; text-transform: uppercase; border-bottom: 1px solid var(--rule); }
.viewport .vp-meta dd { padding: 7px 12px; text-align: right; border-bottom: 1px solid var(--rule); border-left: 1px solid var(--rule); }
.viewport .vp-meta .row-last dt, .viewport .vp-meta .row-last dd { border-bottom: 0; }
/* crossfade layer for the viewport's active project name/number */
.viewport .vp-title { transition: opacity 0.12s ease; }
.viewport.is-swapping .vp-title { opacity: 0; }

/* the dimension line SVG that draws from row to viewport (viewBox-unit stroke,
   NEVER non-scaling-stroke + pathLength — the Chromium draw bug). */
.dim-line { position: absolute; pointer-events: none; z-index: 3; overflow: visible; inset: 0; }
.dim-line path { fill: none; stroke: var(--redline); stroke-width: 1.5; }

/* --------------------------------------------------------------------------
   12. GRID VIEW — the alternate module on Work: sparse, large, 2-up plates.
       Not a masonry wall. List <=> Grid toggle.
   -------------------------------------------------------------------------- */
.view-toggle { display: inline-flex; border: 1px solid var(--ink); }
.view-toggle button {
  font: 500 var(--t-label)/1 var(--font-mono); letter-spacing: 0.10em; text-transform: uppercase;
  padding: 10px 16px; background: var(--plaster); color: var(--ink); border: 0; cursor: pointer;
}
.view-toggle button + button { border-left: 1px solid var(--ink); }
.view-toggle button[aria-pressed="true"] { background: var(--ink); color: var(--plaster); }

.filter-bar { display: flex; flex-wrap: wrap; gap: 10px 20px; align-items: center; margin-top: 24px; }
.filter-bar .f-label { font-family: var(--font-mono); font-size: var(--t-label); letter-spacing: 0.10em; text-transform: uppercase; color: var(--concrete); }
.filter-bar .chip {
  font: 500 var(--t-label)/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase;
  padding: 8px 12px; border: 1px solid var(--rule); background: transparent; color: var(--ink); cursor: pointer;
}
.filter-bar .chip[aria-pressed="true"] { border-color: var(--ink); }

.plate-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(24px, 3vw, 40px); margin-top: clamp(32px, 4vw, 48px); }
.plate-card { text-decoration: none; color: var(--ink); display: block; }
.plate-card .plate { margin-bottom: 14px; }
.plate-card .pc-name { font-family: var(--font-display); font-weight: 600; font-size: 24px; text-transform: uppercase; line-height: 1.02; }
.plate-card:hover .pc-name { text-decoration: underline; text-underline-offset: 4px; text-decoration-color: var(--redline); }
.plate-card .pc-meta { font-family: var(--font-mono); font-size: var(--t-data); color: var(--concrete); margin-top: 6px; display: flex; gap: 14px; }

/* --------------------------------------------------------------------------
   13. SCHEDULES — mono ruled tables: capabilities, phases, timeline, roster,
       recognition. Density rhythm against the sparse plates. Not icon cards.
   -------------------------------------------------------------------------- */
.schedule { width: 100%; border-collapse: collapse; margin-top: clamp(28px, 4vw, 40px); }
.schedule caption { text-align: left; }
.schedule th {
  font-family: var(--font-mono); font-size: var(--t-label); font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--concrete);
  text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--ink);
}
.schedule td { padding: 16px 12px; border-bottom: 1px solid var(--rule); vertical-align: baseline; }
.schedule .s-no { font-family: var(--font-mono); font-size: var(--t-data); color: var(--concrete); width: 3rem; }
.schedule .s-name { font-family: var(--font-display); font-weight: 600; font-size: 22px; text-transform: uppercase; line-height: 1.05; }
.schedule .s-name-body { font: 600 var(--t-h3) var(--font-body); }
.schedule .s-mono { font-family: var(--font-mono); font-size: var(--t-data); color: var(--concrete); }
.schedule .s-desc { color: var(--concrete); font-size: var(--t-small); max-width: 60ch; }

/* the numbered phase — a big drafting-stencil-styled sheet number */
.phase-no {
  font-family: var(--font-display); font-weight: 700; font-size: clamp(40px, 6vw, 72px);
  line-height: 0.9; color: var(--ink);
}

/* --------------------------------------------------------------------------
   14. STATEMENT — a short practice statement set large, a few declarative
       lines. No service cards.
   -------------------------------------------------------------------------- */
.statement-big {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(30px, 4.2vw, 58px); line-height: 1.02; text-transform: uppercase;
  letter-spacing: -0.005em; max-width: 18ch;
}
.statement-prose { max-width: 60ch; margin-top: clamp(24px, 3vw, 36px); font-size: 18px; line-height: 1.6; }

/* --------------------------------------------------------------------------
   15. FORMS — plaster fields, 1px rule border (graphite on focus), mono labels,
       an INK submit button. Honest states only — no fake success toast.
   -------------------------------------------------------------------------- */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px var(--gutter); margin-top: clamp(28px, 4vw, 40px); max-width: 760px; }
.field { display: flex; flex-direction: column; gap: 7px; }
.field--full { grid-column: 1 / -1; }
.field label { font-family: var(--font-mono); font-size: var(--t-label); letter-spacing: 0.08em; text-transform: uppercase; color: var(--concrete); }
.field input, .field select, .field textarea {
  font: 400 16px/1.4 var(--font-body); color: var(--ink); background: var(--plaster);
  border: 1px solid var(--input-border); border-radius: 0; padding: 12px 14px; width: 100%;
}
.field textarea { min-height: 140px; resize: vertical; }
.field select { appearance: none; }

/* --------------------------------------------------------------------------
   16. CTA BAND — ink ground, Big Shoulders headline, plaster-fill button, a
       redline section-cut mark beside the heading (a <3% moment).
   -------------------------------------------------------------------------- */
.band--ink { background: var(--ink-ground); color: var(--plaster); padding-block: var(--sp-section); }
.band--ink .eyebrow { color: var(--ink-muted); }
.band--ink h2 { color: var(--plaster); }
.band--ink .lede { color: var(--ink-muted); }
.band--ink .cut-mark { color: var(--redline-tint); }
.band--ink .mono-label { color: var(--ink-muted); }
.cta .avail { margin-top: 22px; font-family: var(--font-mono); font-size: var(--t-data); color: var(--ink-muted); letter-spacing: 0.04em; }
.cta .btn-row { margin-top: 30px; }

/* next-sheet link (project detail) — the next project as the next drawing */
.next-sheet { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px 20px; text-decoration: none; color: var(--plaster); }
.next-sheet .ns-code { font-family: var(--font-mono); font-size: var(--t-label); letter-spacing: 0.10em; text-transform: uppercase; color: var(--ink-muted); }
.next-sheet .ns-name { font-family: var(--font-display); font-weight: 700; font-size: clamp(32px, 5vw, 64px); text-transform: uppercase; line-height: 0.95; }
.next-sheet:hover .ns-name { text-decoration: underline; text-underline-offset: 6px; text-decoration-color: var(--redline-tint); }

/* --------------------------------------------------------------------------
   17. FOOTER — ink ground, the studio title block rendered in full + the site
       map printed as a sheet index, a faint plan/section watermark.
   -------------------------------------------------------------------------- */
.site-footer { position: relative; background: var(--ink-ground); color: var(--plaster); padding-block: 64px 40px; overflow: hidden; }
/* faint plan/section line-drawing watermark at ~10% */
.site-footer::before {
  content: ""; position: absolute; right: -40px; top: -30px; width: 340px; height: 340px; opacity: 0.10; pointer-events: none;
  background-image:
    linear-gradient(to right, transparent calc(50% - 0.5px), var(--plaster) 50%, transparent calc(50% + 0.5px)),
    linear-gradient(to bottom, transparent calc(50% - 0.5px), var(--plaster) 50%, transparent calc(50% + 0.5px));
  border: 1px solid var(--plaster);
}
.footer-grid { position: relative; display: grid; grid-template-columns: 1.6fr 1fr 1fr; gap: 40px var(--gutter); }
.site-footer .wordmark { color: var(--plaster); font-size: 30px; }
.footer-nap { margin-top: 18px; font-family: var(--font-mono); font-size: var(--t-data); line-height: 1.9; color: var(--ink-muted); font-style: normal; }
.footer-nap a { color: var(--plaster); text-decoration: none; }
.footer-nap a:hover { text-decoration: underline; }
.footer-col h2 { font-family: var(--font-mono); font-size: var(--t-label); letter-spacing: 0.10em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: 14px; font-weight: 500; }
.footer-col ul { list-style: none; }
.footer-col li { padding-block: 5px; }
.footer-col a { font: 400 var(--t-small)/1.5 var(--font-body); color: var(--plaster); text-decoration: none; }
.footer-col a:hover { text-decoration: underline; text-underline-offset: 4px; }
.footer-col .sheet-code { font-family: var(--font-mono); font-size: var(--t-label); color: var(--ink-muted); margin-right: 8px; }
.footer-fine { position: relative; margin-top: 56px; padding-top: 24px; border-top: 1px solid var(--ink-line); display: flex; flex-wrap: wrap; gap: 10px 32px; justify-content: space-between; }
.footer-fine p { font-family: var(--font-mono); font-size: var(--t-label); letter-spacing: 0.04em; color: var(--ink-muted); max-width: none; }

/* --------------------------------------------------------------------------
   18. CONTACT / MAP SLOT — a labelled placeholder, never a fake embed.
   -------------------------------------------------------------------------- */
.map-slot { border: 1px solid var(--rule); background: var(--surface); aspect-ratio: 16 / 7; display: grid; place-items: center; margin-top: clamp(28px, 4vw, 40px);
  background-image:
    linear-gradient(to right, transparent calc(50% - 0.5px), var(--rule) 50%, transparent calc(50% + 0.5px)),
    linear-gradient(to bottom, transparent calc(50% - 0.5px), var(--rule) 50%, transparent calc(50% + 0.5px)); }
.map-slot .plate-spec { font-family: var(--font-mono); font-size: var(--t-label); letter-spacing: 0.10em; text-transform: uppercase; color: var(--concrete); text-align: center; line-height: 1.9; }
.map-slot .plate-spec span { background: var(--surface); padding: 6px 10px; }

/* --------------------------------------------------------------------------
   19. SECTION SCAFFOLDING — heads, spacing, columns
   -------------------------------------------------------------------------- */
.sec-head { margin-bottom: clamp(28px, 4vw, 44px); }
.sec-head h2 { max-width: 20ch; }
.two-col { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(28px, 5vw, 64px); align-items: start; }
.two-col--7-5 { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }

/* --------------------------------------------------------------------------
   20. MOTION — Lenis smooth-scroll + one hand-rolled FLIP (the Register plate).
       Section reveals are pure CSS: nothing is hidden by default; the .in
       class (added on enter) PLAYS a short y-translate + hairline underline
       draw with a `backwards` fill, so print / screenshots / no-JS render the
       complete page (the Candor headless-capture lesson). All of it lives
       inside no-preference; reduced motion renders everything at rest.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  html.js .reveal.in { animation: datum-rise 0.42s ease backwards; }
  html.js .reveal.in .underline-draw { animation: datum-draw 0.5s ease 0.1s backwards; }
  html.js .register.in .register-row { animation: datum-rise 0.4s ease backwards; animation-delay: calc(var(--i, 0) * 45ms); }
}
@keyframes datum-rise { from { opacity: 0; transform: translateY(12px); } }
@keyframes datum-draw { from { transform: scaleX(0); } }
.underline-draw { display: block; height: 1px; background: var(--ink); transform-origin: left; }

/* the Flip clone that scales toward the hero on a register/plate click */
.flip-clone { position: fixed; z-index: 200; pointer-events: none; border: 1px solid var(--ink); background: var(--surface); }

/* --------------------------------------------------------------------------
   20b. AMBIENT DRAFTING FIELD — a hand-authored WebGL background (js/datum-
        motion.js): a whisper-faint drafting grid that drifts and a single datum
        line that redraws. It sits BEHIND the home masthead and the ink enquiry
        bands, UNDER a paper/ink scrim, so text always computes on the section's
        own ground colour — the shader can never break contrast. The page is
        COMPLETE without it: with no JS or no WebGL the layer keeps a static CSS
        grid poster (the still frame) in the same paper tone; never a blank box.
   -------------------------------------------------------------------------- */
.has-motion { position: relative; }
/* content sits above the motion layer (which is z-index 0). Every direct child
   of the host EXCEPT the layer is lifted; positioned so z-index takes. */
.has-motion > :not(.motion-layer) { position: relative; z-index: 1; }
.motion-layer {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
}
.motion-layer .motion-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* the scrim — a paper/ink wash over the motion and under the copy. This is the
   contrast guarantee: the effective background reduces to the ground colour,
   which the palette already proves (ink-on-plaster 15.58, plaster-on-ink 15.6). */
.motion-layer::after { content: ""; position: absolute; inset: 0; }

/* LIGHT host (the home masthead): a plaster field with the faintest graphite
   drafting grid as the no-JS/no-WebGL poster; the scrim washes back to plaster. */
.motion-layer[data-motion="light"] {
  background:
    repeating-linear-gradient(0deg, transparent 0 45px, color-mix(in srgb, var(--concrete) 5%, transparent) 45px 46px),
    repeating-linear-gradient(90deg, transparent 0 45px, color-mix(in srgb, var(--concrete) 5%, transparent) 45px 46px),
    var(--plaster);
}
.motion-layer[data-motion="light"]::after { background: color-mix(in srgb, var(--plaster) 60%, transparent); }

/* DARK host (the ink enquiry bands): an ink field with a faint blueprint grid in
   the ink hairline; the scrim washes back to the ink ground. */
.motion-layer[data-motion="dark"] {
  background:
    repeating-linear-gradient(0deg, transparent 0 45px, color-mix(in srgb, var(--ink-line) 55%, transparent) 45px 46px),
    repeating-linear-gradient(90deg, transparent 0 45px, color-mix(in srgb, var(--ink-line) 55%, transparent) 45px 46px),
    var(--ink-ground);
}
.motion-layer[data-motion="dark"]::after { background: color-mix(in srgb, var(--ink-ground) 58%, transparent); }

/* reduced-motion still renders one frame; but if a user ALSO has no JS, the
   poster above is the resting state. Nothing here needs a reduced-motion guard —
   the JS decides whether to animate; the CSS only ever draws the still poster. */

/* --------------------------------------------------------------------------
   21. RESPONSIVE — one codebase. Registration marks and the drafting underlay
       reduce on phones; the register stays a schedule; plates single-column.
   -------------------------------------------------------------------------- */
@media (max-width: 960px) {
  .register-layout.has-viewport { grid-template-columns: 1fr; }
  .viewport { position: static; order: -1; max-width: 380px; }
  .two-col, .two-col--7-5 { grid-template-columns: 1fr; }
  .plate-grid { gap: 28px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .masthead-foot { grid-template-columns: 1fr; }
  .masthead-foot .titleblock { justify-self: start; }
}

@media (max-width: 720px) {
  .sheet {
    border-inline: 0; border-block: 1px solid var(--rule);
    background-image: none; /* underlay retires on phones */
    padding-inline: 0;
  }
  .sheet::before, .sheet::after, .crop-tr, .crop-bl { display: none; } /* corner marks hide < 640-ish */
  .nav .wrap::before, .nav .wrap::after { display: none; }
  .nav-toggle { display: inline-flex; }
  .nav-links {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    background: var(--plaster); border-bottom: 1px solid var(--rule);
    flex-direction: column; gap: 0; padding: 8px var(--gutter) 16px;
  }
  .nav-links.open { display: flex; }
  .nav-links a { display: block; padding-block: 14px; font-size: 16px; }
  .nav .wrap { gap: 14px; }
  .nav-actions .btn { padding: 12px 16px; font-size: 14px; }

  /* the register reflows: NO · PROJECT · YEAR · STATUS stay; Location + Typology
     drop to a second mono line under the project name (no hover on touch;
     FLIP disabled -> ordinary navigation). The column header row is dropped —
     the rows are self-describing on a phone. */
  .register-head { display: none; }
  .register-row { grid-template-columns: 2.6rem 1fr auto; gap: 6px 12px; align-items: baseline; }
  .register-row .r-no { grid-row: 1; grid-column: 1; }
  .register-row .r-project { grid-column: 2; grid-row: 1; font-size: 20px; }
  .register-row .r-status { grid-column: 3; grid-row: 1; }
  .register-row .r-loc, .register-row .r-type, .register-row .r-year { grid-column: 2; }
  .register-row .r-loc::after { content: " ·"; }

  .plate-grid { grid-template-columns: 1fr; }
  .form-grid { grid-template-columns: 1fr; }
  .field--full { grid-column: auto; }
  .footer-grid { grid-template-columns: 1fr; gap: 32px; }
  .section, .band--ink { padding-block: 56px; }
  .two-col--7-5 { gap: 32px; }
}

/* --------------------------------------------------------------------------
   22. PRINT — a drawing set should print cleanly
   -------------------------------------------------------------------------- */
@media print {
  .site-footer::before { display: none; }
  .plate { border: 1px solid #000; }
  .register-row::after { display: none; }
  .motion-layer { display: none; } /* the ambient field never prints */
}
