/* ─────────────────────────────────────────────────────────────────────────
   Portfolio — shared design system
   Built once, arranged twice: /product and /creative use the SAME components
   in a different order. Anything door-specific is a modifier, never a fork.

   Web-first with print CSS (per TODO 2026-07-26). Tokens live here so the
   same markup can be re-skinned without touching content.
   ───────────────────────────────────────────────────────────────────────── */

:root{
  /* Ink — near-black with a warm cast, not #000. Reads as considered. */
  --ink:      #1a1714;
  --ink-2:    #4a443d;
  --ink-3:    #7d746a;

  /* Paper — warm off-white. A pure white page reads as a template. */
  --paper:    #faf7f2;
  --paper-2:  #f2ede4;
  --rule:     #e3dbcf;

  /* One accent, used sparingly. Restraint over decoration. */
  --accent:   #b1512f;
  --accent-2: #8c3d22;
  --accent-soft:#f6ece6;

  /* A fifth colour, and it had to earn its place the way ⛔ and 🟨 did in the
     charter — by being needed for something no existing colour could say. It marks
     ONE thing on this site: a count of checks that failed. --accent is a warm rust
     and reads as emphasis; a failure needs to read as a failure. Deeper and redder
     than the accent so it separates, still warm so it belongs. ⛔ If it ever gets
     used for decoration, delete it. */
  --flag:     #b3261e;

  /* Dark band — used for the hero and the case-study canvas shots, so the
     dark-tool/white-deliverable idea Homestead argues is visible in the site
     itself rather than only described. */
  --dark:     #14110f;
  --dark-2:   #201b18;
  --dark-ink: #f4efe8;
  --dark-ink-2:#a99f94;

  --serif: Georgia,"Iowan Old Style","Times New Roman",serif;
  --sans: -apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;
  --mono: ui-monospace,SFMono-Regular,Menlo,monospace;

  --measure: 34rem;      /* readable line length */
  --wide: 68rem;         /* full content width */
  --step: clamp(1rem, 0.6rem + 1.2vw, 1.6rem);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* .doorbar is position:sticky;top:0 and measures ~50px (13px type + .7rem block padding + 1px rule).
   Without this, a fragment link scrolls its target flush to the viewport top and the bar covers it —
   you arrive already scrolled, at a heading you cannot see. It bit both cross-page deep links
   (creative → path/#agency and creative → product/#moneyledger) and every pre-deploy invariant passed
   it, because they check that an anchor RESOLVES, not where it lands. 5rem clears the bar with air. */
[id]{scroll-margin-top:5rem}
@media print{[id]{scroll-margin-top:0}}

body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:var(--sans); font-size:17px; line-height:1.6;
  -webkit-font-smoothing:antialiased;
}

img{max-width:100%; height:auto; display:block}
a{color:inherit}

/* ── layout ─────────────────────────────────────────────────────────────── */
.wrap{width:min(100% - 2.4rem, var(--wide)); margin-inline:auto}
.measure{max-width:var(--measure)}
section{padding-block:clamp(3rem,7vw,6rem)}
.rule{border:0; border-top:1px solid var(--rule); margin:0}

/* ── door switch: never trap a visitor on the wrong door ────────────────── */
.doorbar{
  position:sticky; top:0; z-index:50;
  background:color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter:blur(8px);
  border-bottom:1px solid var(--rule);
  font-size:13px;
}
.doorbar .wrap{display:flex; align-items:center; gap:1.25rem; padding-block:.7rem}
/* ⛔ THE NAME IS THE WAY HOME. It was a <span> for months — FOUNDUX 001, "no way back to
   the splash." Now an <a>, and it has to be visibly clickable or it is the same defect
   with different markup: a link nobody can tell is a link. */
.doorbar .who{font-weight:700; letter-spacing:-.01em; margin-right:auto;
              color:inherit; text-decoration:none;
              border-bottom:1px solid transparent}
.doorbar .who:hover,
.doorbar .who:focus-visible{border-bottom-color:currentColor}
.doorbar a{
  color:var(--ink-3); text-decoration:none; padding:.25rem 0;
  border-bottom:2px solid transparent;
}
.doorbar a:hover{color:var(--ink)}
.doorbar a[aria-current="page"]{color:var(--ink); border-bottom-color:var(--accent)}

/* ── hero ───────────────────────────────────────────────────────────────── */
.hero{background:var(--dark); color:var(--dark-ink); padding-block:clamp(4rem,10vw,7.5rem)}
.byline{
  font-family:var(--mono); font-size:12px; letter-spacing:.22em;
  text-transform:uppercase; color:var(--accent); margin:0 0 1.6rem;
}
.hero h1{
  font-family:var(--serif); font-weight:400;
  font-size:clamp(2.1rem, 1.1rem + 4vw, 4rem); line-height:1.08;
  letter-spacing:-.02em; margin:0 0 1.4rem; max-width:20ch;
}
.hero h1 em{font-style:normal; color:var(--accent); }
.hero .lede{
  font-size:clamp(1.05rem,.95rem + .5vw,1.3rem); line-height:1.55;
  color:var(--dark-ink-2); max-width:46ch; margin:0;
}
.hero .lede strong{color:var(--dark-ink); font-weight:600}

/* ── section headings ───────────────────────────────────────────────────── */
.kicker{
  font-family:var(--mono); font-size:11px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--accent); margin:0 0 .75rem;
}
h2{
  font-family:var(--serif); font-weight:400;
  font-size:clamp(1.6rem,1.2rem + 1.6vw,2.4rem); line-height:1.15;
  letter-spacing:-.015em; margin:0 0 1rem;
  /* Orphans. A serif display line at a fluid size will drop its last word onto a line alone at some
     viewport width — spotted on "Nobody asked me to build any of it." `balance` distributes the words
     across lines evenly instead of filling greedily. Progressive enhancement: a browser without it
     wraps exactly as before, so there is nothing to fall back to. */
  text-wrap:balance;
}
h1{text-wrap:balance}
/* `pretty` is the body-copy equivalent — it only prevents the last-line orphan rather than rebalancing
   the whole block, which is what you want for paragraphs. */
p,figcaption,.lede{text-wrap:pretty}
h3{font-size:1.05rem; font-weight:700; letter-spacing:-.005em; margin:0 0 .4rem}
p{margin:0 0 1.1rem}
p:last-child{margin-bottom:0}

/* ── case study ─────────────────────────────────────────────────────────── */
.case{border-top:1px solid var(--rule)}
.case-head{display:grid; gap:1.5rem; margin-bottom:2.5rem}
@media(min-width:56rem){
  .case-head{grid-template-columns:minmax(0,1fr) minmax(0,20rem); gap:3rem; align-items:start}
}
.case-meta{font-size:14.5px; color:var(--ink-2)}
.case-meta dt{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-3); margin-top:1rem;
}
.case-meta dt:first-child{margin-top:0}
.case-meta dd{margin:.2rem 0 0}

/* the one decision each case study turns on */
.decision{
  background:var(--paper-2); border-left:3px solid var(--accent);
  padding:1.25rem 1.5rem; margin:2rem 0; border-radius:0 6px 6px 0;
}
.decision .lbl{
  display:block; font-family:var(--mono); font-size:10.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--accent); font-weight:700; margin-bottom:.5rem;
}
.decision p{font-family:var(--serif); font-size:1.08rem; line-height:1.5}

figure{margin:2rem 0 0}
.shot{border:1px solid var(--rule); border-radius:8px; overflow:hidden; background:var(--paper-2)}
.shot.dark{background:var(--dark); border-color:var(--dark-2)}
figcaption{font-size:13.5px; color:var(--ink-3); line-height:1.5; margin-top:.7rem}
figcaption b{color:var(--ink-2); font-weight:600}

/* receipts — the numbers that make a claim checkable */
.tally{display:grid; grid-template-columns:repeat(auto-fit,minmax(9rem,1fr)); gap:1px;
  background:var(--rule); border:1px solid var(--rule); border-radius:8px; overflow:hidden; margin:2rem 0}
.tally div{background:var(--paper); padding:1rem 1.1rem}
.tally .k{font-family:var(--mono); font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-3)}
.tally .v{font-family:var(--serif); font-size:1.9rem; line-height:1.1; margin-top:.35rem}
.tally .s{font-size:12.5px; color:var(--ink-3); margin-top:.2rem}
.tally .hot .v{color:var(--accent)}
/* The failed-check count. The only red on the site — see --flag. */
.tally .flag{color:var(--flag); font-size:1.15rem; letter-spacing:-.01em}

/* ── the session-flow diagram (/practice/#language) ─────────────────────────
   ⛔ HTML + CSS, NOT SVG, AND NOT DECORATION. SVG text collapses to unreadable at
   phone widths and prints unpredictably; this reflows to a single column, keeps the
   text selectable and searchable, and survives ⌘P. It exists because the section
   argues the system is DESIGNED and then asked the reader to take that on faith. */
.flow{margin:2.25rem 0}
.flow-band{
  display:grid; gap:0; grid-template-columns:1fr; /* stacked by default — phone first */
  border:1px solid var(--rule); border-radius:8px; overflow:hidden; background:var(--paper-2);
}
@media(min-width:46rem){ .flow-band{grid-template-columns:1fr 0.678fr 1fr} }
.flow-stage{padding:1.05rem 1.15rem; background:var(--paper); border-bottom:1px solid var(--rule)}
.flow-stage:last-child{border-bottom:0}
@media(min-width:46rem){
  .flow-stage{border-bottom:0; border-right:1px solid var(--rule)}
  .flow-stage:last-child{border-right:0}
}
.flow-stage.mid{background:var(--paper-2)}
.flow-key{
  font-family:var(--mono); font-size:12.5px; letter-spacing:.1em; font-weight:700;
  color:var(--accent); display:block; margin-bottom:.4rem;
}
.flow-key.quiet{color:var(--ink-3)}
.flow-what{font-size:13.5px; color:var(--ink-2); line-height:1.5}
.flow-caps{display:flex; flex-wrap:wrap; gap:.4rem; margin-top:.75rem}
.flow-cap{
  font-family:var(--mono); font-size:11px; letter-spacing:.08em; font-weight:700;
  color:var(--accent-2); background:var(--accent-soft);
  border:1px solid color-mix(in srgb,var(--accent) 22%,transparent);
  border-radius:4px; padding:.2rem .45rem;
}
.flow-note{
  font-size:12.5px; color:var(--ink-3); line-height:1.55; margin-top:.85rem;
  padding-left:.9rem; border-left:2px solid var(--rule);
}
@media print{ .flow-band{background:#fff} .flow-stage,.flow-stage.mid{background:#fff!important} }

/* ── the proof list (/practice/#guards) ───────────────────────────────────
   Links out to the actual working proof files, not screenshots. The comparisons
   animate; a still of a comparison is not a comparison. */
.proofs{list-style:none;padding:0;margin:1.25rem 0}
/* Thumbnail beside the blurb. The whole tile is one link, so the picture and the
   title hit the same target — a thumbnail you cannot click reads as broken. */
.proofs li{border-top:1px solid var(--rule);padding:.85rem 0;
  display:grid; grid-template-columns:132px 1fr; gap:1rem; align-items:start}
.proofs .thumb{display:block;margin:0;border:1px solid var(--rule);border-radius:5px;
  overflow:hidden;background:var(--dark);line-height:0}
.proofs .thumb img{width:100%;height:auto;display:block;
  transition:transform .18s ease, opacity .18s ease}
.proofs .thumb:hover img{transform:scale(1.04);opacity:.92}
.proofs .txt{min-width:0}
@media(max-width:34rem){
  .proofs li{grid-template-columns:1fr; gap:.6rem}
  .proofs .thumb{max-width:200px}
}
@media print{ .proofs li{grid-template-columns:110px 1fr} }
.proofs li:last-child{border-bottom:1px solid var(--rule)}
.proofs a{display:inline-block;font-weight:600;font-size:15px;color:var(--accent);
  text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--accent) 35%,transparent)}
.proofs a:hover{border-bottom-color:var(--accent)}
.proofs span{display:block;font-size:13px;color:var(--ink-3);line-height:1.55;margin-top:.35rem}
@media print{.proofs a::after{content:" (bighiway.com" attr(href) ")";font-size:9pt;color:#666}}

/* ── links & CTA ────────────────────────────────────────────────────────── */
.more{
  display:inline-block; margin-top:1.5rem; font-size:14.5px; font-weight:600;
  color:var(--accent); text-decoration:none;
  border-bottom:1px solid color-mix(in srgb,var(--accent) 35%,transparent);
  padding-bottom:1px;
}
.more:hover{border-bottom-color:var(--accent)}

.cta{background:var(--dark); color:var(--dark-ink)}
.cta h2{color:var(--dark-ink)}
.cta p{color:var(--dark-ink-2); max-width:46ch}
.btn{
  display:inline-block; margin-top:1.5rem; margin-right:.75rem;
  padding:.8rem 1.4rem; border-radius:6px; text-decoration:none; font-size:15px; font-weight:600;
  background:var(--accent); color:#fff;
}
.btn.ghost{background:transparent; color:var(--dark-ink); border:1px solid var(--dark-ink-2)}

footer{padding-block:2.5rem; font-size:13px; color:var(--ink-3); border-top:1px solid var(--rule)}

/* ── print: the whole door prints as a leave-behind ─────────────────────── */
@page{margin:14mm}
@media print{
  :root{--paper:#fff}
  body{font-size:10.5pt}
  .doorbar,.btn{display:none}
  .hero,.cta{background:#fff!important; color:#000!important}
  .hero h1,.cta h2{color:#000!important}
  .hero .lede,.cta p{color:#333!important}
  .hero .lede strong{color:#000!important}
  section{padding-block:1.2rem; break-inside:avoid}
  figure,.decision,.tally{break-inside:avoid}
  a[href^="http"]::after{content:" (" attr(href) ")"; font-size:9pt; color:#666}
}

/* ── The Path (Door 3) — the narrated timeline ─────────────────────────────
   Chapters are numbered and ruled rather than dotted-and-iconed: this door's
   risk is reading as a scrapbook, and ornament is what tips it over. The
   "lands on" line is the load-bearing element — it's what stops a chronology
   being a gallery — so it gets the accent and nothing else does. */
.chapters{counter-reset:ch}
.chapter{
  counter-increment:ch;
  border-top:1px solid var(--rule);
  padding-block:clamp(2rem,4vw,3.2rem);
  display:grid; gap:1.25rem;
}
@media(min-width:56rem){
  .chapter{grid-template-columns:7rem minmax(0,1fr); gap:2.5rem; align-items:start}
}
.chapter .num{
  font-family:var(--serif); font-size:2.6rem; line-height:1;
  color:var(--rule); font-variant-numeric:tabular-nums;
}
.chapter .num::before{content:counter(ch,decimal-leading-zero)}
.chapter .era{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink-3); margin:.5rem 0 0; display:block;
}
.chapter h3{
  font-family:var(--serif); font-weight:400; font-size:clamp(1.35rem,1.1rem + 1vw,1.9rem);
  line-height:1.2; letter-spacing:-.01em; margin:0 0 .9rem;
}
.chapter .body{max-width:var(--measure)}
.lands{
  margin-top:1.1rem; padding-left:1rem; border-left:2px solid var(--accent);
  font-family:var(--serif); font-size:1.02rem; line-height:1.5; color:var(--ink-2);
}
.lands b{color:var(--ink)}

/* slot for craft assets that don't exist yet — visible, honest, not a fake image */
.pending{
  margin-top:1.25rem; padding:.85rem 1rem; border:1px dashed var(--rule);
  border-radius:6px; font-size:13px; color:var(--ink-3); background:var(--paper-2);
}

.closer{background:var(--dark); color:var(--dark-ink)}
.closer h2{color:var(--dark-ink); max-width:24ch}
.closer p{color:var(--dark-ink-2); max-width:46ch}
@media print{
  .chapter{break-inside:avoid}
  .closer{background:#fff!important; color:#000!important}
  .closer h2{color:#000!important} .closer p{color:#333!important}
  .pending{display:none}
}

/* ── artifact grid — for period work whose masters are small ────────────────
   These assets are 500–768px web exports from 2002; the app captures beside
   them are 1409px. Upscaling would magnify exactly what's weakest, so the
   grid sizes to the ARTIFACT rather than the column: each sits at or below
   its native width, and the frame does the work the resolution can't.
   Replace with the print masters when they surface — sizes are per-item, so
   a bigger file just fills more of its cell. */
.artifacts{display:grid; gap:1.5rem; margin:2rem 0 0}
@media(min-width:44rem){ .artifacts{grid-template-columns:repeat(2,1fr); gap:2rem} }
.artifacts figure{margin:0}
.artifacts .shot{background:var(--dark); border-color:var(--dark-2)}
.artifacts img{margin-inline:auto}          /* centre inside its cell — never stretched */
.artifacts figcaption{margin-top:.6rem}
.dateline{
  display:inline-block; font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-3); border:1px solid var(--rule);
  border-radius:3px; padding:.15rem .45rem; margin-right:.5rem;
}
@media print{ .artifacts{grid-template-columns:repeat(2,1fr)} }

/* ⛔ THE ARC FIGURE — an image beside a LIVE interface, not one flattened picture of both.
   It was a PNG and went stale invisibly: a screenshot of an old interface still looks like a
   screenshot. Regenerating it needs a renderer that runs JavaScript (the B/W bands are measured
   at runtime) and this machine has none. So the phone is iframed from a generated embed, and
   check-site.py refuses a deploy when that embed is stale.
   The iframe is pinned to the phone's own 412x866 ratio so it never reflows or guesses. */
/* ⛔ THE COLUMNS ARE NOT EQUAL, AND THAT IS THE POINT. The photo is 553×764 and the phone is
   412×866 — different aspects, so equal columns made the phone 1.52× the photo's height and
   the figure ran long. 1 : 0.657 is the ratio that renders both at the SAME height. */
.arc-figure{display:grid;grid-template-columns:1fr 0.678fr;gap:2rem;align-items:start;margin:0 0 .9rem}
.arc-figure img{width:100%;height:auto;display:block;border:1px solid var(--rule)}
.arc-figure iframe{width:100%;aspect-ratio:412/866;border:0;display:block;background:transparent}
.arc-figure .dateline{margin-bottom:.5rem}
@media (max-width:640px){ .arc-figure{grid-template-columns:1fr} }
/* ⚠️ AN IFRAME DOES NOT PRINT RELIABLY. The caption carries the claim so the section still reads
   on paper, but a printed copy shows an empty box where the phone is. Named here, not hidden. */
@media print{ .arc-figure iframe{display:none} }
