/* ============================================================================
   site.css - Saso Designs. Direction C "One Home at a Time", in A's dress.

   Grant, 2026-09-10: keep A's layering, animation, dark ground and colours;
   keep everything else of his own site - section order and names, copy,
   services, process, inquiry. So: his content, C's one-home-at-a-time work
   section, A's look. Tokens come from tokens/tokens.css (generated, verbatim
   brand copy); this file only reads them, with the brand value as fallback.
   ========================================================================== */
:root {
  --ink:  var(--color-neutral-950, #1A1917);
  --paper: var(--color-white, #FAF9F5);
  --n50:  var(--color-neutral-50, #F8F6F0);
  --n100: var(--color-neutral-100, #EFEBE3);
  --n200: var(--color-neutral-200, #DED8CC);
  --n300: var(--color-neutral-300, #C8BFAF);
  --n400: var(--color-neutral-400, #AB9F8E);
  --n500: var(--color-neutral-500, #8F8370);
  --n600: var(--color-neutral-600, #756A59);
  --n700: var(--color-neutral-700, #5C5345);
  --n800: var(--color-neutral-800, #433D34);
  --n900: var(--color-neutral-900, #2E2A24);
  --e200: var(--color-earth-200, #E8D8CC);
  --e300: var(--color-earth-300, #D4BBA9);
  --e400: var(--color-earth-400, #BF9C87);
  --e600: var(--color-earth-600, #956B55);
  --e700: var(--color-earth-700, #7A5544);
  --err: #B14E3A;
  --fh: var(--font-heading, 'Sora', 'Segoe UI', system-ui, sans-serif);
  --fb: var(--font-body, 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif);
  --ease: var(--ease-out, cubic-bezier(0.25, 0.46, 0.45, 0.94));
  --pad: clamp(20px, 6.6vw, 96px);
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
html.lock { overflow: hidden; }
body { margin: 0; background: var(--ink); color: var(--paper); font-family: var(--fb); font-size: 16px; line-height: 1.65; -webkit-font-smoothing: antialiased; overflow-x: clip; }
img { max-width: 100%; display: block; }
a { color: var(--e300); text-decoration: none; }
a:hover { color: var(--e200); }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; border-radius: 0; text-align: inherit; }
:focus-visible { outline: 1px solid var(--e300); outline-offset: 4px; }
::selection { background: var(--e300); color: var(--ink); }
.skip { position: absolute; left: -9999px; top: 12px; z-index: 200; background: var(--paper); color: var(--ink); padding: 10px 16px; }
.skip:focus { left: 12px; }

/* ---------- type ---------- */
.micro { font-family: var(--fh); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--n500); margin: 0; }
.display { font-family: var(--fh); font-weight: 300; font-size: clamp(60px, 8vw, 124px); line-height: 0.98; letter-spacing: -0.03em; margin: 20px 0 0; color: var(--paper); }
.h3 { font-family: var(--fh); font-weight: 400; font-size: 21px; line-height: 1.25; letter-spacing: -0.01em; margin: 0; color: var(--paper); display: block; }
.lede { max-width: 480px; font-size: 18px; color: var(--n400); margin: 26px 0 0; text-wrap: pretty; }
.body-1 { font-size: 18px; color: var(--n400); max-width: 580px; margin: 0; text-wrap: pretty; }
/* The lockup is Grant's no-box logo (products/saso-designs/logo, approved
   2026-09-24), used as the file and set by height. Never rebuilt out of a mark
   plus live type. At these heights it takes the same width the boxed one did. */
.lockup { display: block; width: auto; }
.bar .lockup { height: 30px; transition: height 400ms var(--ease); }
.bar.solid .lockup { height: 24px; }

/* ---------- buttons: square, uppercase Sora, trailing dash 18 -> 28px ---------- */
.btn { display: inline-flex; align-items: center; gap: 14px; font-family: var(--fh); font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; padding: 18px 32px; border: 1px solid; transition: background-color 250ms var(--ease), color 250ms var(--ease), border-color 250ms var(--ease); }
.btn .dash { width: 18px; height: 1px; background: currentColor; transition: width 300ms var(--ease); }
.btn:hover .dash { width: 28px; }
.btn-fill { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.btn-fill:hover { background: var(--n200); border-color: var(--n200); color: var(--ink); }
.btn-line { color: var(--paper); border-color: var(--n600); }
.btn-line:hover { color: var(--paper); border-color: var(--paper); }
.btn-sm { padding: 11px 20px; font-size: 11px; }

/* ---------- bar ---------- */
.bar { position: fixed; inset: 0 0 auto 0; z-index: 50; display: flex; justify-content: space-between; align-items: center; padding: 24px var(--pad); border-bottom: 1px solid transparent; transition: background-color 400ms var(--ease), padding 400ms var(--ease), border-color 400ms var(--ease); }
.bar.solid { background: rgba(26, 25, 23, 0.92); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); padding-block: 12px; border-color: var(--n900); }
.brand { display: flex; align-items: center; gap: 14px; }
.nav { display: flex; align-items: center; gap: 36px; }
.nav > a:not(.btn) { font-family: var(--fh); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--n300); padding-bottom: 6px; border-bottom: 1px solid transparent; transition: color 250ms var(--ease), border-color 250ms var(--ease); }
.nav > a:not(.btn):hover, .nav > a.on { color: var(--paper); border-color: var(--e600); }

/* ---------- hero ---------- */
.hero { position: relative; min-height: 100vh; min-height: 100svh; display: flex; align-items: center; overflow: hidden; padding: 104px var(--pad) 72px; }
.grain { position: absolute; inset: 0; pointer-events: none; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.98  0 0 0 0 0.96  0 0 0 0 0.92  0 0 0 0.07 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>"), radial-gradient(ellipse 55% 60% at 78% 45%, rgba(166, 125, 104, 0.10), transparent 70%); }
.hero-grid { position: relative; width: 100%; max-width: 1440px; margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: clamp(40px, 5vw, 80px); align-items: center; }
.hero-copy { position: relative; z-index: 2; }
.over { margin-top: 28px; color: var(--n400); }
.ctas { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 36px; }
.cue { position: absolute; left: 50%; bottom: 28px; transform: translateX(-50%); font-size: 10px; color: var(--n600); }

.sheet-wrap { position: relative; }
.sheet { position: relative; border: 1px solid var(--n600); padding: 10px; background: rgba(250, 249, 245, 0.015); box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45); }
.sheet-draw { position: relative; aspect-ratio: 620 / 360; border: 1px solid var(--n800); overflow: hidden; }
.sl { position: absolute; inset: 0; will-change: transform; }
.sl svg { width: 100%; height: 100%; display: block; }
.grid line { stroke: var(--n800); stroke-width: 1; vector-effect: non-scaling-stroke; opacity: 0.55; }
.ink line, .ink rect, .ink polygon { fill: none; stroke: var(--n200); stroke-width: 1; vector-effect: non-scaling-stroke; }
.ink.fill polygon { fill: rgba(222, 216, 204, 0.06); }
.ink .glass { fill: rgba(212, 187, 169, 0.14); }
.ink .hatch { stroke: var(--n600); stroke-dasharray: 3 5; }
.dims line { stroke: var(--e400); stroke-width: 1; vector-effect: non-scaling-stroke; }
.dims .lvl { stroke-dasharray: 6 6; opacity: 0.6; }
.dims text { font-family: var(--fh); font-size: 9px; font-weight: 600; letter-spacing: 1.6px; fill: var(--e400); }
.sl.photo img { width: 100%; height: 100%; object-fit: cover; }
.title-block { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border: 1px solid var(--n800); border-top: 0; }
.title-block > div { display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; border-left: 1px solid var(--n800); min-width: 0; }
.title-block > div:first-child { border-left: 0; }
.title-block span { font-family: var(--fh); font-size: 8px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--n600); }
.title-block b { font-family: var(--fh); font-size: 10px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--n200); line-height: 1.35; overflow-wrap: anywhere; }

/* the sheet builds itself, layer by layer, then the photograph lands over it */
.ly { opacity: 0; animation: ly 14s var(--ease) infinite both; }
@keyframes ly { 0% { opacity: 0; } 6% { opacity: 1; } 86% { opacity: 1; } 95% { opacity: 0; } 100% { opacity: 0; } }
.sl.photo { opacity: 0; animation: photo 14s ease-in-out infinite both; }
@keyframes photo { 0% { opacity: 0; } 40% { opacity: 0; } 52% { opacity: 1; } 84% { opacity: 1; } 94% { opacity: 0; } 100% { opacity: 0; } }

/* entrance - the hero holds still behind the opening, then rises as it leaves */
@keyframes rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
.intro .hero:not(.done) .a-rise { opacity: 0; }
.intro.intro-out .hero:not(.done) .a-rise { animation: rise 900ms var(--ease) var(--d, 0s) forwards; }

/* ---------- opening: the logo draws itself, then lets go ----------
   Never a preloader - the page underneath is already built. It plays on every
   load, any input skips it, and reduced motion never sees it.

   One SVG whose end state is the logo: the mark traced as a line, then the
   logo's own rule and name outlines. White, like the header's lockup file. */
.intro-ov { display: none; }
.intro .intro-ov { --soft: cubic-bezier(0.33, 0, 0.2, 1); --draw: cubic-bezier(0.45, 0, 0.25, 1); position: fixed; inset: 0; z-index: 400; display: grid; place-items: center; background: var(--ink); transition: opacity 820ms cubic-bezier(0.33, 0, 0.2, 1); }
.intro-ov.out { opacity: 0; pointer-events: none; }
/* The mark draws in the middle of the screen, and then the lockup opens: a
   window over the artwork widens from the mark's own width out to the full
   lockup, so the wordmark runs out to the right while the group, being centred,
   carries the mark left by half of what it gains. One move, and the mark and the
   words are the same drawing throughout - the window is the only thing moving.

   0.3171 is where the mark ends inside the artwork: x=371.5 of the 1165.346-wide
   viewBox that starts at x=2. */
.intro-group { opacity: 0; will-change: opacity; }
.intro-clip { --full: min(86vw, 780px); width: calc(var(--full) * 0.3171); overflow: hidden; will-change: width; }
.intro-lockup { display: block; width: var(--full); height: auto; overflow: visible; }
.intro-rule { fill: #fff; transform: scaleY(0); transform-box: fill-box; transform-origin: 50% 50%; }
.intro-word { fill: #fff; opacity: 0; }
.intro-path { fill: none; stroke: #fff; stroke-width: 29; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: var(--L, 1015); stroke-dashoffset: var(--L, 1015); transition: opacity 260ms var(--ease); }
.intro-ov.play .intro-group { animation: sd-in 560ms var(--soft) 60ms forwards; }
.intro-ov.play .intro-clip { animation: sd-open 820ms var(--soft) 1460ms forwards; }
.intro-ov.play .intro-rule { animation: sd-rule 300ms var(--soft) 1520ms forwards; }
.intro-ov.play .intro-word { animation: sd-word 420ms linear 1560ms forwards; }
.intro-ov.play .intro-path { animation: sd-draw 1080ms var(--draw) 220ms forwards; }
@keyframes sd-in   { to { opacity: 1; } }
@keyframes sd-draw { to { stroke-dashoffset: 0; } }
@keyframes sd-open { to { width: var(--full); } }
@keyframes sd-back { to { scale: 1; } }
@keyframes sd-rule { to { transform: scaleY(1); } }
@keyframes sd-word { to { opacity: 1; } }

/* ---------- sections ---------- */
.wrap { padding-inline: var(--pad); max-width: 1440px; margin: 0 auto; }
.sec { position: relative; padding-block: clamp(52px, 6vw, 88px); border-top: 1px solid var(--n900); }
.sec-head { display: flex; align-items: center; gap: 16px; }
.sec-head .rule { width: 32px; height: 1px; background: var(--n800); }
/* Grant, 2026-09-20: no display headings. The label is each section's heading now,
   a real h2 styled as micro, so it is set in full here rather than left to
   tokens.css's bare h2 rule. Beneath it the first paragraph leads in a lighter
   tone, and the rest of the copy stays at the body tone. */
/* the label IS the heading now, so it carries a little more weight than a
   micro line of type would */
.sec-head .lbl { font-size: 13px; letter-spacing: 0.14em; color: var(--n200); line-height: 1.4; }
.lead-p { color: var(--n200); }
.sec-lead { margin-top: 18px; max-width: 620px; }
.js .rv { opacity: 0; transform: translateY(24px); transition: opacity 900ms var(--ease), transform 900ms var(--ease); }
.js .rv.in { opacity: 1; transform: none; }

/* ---------- about: portrait over an offset plate - two planes ---------- */
.about { display: grid; grid-template-columns: minmax(240px, 372px) minmax(0, 1fr); gap: clamp(32px, 5vw, 72px); align-items: center; }
.portrait-stack { position: relative; padding: 0 28px 28px 0; }
.plate { position: absolute; inset: 28px 0 0 28px; border: 1px solid var(--n700); background: repeating-linear-gradient(0deg, transparent 0 39px, rgba(92, 83, 69, 0.35) 39px 40px), repeating-linear-gradient(90deg, transparent 0 39px, rgba(92, 83, 69, 0.35) 39px 40px); }
.portrait { position: relative; margin: 0; aspect-ratio: 44 / 52; overflow: hidden; background: var(--n900); box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45); }
.portrait img { width: 100%; height: 100%; object-fit: cover; }
.about-copy { display: flex; flex-direction: column; gap: 18px; }
/* the credentials as a drawing's title block: an outer rule, hairline cells, each
   field named small in its top corner and filled in below */
.tblock { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 6px 0 0; max-width: 620px; border: 1px solid var(--n700); }
.tblock > div { min-width: 0; padding: 11px 14px 13px; border-left: 1px solid var(--n800); border-top: 1px solid var(--n800); }
.tblock > div:nth-child(-n+2) { border-top: 0; }
.tblock > .tb-wide { grid-column: span 2; border-left: 0; }
.tblock > div:nth-child(3) { border-left: 0; }
.tblock dt { font-size: 9.5px; letter-spacing: 0.16em; color: var(--n500); }
.tblock dd { margin: 7px 0 0; font-family: var(--fh); font-weight: 300; font-size: 21px; line-height: 1.2; letter-spacing: -0.01em; color: var(--paper); overflow-wrap: anywhere; }
.tblock > .tb-wide dd { font-size: 26px; }
.difference { border-top: 1px solid var(--n800); padding-top: 14px; max-width: 620px; }
.difference .quote { font-family: var(--fh); font-weight: 300; font-size: 20px; line-height: 1.4; color: var(--n200); margin: 8px 0 0; }

/* ---------- work: his own list, carrying the new motion ----------
   Grant, 2026-09-18: the list from his site reads faster than a forced tour -
   you can scroll straight past it - but it was clunky. So the row stays and
   the motion arrives. Hovering a row lifts that photograph FULL BLEED behind
   the list, with its caption below it; the row opens the full-bleed takeover.
   A coarse pointer, which has no hover to give, gets a thumbnail in the row. */
.work-head { padding-block: clamp(52px, 6vw, 88px) clamp(12px, 1.4vw, 20px); }
.worklist-wrap { position: relative; margin-top: clamp(12px, 1.6vw, 24px); overflow: clip; }
.wl-bleed { position: absolute; inset: 0; opacity: 0; transition: opacity 900ms var(--ease); }
.wl-img { position: absolute; inset: 0; background-size: contain; background-repeat: no-repeat; background-position: center; opacity: 0; transition: opacity 600ms var(--ease), background-position 780ms var(--ease); }
.wl-img.on { opacity: 1; }
/* Lifted (a project open): the picture hangs from the top of the window, so any
   spare height gathers at the foot under the type and Close always sits on the
   picture, never across its edge. On a portrait phone it stands just under Close
   instead, and the words start where it ends - site.js only sets to-stack when it
   all fits. (2026-09-24: the soft-edged preview that used to live here was
   reverted - Grant found it jumpy as the picture expanded.) */
.wl-bleed.lift .wl-img:not(.plan) { background-position: center top; }
html.to-stack .wl-bleed.lift .wl-img:not(.plan) { background-position: center var(--to-top, 0px); }
html.to-stack .takeover:not(.plan) .to-veil { background: none; }
html.to-stack .takeover:not(.plan):not(.bare) .to-ui { justify-content: flex-start; padding-top: var(--to-pt, 0px); }
.wl-img.plan { background-origin: content-box; background-color: var(--paper); background-blend-mode: multiply; padding: clamp(20px, 5vh, 68px) clamp(20px, 5vw, 88px); transition: opacity 600ms var(--ease), padding 500ms var(--ease); }
/* with the type showing, the drawing fits ABOVE it - the field stays the same
   size, the sheet just keeps clear of the words */
.wl-bleed.typed .wl-img.plan { padding-bottom: clamp(150px, 33vh, 300px); }
.wl-bleed::after { transition: opacity 420ms var(--ease); content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(26, 25, 23, 0.9) 0%, rgba(26, 25, 23, 0.68) 40%, rgba(26, 25, 23, 0.3) 100%), linear-gradient(180deg, rgba(26, 25, 23, 0.8) 0%, rgba(26, 25, 23, 0.14) 38%, rgba(26, 25, 23, 0.78) 100%); }
.worklist-wrap.on .wl-bleed { opacity: 0.88; }
.wl-bleed.promote { position: fixed; z-index: 99; transition: left 780ms var(--ease), top 780ms var(--ease), width 780ms var(--ease), height 780ms var(--ease), opacity 420ms var(--ease), background-color 500ms var(--ease); }
.wl-bleed.landed { background-color: var(--ink); }
.worklist-wrap .wl-bleed.promote, .worklist-wrap.on .wl-bleed.promote { opacity: 1; }
.wl-bleed.promote::after { opacity: 0; }
.worklist { position: relative; z-index: 1; list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--n800); }
.wl-row { position: relative; border-bottom: 1px solid var(--n900); }
.wl-row::after { content: ''; position: absolute; left: 0; bottom: -1px; height: 1px; width: 0; background: var(--e600); transition: width 700ms var(--ease); }
.wl-row.on::after { width: 100%; }
.wl-btn { display: grid; grid-template-columns: 56px minmax(0, 1fr) 240px 74px 44px; align-items: center; gap: 24px; width: 100%; padding: clamp(15px, 1.9vw, 25px) 0; transition: opacity 400ms var(--ease); }
.worklist.hot .wl-row:not(.on) .wl-btn { opacity: 0.34; }
.wl-n { color: var(--n500); transition: color 300ms var(--ease); }
.wl-row.on .wl-n { color: var(--e400); }
/* the placeholder: present, numbered, and plainly not a door */
.wl-soon .wl-btn { cursor: default; }
.wl-soon .wl-n, .wl-soon .wl-title { color: var(--n700); }
.wl-soon .wl-title { font-style: normal; }
.wl-soon .wl-go { border-color: transparent; }
.worklist.hot .wl-soon .wl-btn { opacity: 0.34; }
.wl-title { font-family: var(--fh); font-weight: 300; font-size: clamp(26px, 2.7vw, 42px); line-height: 1.1; letter-spacing: -0.02em; color: var(--paper); transition: transform 500ms var(--ease); }
.wl-row.on .wl-title { transform: translateX(14px); }
.wl-type, .wl-year { transition: color 300ms var(--ease); }
.wl-row.on .wl-type { color: var(--n300); }
.wl-go { justify-self: end; width: 44px; height: 44px; display: grid; place-items: center; border: 1px solid var(--n800); transition: background-color 350ms var(--ease), border-color 350ms var(--ease); }
.wl-go svg { width: 17px; height: 17px; stroke: var(--n400); fill: none; transition: stroke 350ms var(--ease), transform 350ms var(--ease); }
.wl-row.on .wl-go { background: var(--paper); border-color: var(--paper); }
.wl-row.on .wl-go svg { stroke: var(--ink); transform: translateX(3px); }
.wl-thumb { display: none; }
.js .wl-row.rv { transition-delay: calc(var(--i, 0) * 70ms); }

/* ---------- services: numbers layered behind the words ---------- */
.services { list-style: none; margin: 26px 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 1px solid var(--n800); }
.services li { position: relative; display: flex; flex-direction: column; gap: 10px; padding: 26px 40px 28px 0; border-bottom: 1px solid var(--n800); }
/* three project types in one row (2026-09-24: full design + construction admin left
   Services - it is process, not a kind of project) */
.services li:not(:first-child) { padding-left: 32px; border-left: 1px solid var(--n800); }
.services li:last-child { padding-right: 0; }
.services li::before { content: ''; position: absolute; left: 0; top: -1px; height: 1px; width: 0; background: var(--e600); transition: width 700ms var(--ease); }
.services li:hover::before { width: 100%; }
.services .h3 { font-size: 22px; font-weight: 300; }
.services p { margin: 0; max-width: 430px; font-size: 15px; line-height: 1.6; color: var(--n400); }
/* One house, three kinds of work: the hero's shelter above each heading, what
   already stands drawn faint and the work itself in the warm line, as an architect
   marks existing against new. Each draws once as its card arrives - the house
   first, then the work. */
.services li { padding-right: 32px; }
.svc-art { display: block; width: 150px; height: auto; margin-bottom: 6px; fill: none; stroke-linecap: round; stroke-linejoin: round; overflow: visible; }
.svc-art .gd { stroke: var(--paper); stroke-opacity: 0.14; stroke-width: 1; }
.svc-art .ex { stroke: var(--paper); stroke-opacity: 0.34; stroke-width: 1.3; }
.svc-art .rm { stroke: var(--paper); stroke-opacity: 0.3; stroke-width: 1.2; stroke-dasharray: 3 4; }
.svc-art .nw { stroke: #c98b4b; stroke-opacity: 0.95; stroke-width: 1.7; }
.js .svc-art .gd, .js .svc-art .ex, .js .svc-art .nw { stroke-dasharray: 1; stroke-dashoffset: 1; }
.js .svc-art .rm { opacity: 0; transition: opacity 600ms var(--ease) 700ms; }
.js .services li.in .svc-art .gd, .js .services li.in .svc-art .ex { animation: ld 1100ms cubic-bezier(0.33, 0, 0.2, 1) 250ms forwards; }
.js .services li.in .svc-art .nw { animation: ld 1000ms cubic-bezier(0.33, 0, 0.2, 1) 950ms forwards; }
.js .services li.in .svc-art .rm { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .js .svc-art .gd, .js .svc-art .ex, .js .svc-art .nw { animation: none; stroke-dashoffset: 0; }
  .js .svc-art .rm { opacity: 1; transition: none; }
}

/* ---------- process: the services' line numerals, carried across ---------- */
.steps { list-style: none; margin: 32px 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-top: 1px solid var(--n800); }
.steps li { position: relative; border-bottom: 1px solid var(--n800); border-left: 1px solid var(--n800); }
.steps li:first-child { border-left: 0; }
.step { position: relative; overflow: hidden; display: flex; flex-direction: column; gap: 10px; width: 100%; padding: 26px 26px 28px; }
.step-num { position: absolute; right: 14px; top: -20px; font-family: var(--fh); font-weight: 300; font-size: 108px; line-height: 1; letter-spacing: -0.05em; color: transparent; -webkit-text-stroke: 1px var(--n800); pointer-events: none; transition: transform 1s var(--ease), -webkit-text-stroke-color 400ms var(--ease); }
.step-num { -webkit-text-stroke-color: var(--e700); }
.step:hover .step-num { transform: translateY(8px); -webkit-text-stroke-color: var(--e600); }
.step .h3, .step .short { position: relative; }
/* The numerals sit behind the words, and a drawing breaks a line where a label
   crosses it: each line of text carries a thin ink wipeout, so a numeral's stroke
   stops where a word begins. Same numerals, same place, same size. */
.wo { background: var(--ink); -webkit-box-decoration-break: clone; box-decoration-break: clone; padding: 0.12em 0.28em 0.16em; margin: 0 -0.28em; }
.step .short { font-size: 15px; line-height: 1.6; color: var(--n500); }
.steps .detail { position: absolute; left: -1px; right: -1px; top: 100%; z-index: 4; display: flex; flex-direction: column; gap: 10px; max-height: 0; padding: 0 26px; overflow: hidden; opacity: 0; background: var(--ink); border: 1px solid var(--e700); border-top: 0; box-shadow: 0 26px 50px rgba(0, 0, 0, 0.5); transition: max-height 420ms var(--ease), padding 420ms var(--ease), opacity 300ms var(--ease); }
/* on a pointer the note follows the pointer; a tap is only for touch */
@media (hover: hover) { .step { cursor: default; } }
/* A mouse click focuses the button, and :focus-within kept the note open long
   after the pointer had gone - that, not any handler, was what made a phase
   stick. Keyboard focus is separated out with :focus-visible, which a click
   never sets, and kept in its own rule so a browser without :has() loses only
   the keyboard case and not hover. */
.steps li:hover .detail, .steps li.open .detail { max-height: 340px; padding: 18px 26px 22px; opacity: 1; }
.steps li:has(.step:focus-visible) .detail { max-height: 340px; padding: 18px 26px 22px; opacity: 1; }
.steps .detail .long { font-size: 13px; line-height: 1.55; color: var(--n400); }
.steps .detail .deliv { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.steps .detail .deliv span { position: relative; padding-left: 13px; font-family: var(--fh); font-size: 10px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--n500); }
.steps .detail .deliv span::before { content: ''; position: absolute; left: 0; top: 7px; width: 7px; height: 1px; background: var(--e700); }

/* ---------- inquiry ---------- */
.inquiry { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: clamp(32px, 5vw, 76px); align-items: start; }
.inq-intro { display: flex; flex-direction: column; gap: 18px; }
.inq-form { display: flex; flex-direction: column; gap: 20px; padding: clamp(20px, 2.4vw, 32px); border: 1px solid var(--n800); background: rgba(250, 249, 245, 0.015); }
.f-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field input, .field select, .field textarea { width: 100%; font: inherit; font-size: 16px; color: var(--paper); background: transparent; border: 0; border-bottom: 1px solid var(--n700); border-radius: 0; padding: 12px 0 10px; outline: none; transition: border-color 250ms var(--ease); -webkit-appearance: none; appearance: none; }
.field select { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8'><path d='M1 1l5 5 5-5' stroke='%23AB9F8E' stroke-width='1.5' fill='none' stroke-linecap='round'/></svg>"); background-repeat: no-repeat; background-position: right 4px center; padding-right: 24px; }
.field select option { background: var(--ink); color: var(--paper); }
.field textarea { resize: vertical; min-height: 84px; }
.field ::placeholder { color: var(--n500); }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--e400); }
.field.err input, .field.err textarea { border-color: var(--err); }
.f-err { font-size: 13px; color: #D9826F; min-height: 0; }
.f-foot { display: flex; justify-content: space-between; gap: 16px; }
.f-foot .micro { font-size: 10px; color: var(--n500); }
.f-submit { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; }
.form-note { margin: 0; font-size: 14px; color: var(--n400); max-width: 360px; }
/* the hand-off that replaces the form once the note is written */
.handoff:focus { outline: none; }
.ho-ok { color: var(--e300); }
.ho-msg { margin: 0; padding: 16px 18px; border: 1px solid var(--n800); background: rgba(250, 249, 245, 0.02); font-size: 14px; line-height: 1.6; color: var(--n300); white-space: pre-wrap; overflow-wrap: anywhere; max-height: 210px; overflow: auto; }
.ho-acts { display: flex; flex-wrap: wrap; gap: 12px; }
.ho-direct { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 16px; padding-top: 14px; border-top: 1px solid var(--n900); }
.ho-direct a { color: var(--n200); font-size: 15px; }
.ho-direct a:hover { color: var(--paper); }
.ho-link { font-family: var(--fh); font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--e300); border-bottom: 1px solid var(--e700); padding-bottom: 2px; }
.ho-link:hover { color: var(--e200); border-color: var(--e400); }
.ho-link:last-child { margin-left: auto; color: var(--n400); border-color: var(--n700); }

/* ---------- footer ---------- */
/* The last section sits closer to the rule than the others - with the footer down
   to one line, a full section's bottom padding above it just reads as a hole. */
#inquiry { padding-bottom: clamp(22px, 2.6vw, 38px); }

/* One line under the rule: copyright, then the contact facts. The lockup and the
   tagline are gone from here - the page has already said who it is. */
.foot { border-top: 1px solid var(--n900); padding: 20px 0 24px; }
/* three parts on one line, with the address held in the true centre of the page
   rather than wherever the two notices either side happen to leave it */
.foot-base { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; gap: 10px 30px; }
.foot-base .micro { font-size: 10px; color: var(--n500); }
.foot-mail { justify-self: center; color: var(--n400); font-size: 11px; }
.foot-mail:hover { color: var(--paper); }
.foot-loc { justify-self: end; }

/* ---------- takeover: the photograph comes forward ----------
   Grant, 2026-09-18, with his own full-bleed project view as the reference:
   clicking a row must not cut to a panel. The list text fades out, the same
   photograph that was already behind the list comes to the front full bleed,
   and the project's text layers on after it lands. The strip along the bottom
   sits back at a third opacity and brightens to full on hover. */
.opening .bar, .opening .work-head, .opening .worklist { opacity: 0; pointer-events: none; transition: opacity 260ms var(--ease); }

.takeover { position: fixed; inset: 0; z-index: 100; }
.to-veil { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 620ms var(--ease); background: linear-gradient(180deg, rgba(26, 25, 23, 0.6) 0%, rgba(26, 25, 23, 0.1) 16%, rgba(26, 25, 23, 0.02) 30%, rgba(26, 25, 23, 0.35) 50%, rgba(26, 25, 23, 0.74) 68%, rgba(26, 25, 23, 0.93) 84%, rgba(26, 25, 23, 0.98) 100%); }
.takeover.open .to-veil { opacity: 1; }
/* A drawing is a sheet: the field is paper, so the type turns to ink and the
   foot whitens instead of darkening. White type on a pale sheet is unreadable. */
.takeover.plan .to-veil { background: linear-gradient(180deg, rgba(250, 249, 245, 0) 0%, rgba(250, 249, 245, 0) 46%, rgba(250, 249, 245, 0.72) 68%, rgba(250, 249, 245, 0.95) 84%, rgba(250, 249, 245, 0.99) 100%); }
.takeover.plan.bare .to-veil { opacity: 0.18; }
.takeover.plan .to-title { color: var(--ink); text-shadow: none; }
.takeover.plan .to-count { color: var(--n600); text-shadow: none; }
.takeover.plan .to-type { color: var(--e700); }
.takeover.plan .to-type .lead { background: var(--e700); }
.takeover.plan .to-summary { color: var(--n800); text-shadow: none; }
.takeover.plan .to-specs li { color: var(--n700); text-shadow: none; }
.takeover.plan .to-specs li::before { background: var(--e700); }
.takeover.plan .to-close, .takeover.plan .to-arrow-chip { background: rgba(26, 25, 23, 0.74); border-color: rgba(26, 25, 23, 0.25); }
.takeover.plan .to-arrow-label { color: var(--n800); text-shadow: none; }
/* on a white plan the chips invert the other way - paper on paper is nothing */
.takeover.plan .to-close:hover, .takeover.plan .to-arrow:hover .to-arrow-chip { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.to-ui { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: flex-end; padding: clamp(20px, 3vw, 44px) var(--pad) clamp(16px, 2.2vw, 30px); }
/* Grant, 2026-09-20: the text sits on the bottom edge. The thumbnails only fill the
   left column, so the description takes a column of its own running the full height,
   and its last line lands on the same line as the bottom of the thumbnails. */
.to-bottom { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); grid-template-areas: "left right" "strip right"; column-gap: clamp(24px, 5vw, 80px); row-gap: clamp(20px, 3vh, 34px); align-items: end; }
.to-body { display: contents; }
.to-left { grid-area: left; }
.to-right { grid-area: right; align-self: end; }
.to-strip { grid-area: strip; }
.to-ui > * { opacity: 0; transform: translateY(18px); transition: opacity 600ms var(--ease), transform 600ms var(--ease); }
.takeover.ui .to-ui > * { opacity: 1; transform: none; }
.takeover.ui .to-bottom { transition-delay: 90ms; }
.takeover.ui .to-arrow { transition-delay: 240ms; opacity: 0.5; }
.to-body > *, .to-strip { opacity: 0; transform: translateY(14px); transition: opacity 600ms var(--ease), transform 600ms var(--ease); }
.takeover.ui .to-body > * { opacity: 1; transform: none; }
.takeover.ui .to-right { transition-delay: 150ms; }
.takeover.ui .to-strip { opacity: 0.42; transform: none; transition-delay: 260ms; }
.takeover.ui .to-strip:hover, .takeover.ui .to-strip:focus-within { opacity: 1; transition-delay: 0ms; }
.to-count { color: var(--n300); margin-bottom: 16px; text-shadow: 0 1px 16px rgba(0, 0, 0, 0.5); }
.to-close { position: absolute; top: clamp(20px, 3vw, 44px); right: var(--pad); display: inline-flex; align-items: center; gap: 14px; padding: 14px 22px; border: 1px solid rgba(250, 249, 245, 0.45); color: var(--paper); background: rgba(26, 25, 23, 0.34); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); transition: background-color 300ms var(--ease), border-color 300ms var(--ease), color 300ms var(--ease); }
.to-close:hover { background: var(--paper); border-color: var(--paper); color: var(--ink); }
.to-close .micro { color: inherit; }
.to-close .x { position: relative; width: 14px; height: 14px; }
.to-close .x::before, .to-close .x::after { content: ''; position: absolute; left: 0; top: 6px; width: 14px; height: 1px; background: currentColor; }
.to-close .x::before { transform: rotate(45deg); }
.to-close .x::after { transform: rotate(-45deg); }

.to-type { display: flex; align-items: center; gap: 16px; color: var(--e300); }
.to-type .lead { width: 44px; height: 1px; background: var(--e300); }
.to-title { font-family: var(--fh); font-weight: 300; font-size: clamp(38px, 5.2vw, 88px); line-height: 0.98; letter-spacing: -0.03em; color: var(--paper); margin: 18px 0 14px; text-shadow: 0 2px 30px rgba(0, 0, 0, 0.35); }
.to-summary { margin: 0; max-width: 560px; font-size: clamp(16px, 1.25vw, 19px); line-height: 1.6; color: var(--n100); text-shadow: 0 1px 20px rgba(0, 0, 0, 0.45); }
.to-specs:empty { display: none; }
.to-specs { list-style: none; display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 18px 0 0; padding: 0; max-width: 560px; }
.to-specs li { position: relative; padding-left: 18px; font-size: 13px; line-height: 1.5; color: var(--n200); text-shadow: 0 1px 16px rgba(0, 0, 0, 0.5); }
.to-specs li::before { content: ''; position: absolute; left: 0; top: 10px; width: 9px; height: 1px; background: var(--e300); }

.to-strip { display: flex; justify-content: flex-start; align-items: flex-end; gap: 12px; flex-wrap: wrap; opacity: 0.42; transition: opacity 400ms var(--ease); }
.to-none { color: var(--n300); }
.to-thumb { position: relative; width: clamp(76px, 8vw, 116px); aspect-ratio: 3 / 2; overflow: hidden; border: 1px solid rgba(250, 249, 245, 0.25); box-shadow: 0 0 0 1px rgba(26, 25, 23, 0.22); opacity: 0.72; transition: opacity 350ms var(--ease), border-color 350ms var(--ease), transform 350ms var(--ease); }
.to-thumb img { width: 100%; height: 100%; object-fit: cover; }
.to-thumb:hover, .to-thumb:focus-visible { opacity: 1; transform: translateY(-4px); border-color: var(--paper); }
.to-thumb[aria-current="true"] { opacity: 1; border-color: var(--e300); }

.to-arrow { position: absolute; top: 50%; translate: 0 -50%; display: grid; justify-items: center; gap: 9px; padding: 0; border: 0; background: none; color: var(--paper); transition: opacity 300ms var(--ease); }
.to-arrow-chip { width: 46px; height: 46px; display: grid; place-items: center; border: 1px solid rgba(250, 249, 245, 0.3); color: inherit; background: rgba(26, 25, 23, 0.34); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); transition: background-color 300ms var(--ease), color 300ms var(--ease), border-color 300ms var(--ease); }
.to-arrow:hover .to-arrow-chip { background: var(--paper); border-color: var(--paper); color: var(--ink); }
/* has to out-specify .takeover.ui .to-arrow, which sets the resting 0.5 */
.takeover.ui .to-arrow:hover { opacity: 1; transition-delay: 0ms; }
.to-arrow-label { font-size: 9px; letter-spacing: 0.15em; color: var(--paper); white-space: nowrap; text-shadow: 0 1px 12px rgba(26, 25, 23, 0.9), 0 0 4px rgba(26, 25, 23, 0.7); transition: color 300ms var(--ease), text-shadow 300ms var(--ease); }
.to-arrow svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.2; }
.to-arrow.prev { left: clamp(14px, 2.4vw, 36px); }
.to-arrow.next { right: clamp(14px, 2.4vw, 36px); }

/* ---------- small screens ---------- */
@media (max-width: 960px) {
  .nav { gap: 20px; }
  .nav > a:not(.btn) { display: none; }
  /* every section link folds away on a phone except the one that matters */
  .nav > a[data-nav="inquiry"] { display: block; }
  .hero-grid, .about, .inquiry { grid-template-columns: 1fr; }
  .wl-btn { grid-template-columns: 40px minmax(0, 1fr) 40px; gap: 16px; }
  .wl-type, .wl-year { display: none; }
  .wl-title { font-size: clamp(22px, 5vw, 30px); }
  .services { grid-template-columns: 1fr; }
  .services li, .services li:not(:first-child) { padding: 32px 0; border-left: 0; }
  .svc-art { width: 120px; margin-bottom: 4px; }
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .steps li:nth-child(3) { border-left: 0; }
  .f-row { grid-template-columns: 1fr; }
  .foot-base { grid-template-columns: 1fr; justify-items: center; gap: 10px; text-align: center; }
  .foot-mail, .foot-loc { justify-self: center; }
  .to-bottom { grid-template-columns: 1fr; grid-template-areas: "left" "right" "strip"; row-gap: 14px; }
  .to-specs { display: none; }
  .to-arrow { display: none; }
  .to-thumb { width: 64px; }
  .to-close { padding: 11px 16px; }
  .title-block { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .title-block > div:nth-child(3) { border-left: 0; }
  .title-block > div:nth-child(n+3) { border-top: 1px solid var(--n800); }
}
@media (max-width: 560px) {
  /* The lockup is nearly seven times as wide as it is tall, so on a phone the
     whole artwork has to fit the screen - which would leave the mark drawing at
     about 110px. So the phone starts in close on the mark and pulls back as the
     window opens: the mark draws at roughly the size it always had, and settles
     to its place in the lockup on the same 820ms as the words running out. */
  .intro-clip { --full: min(90vw, 420px); }
  .intro-group { scale: 1.6; will-change: opacity, scale; }
  .intro-ov.play .intro-group { animation: sd-in 560ms var(--soft) 60ms forwards, sd-back 820ms var(--soft) 1460ms forwards; }
  .tblock { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tblock > div:nth-child(n) { border-left: 1px solid var(--n800); border-top: 1px solid var(--n800); }
  .tblock > .tb-wide { border-top: 0; border-left: 0; }
  .tblock > div:nth-child(2), .tblock > div:nth-child(4) { border-left: 0; }
  .tblock dd { font-size: 19px; }
  .tblock > .tb-wide dd { font-size: 23px; }
  .steps { grid-template-columns: 1fr; }
  .steps li { border-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .intro .intro-ov { display: none; }
  .ly, .sl.photo { animation: none; opacity: 1; }
  .sl.photo { opacity: 0; }
  .js .rv { opacity: 1; transform: none; transition: none; }
  .steps::before { transform: scaleX(1); transition: none; }
  .wl-bleed, .wl-title, .wl-row::after { transition: none; }
  .worklist-wrap.on .wl-bleed { opacity: 0.4; transform: none; }
  .wl-bleed, .wl-bleed.promote, .wl-img, .to-veil, .to-thumb, .to-ui > * { transition: none; }
}

/* a coarse pointer cannot hover, so the thumbnail rides in the row and the
   plate never appears. Last in the file on purpose: it has to win over the
   width query above on a narrow touch screen. */
@media (hover: none), (pointer: coarse) {
  .wl-thumb { display: block; width: 84px; height: 58px; overflow: hidden; background: var(--n900); }
  .wl-thumb img { width: 100%; height: 100%; object-fit: cover; }
  .wl-btn { grid-template-columns: 40px 84px minmax(0, 1fr) 40px; gap: 16px; }
  .wl-type, .wl-year { display: none; }
}

/* a short window cannot hold the whole foot: the details go first, then size */
@media (max-height: 660px) {
  .to-specs { display: none; }
  .to-title { font-size: clamp(32px, 4.4vw, 58px); margin: 12px 0 10px; }
  .to-bottom { row-gap: 16px; }
  .to-thumb { width: clamp(64px, 6vw, 88px); }
}

/* ---------- a phone turned on its side ----------
   The takeover is the one place rotating actually pays: the photographs and the
   plans are landscape, so sideways is how they want to be seen. Everything
   below is about a short, wide window, not about phones as such.

   The one thing that genuinely breaks is contrast. The veil is tuned for a tall
   window, where the type sits well down the picture; squeeze the window to 390px
   and the label lands in the brightest part of the sky. So the veil is
   recompressed - the same reading, over a third of the height. */
@media (max-height: 520px) and (orientation: landscape) {
  .to-veil { background: linear-gradient(180deg, rgba(26, 25, 23, 0.55) 0%, rgba(26, 25, 23, 0.14) 12%, rgba(26, 25, 23, 0.26) 24%, rgba(26, 25, 23, 0.6) 46%, rgba(26, 25, 23, 0.84) 66%, rgba(26, 25, 23, 0.95) 84%, rgba(26, 25, 23, 0.98) 100%); }
  .takeover.plan .to-veil { background: linear-gradient(180deg, rgba(250, 249, 245, 0) 0%, rgba(250, 249, 245, 0.2) 24%, rgba(250, 249, 245, 0.8) 48%, rgba(250, 249, 245, 0.96) 70%, rgba(250, 249, 245, 0.99) 100%); }
  .to-ui { padding-top: 16px; padding-bottom: 14px; }
  .to-title { font-size: clamp(28px, 3.4vw, 42px); margin: 8px 0 8px; }
  .to-summary { font-size: 14px; line-height: 1.5; }
  .to-bottom { row-gap: 12px; }
  .to-close { padding: 9px 14px; }
  /* sideways there is width to spare, so the arrows come back */
  .to-arrow { display: grid; }
  .to-arrow-label { display: none; }
  .to-arrow-chip { width: 38px; height: 38px; }
}

/* Sideways, the header cannot eat a quarter of the screen. The hero itself needs
   nothing: it is sized in vh, so it shortens with the window and the type still
   lands on the threshold. */
@media (max-height: 520px) and (orientation: landscape) {
  .bar { padding-top: 10px; padding-bottom: 10px; }
  .bar .lockup, .bar.solid .lockup { height: 22px; }
}

/* Grant, 2026-09-19: choosing a photograph should show the photograph. The type
   clears out, the foot of the veil lifts, and a click on the picture brings it
   all back. */
.takeover.bare .to-left, .takeover.bare .to-right { opacity: 0; transform: translateY(12px); pointer-events: none; }
.takeover.bare .to-veil { opacity: 0.4; }
.takeover.bare .to-strip { opacity: 0.3; }
.takeover.bare .to-strip:hover, .takeover.bare .to-strip:focus-within { opacity: 1; }

/* ---------- the drawing: hero, and one turn per section ----------
   The hero states the idea. Every other section gets one turn of the same line,
   placed in that section's own empty ground (measured, never guessed) so it can
   never run through the words. Drawn once, on arrival. Nothing loops. */
.lineHero { position: relative; min-height: 84vh; display: block; overflow: hidden; }
.lh-art { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; }
/* The type is not centred in the box - it stands ON the threshold. Script writes
   --ground with the real y of the warm line, the block hangs its bottom edge off
   it, and the link steps below it, so the line reads as the floor of the type. */
.lineHero { --hx: clamp(var(--pad), 15vw, 21vw); }
.lh-copy { position: absolute; left: var(--hx); top: var(--ground, 74%); translate: 0 -100%; z-index: 2; max-width: min(53vw, 720px); padding-bottom: clamp(18px, 2.1vw, 30px); }
.lh-lbl { color: var(--n500); }
/* The sentence is set at two sizes. The opening clause is the smaller and the
   quieter of the two and steps in from the margin; the part that carries the
   idea is large, flush left, and lands square on the threshold below it. No
   styling tricks - the hierarchy is scale, tone and one step. */
.lh-h { display: grid; justify-items: start; font-family: var(--fh); font-weight: 300; font-size: clamp(38px, 5.2vw, 76px); line-height: 1.04; letter-spacing: -0.028em; color: var(--paper); margin: 16px 0 0; }
.lh-a { font-size: 0.47em; line-height: 1.18; letter-spacing: -0.014em; color: var(--n200); margin-left: clamp(18px, 2.6vw, 52px); }
.lh-b { font-size: 1em; margin-top: 0.1em; }
/* the hero runs straight into the page instead of stopping and starting again */
#about { padding-top: clamp(24px, 2.6vw, 40px); }
.sec, .worklist-wrap, .foot { position: relative; }
/* positioning the sections for the line layer also put them in paint order, so a
   later section covered the process panel when it opened. Process sits above. */
#process { z-index: 3; }

/* ---------- phone ---------- */
@media (max-width: 760px) {
  /* a wider margin than the rest of the page: the hero is the one place the type
     should not run to the edges, and the drawing needs the room either side */
  .lineHero { min-height: 82vh; --hx: clamp(34px, 11vw, 54px); }
  .lh-copy { max-width: calc(100% - var(--hx) * 2); padding-bottom: 20px; }
  .lh-h { font-size: clamp(40px, 12.2vw, 58px); }
  .lh-a { font-size: 0.5em; margin-left: 14px; }
  #about { padding-top: clamp(20px, 5vw, 34px); }
}
.sec-lines { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; pointer-events: none; }
.sec > .wrap, .worklist-wrap > .wrap { position: relative; z-index: 1; }
.ld { stroke-dasharray: 1; stroke-dashoffset: 1; }
.ld.on { animation: ld 1500ms cubic-bezier(0.33, 0, 0.2, 1) forwards; }
/* already drawn: show it, do not draw it again */
.ld.done { animation: none; stroke-dashoffset: 0; }
@keyframes ld { to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) { .ld, .ld.on { animation: none; stroke-dashoffset: 0; } }

/* ---------- the process, read as a sequence ----------
   The four cards say what each phase is; this rail above them says they happen
   one after another. A tick where each begins, a chevron at each hand-off, and
   the line fading past the last card, since construction does not end on a page.
   A phase switched off dims out of the rail with its card. */
.seq { position: relative; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: clamp(26px, 3vw, 40px) 0 0; }
.seq-cell { position: relative; height: 16px; }
.seq-cell::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--e700); }
/* the tick that opens each phase */
.seq-cell::after { content: ''; position: absolute; left: 0; top: calc(50% - 5px); width: 1px; height: 11px; background: var(--e600); }
/* the hand-off between one phase and the next */
.seq-tick { position: absolute; left: -4px; top: 50%; width: 7px; height: 7px; translate: 0 -50%; rotate: 45deg; border-top: 1px solid var(--e600); border-right: 1px solid var(--e600); }
.seq-cell:first-child .seq-tick { display: none; }
.seq-last::before { background: linear-gradient(to right, var(--e700) 0%, var(--e700) 46%, rgba(168, 117, 74, 0) 100%); }
.seq-last::after { background: var(--e600); }
/* Something has to move along it, or it is only a diagram. One pass when the
   section arrives: a point leaves the first tick, runs the phases in order, and
   goes out the far end where the line itself is already fading. It runs once and
   it does not come back - the same rule every other line on this page follows. */
.seq-run { position: absolute; left: 0; top: 50%; z-index: 1; width: 0; height: 1px; translate: 0 -50%; background: linear-gradient(to right, rgba(149, 107, 85, 0) 0%, var(--e600) 55%, var(--e400) 100%); }
.seq-run::after { content: ''; position: absolute; right: -2px; top: -2px; width: 5px; height: 5px; border-radius: 50%; background: var(--e300); box-shadow: 0 0 9px 1px rgba(201, 139, 75, 0.55); }
.seq.in .seq-run { animation: seq-run 2000ms var(--ease) 260ms forwards; }
.seq.in .seq-run::after { animation: seq-dot 2000ms var(--ease) 260ms forwards; }
@keyframes seq-run { from { width: 0; } to { width: 100%; } }
/* the point dies away over the last stretch, where the rail is fading anyway */
@keyframes seq-dot { 0%, 74% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .seq.in .seq-run, .seq.in .seq-run::after { animation: none; }
  .seq-run { width: 100%; }
  .seq-run::after { opacity: 0; }
}
@media (max-width: 1080px) {
  /* the cards fall to two columns, so the rail does too */
  .seq { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .seq-cell:nth-child(3) .seq-tick { display: none; }
}
@media (max-width: 760px) {
  /* stacked: the hand-off turns and points down, between one card and the next */
  .seq { display: none; }
  .steps li { position: relative; }
  .steps li:not(:last-child)::after { content: ''; position: absolute; left: 26px; bottom: -4px; width: 7px; height: 7px; rotate: 135deg; border-top: 1px solid var(--e600); border-right: 1px solid var(--e600); background: var(--ink); transition: opacity 400ms var(--ease); }
  /* the rail is gone at this width, so the progression is carried by the
     hand-offs themselves: they arrive in order, top to bottom, once */
  /* Stacked, the note drops over the card below and used to cover its number.
     Its left edge still lines up with the card; the right comes in far enough to
     clear the numeral, which is 108px type sitting 14px off the right edge. The
     column that leaves is narrow, so the note is set a little tighter to suit. */
  .steps .detail { right: 157px; padding-left: 18px; padding-right: 18px; }
  .steps li:hover .detail, .steps li.open .detail,
  .steps li:has(.step:focus-visible) .detail { padding: 16px 18px 18px; }
  .steps .detail .long { font-size: 12.5px; line-height: 1.5; }
  .steps .detail .deliv { gap: 5px 12px; }
  .steps li:not(:last-child)::after { opacity: 0; }
  .steps.in li:not(:last-child)::after { animation: seq-down 520ms var(--ease) forwards; }
  .steps.in li:nth-child(1)::after { animation-delay: 500ms; }
  .steps.in li:nth-child(2)::after { animation-delay: 1100ms; }
  .steps.in li:nth-child(3)::after { animation-delay: 1700ms; }
  @keyframes seq-down { from { opacity: 0; translate: 0 -5px; } to { opacity: 1; translate: 0 0; } }
  @media (prefers-reduced-motion: reduce) {
    .steps li:not(:last-child)::after, .steps.in li:not(:last-child)::after { animation: none; opacity: 1; }
  }
}

/* ---------- the select we can style ----------
   The real <select> keeps the value and stays reachable; it is only moved out of
   sight. Everything visible is ours, so it takes the page's own colours. */
.field select.sel-native, .sel-native { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.sel { position: relative; }
.sel-btn { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; font: inherit; font-size: 16px; text-align: left; color: var(--paper); background: transparent; border: 0; border-bottom: 1px solid var(--n700); padding: 12px 0 10px; transition: border-color 250ms var(--ease); }
.sel-btn.empty { color: var(--n500); }
.sel-btn:hover { border-color: var(--n600); }
.sel.open .sel-btn, .sel-btn:focus-visible { border-color: var(--e400); outline: none; }
.sel-arrow { flex: none; width: 12px; height: 8px; background: var(--n400); clip-path: polygon(0 12%, 50% 88%, 100% 12%, 88% 0, 50% 62%, 12% 0); transition: transform 300ms var(--ease), background-color 250ms var(--ease); }
.sel.open .sel-arrow { transform: rotate(180deg); background: var(--e400); }
.sel-list { position: absolute; left: 0; right: 0; top: calc(100% + 1px); z-index: 12; list-style: none; margin: 0; padding: 6px 0; background: var(--ink); border: 1px solid var(--e700); box-shadow: 0 22px 44px rgba(0, 0, 0, 0.55); opacity: 0; visibility: hidden; transform: translateY(-6px); transition: opacity 220ms var(--ease), transform 260ms var(--ease), visibility 0s linear 260ms; }
.sel.open .sel-list { opacity: 1; visibility: visible; transform: translateY(0); transition-delay: 0s; }
.sel-list li { padding: 10px 16px; font-size: 15px; color: var(--n300); cursor: pointer; transition: color 180ms var(--ease), background-color 180ms var(--ease); }
.sel-list li:hover, .sel-list li.here { background: var(--n900); color: var(--paper); }
.sel-list li[aria-selected="true"] { color: var(--paper); }
.sel-list li[aria-selected="true"]::after { content: ""; float: right; width: 5px; height: 5px; margin-top: 8px; background: var(--e600); }
