  :root{
    --navh:64px;
    --navy:#050D28; --navy-soft:#0d1c52; --paper:#ffffff; --lime:#d6ee73; --lime-soft:#f2f9d8;
    --blue:#2450e6; --ink:#050D28; --ink-inv:#ffffff;
    --display:'Forum',Georgia,serif;
    --sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
    --max:1120px;
    /* type scale: 3 steps under 16px, not 7 */
    --t-label:11px; --t-small:13.5px; --t-body:15px; --t-lede:16.5px;
    /* 4px spacing scale */
    --s1:8px; --s2:16px; --s3:24px; --s4:32px; --s5:48px; --s6:64px; --s7:88px;
  }
  *{box-sizing:border-box}
  html{scroll-behavior:smooth}
  @media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto} *{transition:none!important} }
  body{margin:0;font-family:var(--sans);font-weight:400;color:var(--ink);background:var(--paper);line-height:1.6;font-size:16px}
  img{max-width:100%;height:auto;display:block;border-radius:4px}
  a{color:inherit}
  .wrap{max-width:var(--max);margin:0 auto;padding:0 24px}
  .vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
  /* visible focus, everywhere */
  a:focus-visible,button:focus-visible{outline:2.5px solid var(--blue);outline-offset:3px;border-radius:2px}
  #contact a:focus-visible{outline-color:var(--lime)}

  section, header.hero{scroll-margin-top:var(--navh)}
  /* the nav: see "the nav" at the end */

  /* ── hero ── */
  header.hero{background:var(--navy);color:#fff;overflow:hidden}
  .hero .wrap > div{min-width:0}
  .hero .wrap{display:grid;grid-template-columns:1.25fr .75fr;gap:var(--s5);align-items:start;padding-top:var(--s5);padding-bottom:var(--s4)}
  .hero h1{font-family:var(--sans);font-style:italic;font-weight:800;font-size:clamp(38px,3.45vw,52px);line-height:1.15;margin:0 0 var(--s2);letter-spacing:-.035em}
  .hero h1 .l2{display:block;padding-left:.9em}
  .hero p.tag{font-family:var(--sans);font-size:clamp(13px,1.5vw,16px);margin:0 0 var(--s1);color:var(--lime);line-height:1.5}
  .hero p.tag i{font-style:normal;opacity:.55;padding:0 .55em}
  /* the eyebrow may wrap between segments, never inside one — no orphaned
     "FI", no split "MIXED / METHODS" */
  .hero p.tag .nb{white-space:nowrap}
  .hero p.sub{font-size:16.5px;max-width:50ch;opacity:.95;margin:0}
  .hero .pic{position:relative;padding-top:6px}
  .hero .pic img{max-width:300px;border-radius:6px;box-shadow:0 18px 50px rgba(0,0,0,.35)}
  /* the proof strip: hard facts, above the fold */
  .proof{display:grid;grid-template-columns:repeat(4,auto);justify-content:start;gap:6px var(--s3);margin:var(--s3) 0 0;padding:14px 0 0;border-top:1.5px solid rgba(214,238,115,.35);font-family:var(--sans);font-size:12.5px;line-height:1.7;letter-spacing:.01em}
  .proof span{white-space:nowrap;opacity:.9}
  .proof b{color:var(--lime);font-weight:700}
  @media(max-width:1080px){ .proof{grid-template-columns:repeat(2,auto)} }
  @media(max-width:700px){ .proof{grid-template-columns:1fr;gap:2px} .proof span{white-space:normal} }
  @media(max-width:860px){ .hero .wrap{grid-template-columns:1fr;padding-top:var(--s4)} .hero .pic{max-width:190px} .hero .pic img{max-width:100%} .hero h1{font-size:clamp(38px,11vw,56px)} }

  /* ── section scaffolding ── */
  section{padding:var(--s7) 0;position:relative}
  .eyebrow{font-family:var(--sans);font-weight:500;font-size:13px;letter-spacing:.14em;text-transform:uppercase;margin:0 0 10px}
  h2.sec{font-family:var(--sans);font-style:italic;font-weight:800;font-size:clamp(30px,4.4vw,46px);letter-spacing:-.03em;line-height:1.1;margin:0 0 var(--s3);text-wrap:balance}
  .secband{background:var(--navy);color:#fff;padding:var(--s7) 0}
  .secband .eyebrow{color:var(--lime);margin:0 0 10px}
  .secband h2.sec{color:#fff;margin:0}
  #work,#more{padding-top:0}
  .hl{background:var(--blue);color:#fff;padding:0 .18em;box-decoration-break:clone;-webkit-box-decoration-break:clone}

  /* ── pillars ── */
  /* the exact ground from Iida's portfolio deck, reassembled from the
     PDF's background slabs (grain and glows, no content) */
  #skills{background:#ecf6c5 url(images/skills-bg.jpg) center/cover no-repeat}
  .pillars{display:grid;grid-template-columns:repeat(3,1fr);gap:26px;container-type:inline-size}
  .pillar{background:rgba(255,255,255,.9);border-radius:calc((100cqw - 52px)/6) calc((100cqw - 52px)/6) 6px 6px;padding:var(--s5) 26px var(--s3);display:flex;flex-direction:column}
  .pillar h3{font-family:var(--sans);font-style:italic;font-weight:800;font-size:21px;line-height:1.2;margin:0 0 var(--s2);min-height:2.4em;display:flex;align-items:center}
  .pillar .ill{height:130px;display:flex;align-items:center;justify-content:center;margin:-8px 0 20px}
  .pillar .ill img{max-height:130px;width:auto;border-radius:0}
  .pillar p{font-size:15px;margin:0 0 14px;flex:1;max-width:62ch}
  .pillar a.jump{color:var(--blue);text-decoration-thickness:1px;text-underline-offset:2px}
  .pillar .chips{margin:10px 0 0}
  .pillar .chips span,.pillar .chips button{white-space:nowrap}
  .pillar .chips span,.pillar .chips button{font-size:10.5px;border-color:rgba(5,13,40,.35)}
  @media(max-width:980px){ .pillars{grid-template-columns:1fr;gap:20px;max-width:640px;margin:0 auto} .pillar{border-radius:180px 180px 6px 6px;padding-top:var(--s4)} .pillar .ill{height:104px} .pillar .ill img{max-height:104px} }

  /* ── case studies ── */
  .case{padding:var(--s6) 0;border-top:1.5px solid #e3e6f0}
  .case:first-of-type{border-top:none}
  .case .meta{font-family:var(--sans);font-weight:500;font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--blue);margin:0 0 var(--s1)}
  .case h3{font-family:var(--sans);font-style:italic;font-weight:800;font-size:clamp(26px,3.6vw,38px);letter-spacing:-.026em;line-height:1.12;margin:0 0 var(--s2);text-wrap:balance}
  .case .story{font-size:15px;line-height:1.7;max-width:70ch;margin:0 0 var(--s3);opacity:.92}
  .case .story + .story{margin-top:calc(var(--s3) * -1 + 14px)}
  .chips{display:flex;flex-wrap:wrap;gap:8px;margin:var(--s2) 0 var(--s3)}
  .chips span,.chips button{font-family:var(--sans);font-size:var(--t-label);font-weight:500;letter-spacing:.08em;text-transform:uppercase;border:1px solid var(--navy);border-radius:999px;padding:3px 12px;color:var(--navy)}
  .chips span.ai,.chips button.ai{background:var(--lime);border-color:var(--lime)}

  /* TL;DR strip: THE scanning layer, larger than the story it summarises */
  .tldr{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s3) 20px;background:var(--lime-soft);border-radius:6px;padding:var(--s3) var(--s3);margin:0 0 var(--s3);font-size:var(--t-lede);line-height:1.5}
  .tldr b.lab{display:block;font-weight:500;font-family:var(--sans);font-size:var(--t-label);letter-spacing:.12em;text-transform:uppercase;color:var(--blue);margin:0 0 var(--s1)}
  .tldr .n{font-weight:700;font-style:normal;font-variant-numeric:tabular-nums}
  @media(max-width:900px){ .tldr{grid-template-columns:1fr 1fr;font-size:var(--t-body)} }
  @media(max-width:560px){ .tldr{grid-template-columns:1fr;font-size:14.5px;gap:var(--s2);padding:var(--s2) 18px} }

  /* figure rows below the text */
  .figrow{display:grid;gap:16px;align-items:start}
  .figrow + .figrow{margin-top:16px}
  .figrow.c1{grid-template-columns:minmax(0,660px)}
  .figrow.full{grid-template-columns:minmax(0,1fr)}
  .figrow.c2{grid-template-columns:1fr 1fr}
  .figrow.c3{grid-template-columns:1fr 1fr 1fr}
  .figrow.c4{grid-template-columns:repeat(4,1fr)}
  .figrow.split{grid-template-columns:minmax(0,1fr) minmax(0,300px)}
  .figrow figcaption,.rowcap{font-family:var(--sans);font-size:11.5px;line-height:1.55;opacity:.75;margin-top:var(--s1)}
  .rowcap{margin-top:10px}
  figure{margin:0}
  /* every figure opens full size */
  figure a.zoom{display:block;position:relative;border-radius:4px}
  figure a.zoom::after{content:"⤢ full size";position:absolute;right:8px;bottom:8px;font-family:var(--sans);font-size:10px;letter-spacing:.06em;background:rgba(5,13,40,.88);color:#fff;padding:3px 8px;border-radius:3px;opacity:0;transition:opacity .15s}
  figure a.zoom:hover::after,figure a.zoom:focus-visible::after{opacity:1}
  @media(hover:none){ figure a.zoom::after{opacity:.85} }
  @media(max-width:900px){ .figrow.c3,.figrow.c4{grid-template-columns:1fr 1fr} .figrow.split{grid-template-columns:1fr} .figrow.split figure:last-child{max-width:280px} }
  @media(max-width:560px){ .figrow.c2,.figrow.c3,.figrow.c4{grid-template-columns:1fr} }

  /* ── evidence card: real repository record ── */
  .evidence{background:var(--navy);color:#fff;border-radius:6px;padding:22px 24px;font-family:var(--sans);font-size:13px;line-height:1.7}
  .evidence .cmd{color:var(--lime);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;margin-bottom:14px}
  .evidence .subj{font-size:14px;font-weight:600;margin-bottom:12px;word-break:break-word}
  .evidence dl{display:grid;grid-template-columns:auto 1fr;gap:2px 18px;margin:0 0 14px;font-size:12.5px}
  .evidence dt{opacity:.6}
  .evidence dd{margin:0}
  .evidence .stat{border-top:1px solid rgba(255,255,255,.2);padding-top:12px;font-size:13.5px}
  .evidence .stat b{color:var(--lime);font-weight:700}
  .evidence .merge{border-top:1px solid rgba(255,255,255,.2);margin-top:12px;padding-top:12px;font-size:12px;opacity:.85;font-style:italic}

  /* ── benchmark instrument matrix ── */
  .matrix{border:1.5px solid var(--navy);border-radius:6px;overflow:hidden;font-family:var(--sans);font-size:12px}
  .matrix table{width:100%;border-collapse:collapse}
  .matrix caption{text-align:left;font-weight:500;font-size:11px;letter-spacing:.12em;text-transform:uppercase;background:var(--navy);color:var(--lime);padding:10px 14px}
  .matrix th,.matrix td{padding:7px 10px;text-align:left;border-top:1px solid #e3e6f0}
  .matrix thead th{background:var(--lime-soft);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;border-top:none}
  .matrix tbody th{font-weight:400;white-space:nowrap}
  .matrix td{text-align:center;width:15%}
  .matrix .p{color:#050D28;opacity:.85}
  .matrix .no{color:#5a6180;font-size:11px}
  .matrix .y{color:var(--blue);font-weight:600}
  .matrix tbody th{max-width:none}
  .matrix .n{color:#5a6180}
  .matrix tfoot td{text-align:left;font-size:10.5px;line-height:1.6;opacity:.75;padding:10px 14px;background:#fafbfe}

  /* ── human–AI loop diagram ── */
  .loopfig{border:1.5px solid var(--navy);border-radius:6px;padding:20px 22px;max-width:660px;background:#fff}
  .loopfig .dt{font-family:var(--sans);font-weight:500;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--blue);margin-bottom:14px}
  .loopfig .svgwrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .loopfig svg{width:100%;min-width:540px;height:auto;display:block}
  .confnote{font-family:var(--sans);font-size:11.5px;letter-spacing:.05em;border-top:1.5px solid rgba(5,13,40,.25);padding-top:10px;margin-top:14px;opacity:.8}

  /* ── more projects: visually demoted tier ── */
  #more .case{padding:var(--s4) 0}
  #more .case h3{font-size:clamp(21px,2.4vw,26px);margin-bottom:12px}
  #more .case .meta{font-size:12px}
  #more .case .story{font-size:14px;max-width:72ch}
  #more .minigrid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
  #more .minigrid img{aspect-ratio:4/3;object-fit:cover;width:100%}
  @media(max-width:640px){ #more .minigrid{grid-template-columns:1fr 1fr} }

  /* ── contact ── */
  /* the close holds a full screen, the way the hero opens on one. The nav
     overlays the top of it, so the navy runs from under the bar to the
     footer with no white anywhere in the last screen. */
  #contact{background:var(--navy);color:#fff;text-align:center;padding:var(--s7) 0;
    min-height:calc(100svh - var(--navh));display:flex;flex-direction:column;
    align-items:center;justify-content:center}
  #contact h2{font-family:var(--sans);font-style:italic;font-weight:800;font-size:clamp(28px,4.4vw,46px);margin:0 0 var(--s2);line-height:1.12}
  #contact p.avail{font-family:var(--sans);font-size:var(--t-lede);opacity:.95;margin:0 auto var(--s3);max-width:46ch}
  .cta{display:inline-block;font-family:var(--sans);font-weight:500;background:var(--lime);color:var(--navy);text-decoration:none;padding:14px 26px;border-radius:4px;font-size:15px;transition:transform .15s}
  .cta:hover,.cta:focus-visible{transform:translateY(-2px)}
  #contact .links{margin:var(--s3) 0 0;font-family:var(--sans);font-size:var(--t-small)}
  #contact .links a{color:var(--lime);display:inline-block;padding:6px 2px}
  footer{background:var(--navy);color:rgba(255,255,255,.75);font-family:var(--sans);font-size:12px;text-align:center;padding:18px 0 26px}

  /* ══ typography & rhythm pass ══ */
/* ─────────────────────────────────────────────────────────
   1. TOKENS — one spacing scale, one type scale
   ───────────────────────────────────────────────────────── */
:root{
  /* spacing: bonded 4-8 · grouped 16-24 · separated 40-56 · chaptered 72-104 */
  --s0:4px; --s1:8px; --s2:16px; --s3:24px;
  --s4:40px;   /* was 32 */
  --s5:56px;   /* was 48 */
  --s6:72px;   /* was 64 */
  --s7:104px;  /* was 88 */

  /* type: four steps under 17px, replacing eleven */
  --t-label:11.5px;    /* ALL uppercase mono micro-labels — also the floor */
  --t-caption:12.5px;  /* figcaption, rowcap, confnote, proof strip, footer */
  --t-small:14px;      /* secondary body: contact .off, #more .story */
  --t-body:15px;       /* .story, .pillar p, .secband p.lede — the floor for read text */
  --t-lede:16.5px;     /* .tldr values, .hero p.sub, #contact p.avail */
}
@media(max-width:860px){
  /* narrow screens have no portrait slack — clamp the big steps */
  :root{ --s4:32px; --s5:40px; --s6:56px; --s7:72px; }
}

/* ─────────────────────────────────────────────────────────
   2. HERO — lockup kerning + air + the clipped proof strip
   ───────────────────────────────────────────────────────── */
.hero h1{
  letter-spacing:.005em;
  word-spacing:normal;      /* full mono advances: the deck's even, optical rhythm */
  margin:0 0 var(--s3);
}
.hero h1 .l2{ padding-left:0 }

.hero .wrap{ padding-top:var(--s6); padding-bottom:var(--s5) }
.hero p.tag{ margin:0 0 var(--s2) }
.proof{
  grid-template-columns:repeat(2,auto);     /* DELETE the @media(max-width:1080px) rule */
  margin-top:var(--s4);
  padding-top:var(--s3);
  font-size:var(--t-caption);
}
@media(max-width:860px){
  .hero .wrap{ padding-top:var(--s5); padding-bottom:var(--s4) }
  .hero h1{ margin-bottom:var(--s2) }
}
@media(max-width:700px){ .proof{ grid-template-columns:1fr } }   /* keep this rule */

/* ─────────────────────────────────────────────────────────
   3. SKILLS — the donor section
   ───────────────────────────────────────────────────────── */
#skills{ padding:var(--s6) 0 }
.pillars{ gap:var(--s4) }
.pillar{ padding:var(--s5) var(--s3) var(--s4) }
.pillar .ill{ margin:-8px 0 var(--s3) }
.pillar h3{ margin:0 0 var(--s2) }
.pillar p{ margin:0 0 var(--s3); font-size:var(--t-body); max-width:33em }
/* .pillar .chips{display:none} — held: costs the skills keywords */
@media(max-width:860px){ .pillars{ gap:var(--s3) } }

/* ─────────────────────────────────────────────────────────
   4. SECTION BANDS
   ───────────────────────────────────────────────────────── */
.secband{ padding:var(--s7) 0 }
.secband .eyebrow{ margin:0 0 var(--s2) }
.secband h2.sec{ margin:0 }

/* ─────────────────────────────────────────────────────────
   5. CASE RHYTHM — bonded stays tight, blocks separate
   ───────────────────────────────────────────────────────── */
.case{ padding:var(--s6) 0 }
.case .meta{ margin:0 0 var(--s1) }            /* bonded to the headline */
.case h3{ margin:0 0 var(--s4) }               /* was s2 — the big change */
.tldr{ margin:0 0 var(--s3) }
.chips{ margin:var(--s3) 0 var(--s4) }
.case .story{
  margin:0 0 var(--s5);
  max-width:34em;              /* was 70ch = 662px = 89 chars; now 510px = 68 chars */
  font-size:var(--t-body);
  line-height:1.7;
}
.case .story + .story{ margin-top:calc(var(--s5) * -1 + var(--s3)) }
.figrow + .figrow{ margin-top:var(--s3) }
.figrow figcaption,.rowcap{ margin-top:var(--s1); font-size:var(--t-caption) }
@media(max-width:860px){ .case .story{ margin-bottom:var(--s4) } }

/* ─────────────────────────────────────────────────────────
   6. MORE + CONTACT
   ───────────────────────────────────────────────────────── */
#more .case{ padding:var(--s4) 0 }
#more .case .story{ font-size:var(--t-small); max-width:36em }   /* was 72ch = 91 chars */
#contact h2{ margin:0 0 var(--s3) }
#contact p.avail{ margin:0 auto var(--s3); font-size:var(--t-lede) }
#contact .links{ margin:var(--s3) 0 0; font-size:var(--t-small) }

/* ─────────────────────────────────────────────────────────
   7. TYPE-SCALE CLEANUP — eleven sub-16px steps become four
   ───────────────────────────────────────────────────────── */
.eyebrow,
.case .meta,
.tldr b.lab,
.chips span,
.chips button,
.pillar .chips span,
.pillar .chips button,
.matrix caption,
.matrix thead th,
.loopfig .dt,
figure a.zoom::after{ font-size:var(--t-label) }   /* 9.5/10/10.5/11/12/13 → 11.5 */

.evidence .cmd,
.evidence dl,
.evidence .merge,
.matrix tfoot td,
.matrix .no,
.confnote,
footer{ font-size:var(--t-caption) }           /* 10.5/11.5/12/12.5 → 12.5 */

.evidence,
.matrix{ font-size:var(--t-small) }            /* 12/13 → 14 */

/* raise the SVG diagram text to the 11.5px floor */
.loopfig svg text{ font-size:11.5px }

  /* ══ hero: one full screen, no glimpse of the next ══ */
  header.hero{min-height:calc(100vh - var(--navh));min-height:min(calc(100svh - var(--navh)),900px);display:flex;align-items:center}
  .hero .wrap{width:100%;padding-top:var(--s6);padding-bottom:var(--s6)}
  .hero p.tag{margin:0 0 var(--s3)}
  .hero h1{margin:0 0 var(--s4)}
  .hero p.sub{max-width:46ch}
  .proof{margin-top:var(--s5);padding-top:var(--s3)}
  .hero .pic img{max-width:360px}
  @media(max-width:860px){
    header.hero{min-height:auto;display:block}
    .hero .wrap{padding-top:var(--s5);padding-bottom:var(--s5)}
    .hero h1{margin-bottom:var(--s3)}
    .proof{margin-top:var(--s4)}
  }

  /* ══ hero alignment: one left edge, optical centring ══ */
  .hero h1 .l2{padding-left:0}
  .hero .wrap{align-items:center}
  @media(max-width:860px){ .hero .wrap{align-items:start} }

  /* ══ proof strip: wrap rather than clip ══
     The hero column narrows from 635px well before the 700px breakpoint,
     so nowrap items were being cut off by the hero's overflow:hidden
     anywhere between ~700px and ~1180px. Let the grid shrink them instead. */
  .proof{column-gap:var(--s2)}
  .proof span{white-space:normal}
  @media(max-width:1180px){ .proof{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:10px} }
  @media(max-width:700px){ .proof{grid-template-columns:1fr;row-gap:6px} }

  /* ══ Iida's hero, from the Claude Design pass ══
     Larger portrait, larger sub, more air between the three text blocks.
     Nav and hero share the 1120px container with every section below, so
     one left edge runs down the whole page. The portrait is scaled to
     hold the proportion of the Claude Design version: it was 440px in a
     1312px full-bleed column, which is the same share of a 1072px one. */
  .hero .pic img{max-width:360px;display:block;margin-left:auto}
  .hero p.sub{font-size:18px;max-width:none}
  /* eyebrow justified across exactly the headline lockup's width */
  .hero p.tag{margin:0 0 var(--s7);display:flex;justify-content:space-between;align-items:baseline;
    width:min(100%,454px)}
  .hero h1 svg.lockup{display:block;width:100%;max-width:454px;height:auto}
  .hero p.tag i{padding:0}
  .hero h1{margin:0 0 84px}
  .hero p.sub{line-height:1.7}
  @media(max-width:1080px){
    .hero .pic img{max-width:100%}
    .hero p.sub{font-size:16.5px}
    .hero p.tag{margin:0 0 14px}
    .hero h1{margin:0 0 var(--s4)}
  }

  /* ══ split hero: the portrait takes the right half of the screen ══
     From Iida's reference: text left, photo bleeding to the top, right
     and bottom edges. The portrait leaves the text container and
     becomes the hero's second grid column; the text keeps the page's
     shared left edge by carrying the container margin as padding. */
  @media(min-width:861px){
    header.hero{display:grid;grid-template-columns:1fr 1fr;align-items:stretch}
    .hero .wrap{grid-template-columns:1fr;max-width:none;margin:0;align-self:center;
      padding-left:max(24px,calc(50vw - var(--max)/2 + 24px));padding-right:var(--s5)}
    .hero .pic{padding:0;height:100%}
    .hero .pic img{width:100%;height:100%;max-width:none;object-fit:cover;object-position:50% 20%;border-radius:0;box-shadow:none;margin:0}
  }
  /* stacked: the photo goes full-bleed under the text */
  @media(max-width:860px){
    .hero .wrap{padding-bottom:0}
    .hero .pic{max-width:none;margin:var(--s4) 0 0;padding:0}
    .hero .pic img{display:block;width:100%;max-width:none;aspect-ratio:4/5;object-fit:cover;object-position:50% 20%;border-radius:0;box-shadow:none}
  }

  /* ══ skills: the illustrations climb over the arch ══
     From Iida's deck: each drawing straddles its card's dome, half on
     the lime ground, half on the white. The section grows headroom for
     the overhang; stacked cards grow their gaps for the same reason. */
  #skills{padding-top:190px}
  .pillar .ill{height:200px;margin:-150px 0 12px}
  .pillar .ill img{max-height:200px}
  /* the hammer's ink fills its frame edge to edge, so at equal box
     height it crowds its heading; slightly smaller reads as equal */
  .pillar:nth-child(2) .ill img{max-height:171px;position:relative;top:8px}
  .pillar:nth-child(3) .ill img{max-height:178px}
  /* Iida's deck proportions: drawings large, heading sitting a beat
     lower under the dome, body small and tight, card short */
  .pillar{padding-bottom:36px;padding-left:38px;padding-right:38px}
  .pillar h3{margin-top:14px;margin-bottom:16px}
  .pillar p{font-size:13px;line-height:1.5;margin-top:5px}
  .pillar .chips{gap:6px}
  .pillar .chips span,.pillar .chips button{font-size:9.5px;padding:2.5px 9px}
  @media(max-width:980px){
    #skills{padding-top:130px}
    .pillars{gap:124px}   /* the pop-over eats ~95px; keep real air between cards */
  }

  /* ══ marker highlight ══
     A blue bar with slanted ends behind the sentence that matters, from
     Iida's reference — the 100deg gradient tilts each edge ~10° off
     vertical, and clone gives every wrapped line its own bar ends. */
  .mark{
    color:#fff; padding:.06em .3em;
    /* the bar may leave the text column; the text may not. Clone
       repeats margin+padding per line fragment, and they cancel, so
       every wrapped line's first glyph sits on the column edge and
       the bar alone bleeds into the margin. Bleed = the .3em slant
       wedge exactly, so the solid bar starts and ends on the glyphs. */
    margin:0 -.3em;
    -webkit-box-decoration-break:clone; box-decoration-break:clone;
    background-image:linear-gradient(100deg,transparent .3em,var(--blue) .3em,var(--blue) calc(100% - .3em),transparent calc(100% - .3em));
  }

  /* ══════════════════════════════════════════════════════════
     IIDA'S ILLUSTRATOR LAYOUT — case pages
     Two equal columns, ~1.5% gutter. Row 1: brief left, figure
     right. Row 2: figure left, story right in two sub-columns.
     Row 3: figure full width. The question is promoted out of
     the four-box brief and given the lime plate on its own.
     ══════════════════════════════════════════════════════════ */
  .case.ill{ --colgap:var(--s4); --plate:#f5f7fc; --plate-edge:#e6eaf4 }
  .case.ill .ill-row{
    /* minmax(0,1fr), never 1fr: a wide SVG or table has a min-content
       width, and plain 1fr lets it push its column past half. The two
       panels must always be exactly equal. */
    display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
    gap:var(--colgap); align-items:stretch; margin:0 0 var(--colgap);
  }
  .case.ill .ill-row.full{ grid-template-columns:minmax(0,1fr) }

  /* the title sits optically centred between the meta line and the lime
     plate. The two margins differ because the type does: the meta's line
     box carries ~6px of space under its ink, the title's ~8px, and the
     title's cap height starts ~9px below its own line-box top. */
  .case.ill .meta{ margin:0 0 32px }
  .case.ill h3{
    font-size:clamp(26px,2.7vw,38px);  /* your mockup: title fills ~81% of the column on 2 lines */
    letter-spacing:0;
    word-spacing:-.12em;
    max-width:21ch;
    margin:0 0 32px;
  }

  /* the question, promoted */
  .case.ill .q{
    background:var(--lime-soft);
    padding:28px;              /* the plate's inner edge is the case's text margin */
    margin:0 0 var(--colgap);
    font-size:clamp(17px,1.45vw,20px);
    font-weight:500; font-style:italic; line-height:1.6;
  }
  /* the question's label matches the other three — upright, mono, blue —
     and is only a step larger, because the plate already marks it out */
  .case.ill .q .lab{ font-style:normal; font-size:13px; margin:0 0 var(--s2) }

  /* the other three cells, small print */
  .case.ill .cols3{
    display:grid; grid-template-columns:repeat(3,1fr);
    /* the three boxes hang off the same left and right margins as the
       question text, so the plate's inner edge runs on down the case */
    padding:0 28px;
    gap:var(--s3); align-items:start; margin:0 0 var(--s5);
    font-size:12px; line-height:1.55;   /* your mockup implies ~10.4px; 12 is the readable floor */
  }

  .case.ill .lab{
    display:block; font-family:var(--sans); font-weight:500;
    font-size:var(--t-label); letter-spacing:.1em;
    text-transform:uppercase; color:var(--blue);
    margin:0 0 var(--s1);
  }
  .case.ill .lab.run{ display:inline; margin:0 .7em 0 0 }
  .case.ill .n{ font-weight:700; font-variant-numeric:tabular-nums }

  /* the story, two sub-columns, justified with hyphenation */
  .case.ill p.story{
    margin:0; max-width:none;
    font-size:13.5px; line-height:1.6;  /* your mockup implies ~12px */
    columns:2; column-gap:var(--colgap);
    text-align:justify; hyphens:auto; -webkit-hyphens:auto;
  }
  /* links never hyphenate — an auto-hyphen inside a URL reads as part
     of the address. They may still break anywhere, hyphen-free. */
  .story a{ hyphens:none; -webkit-hyphens:none; overflow-wrap:anywhere }

  /* figures sit on a plate that fills the slot, so an image of the
     wrong proportion leaves tinted space rather than a raw white void.
     The caption sinks to the foot of the plate, as in the mockup. */
  .case.ill figure.slot{
    margin:0; height:100%;
    display:flex; flex-direction:column;
    background:var(--plate); border:1px solid var(--plate-edge);
    padding:var(--s3);
  }
  /* Nothing on the plate may shrink on the main axis. Some figures wrap
     their image in a zoom link and some do not; without this, a bare
     <img> becomes a flex item and gets squashed out of aspect. */
  .case.ill figure.slot > *{ flex:0 0 auto }
  .case.ill figure.slot .zoom{ display:block }
  .case.ill figure.slot img,
  .case.ill figure.slot video{ width:100%; height:auto; display:block }
  /* the caption holds the floor of the plate, one padding step up from the
     edge. The picture is not bonded to it: it centres in the area left
     above the caption. Two auto margins on the picture and none on the
     caption split the spare height evenly, so the space above the picture
     and the space between picture and caption always match. A figure with
     no caption centres in the whole plate by the same rule. */
  .case.ill figure.slot{ justify-content:flex-end }
  .case.ill figure.slot > *:not(figcaption){ margin-top:auto; margin-bottom:auto }
  .case.ill figure.slot figcaption{
    font-family:var(--sans); font-size:11px; line-height:1.6;
    max-width:62ch; padding-top:var(--s3); opacity:.7;
  }

  /* aspect rule: a portrait figure is capped and centred on its plate,
     so it fills the slot without dictating how tall the row becomes */
  .case.ill figure.slot.tall .zoom{ display:flex; justify-content:center }
  .case.ill figure.slot.tall img{ width:auto; max-width:100%; max-height:560px; margin-left:auto; margin-right:auto }
  /* a square photo held back so its plate stops towering over a short story */
  .case.ill figure.slot.tall.sq img{ max-height:340px }

  /* Minor-case photo groups. The blanket 4/3 above turns every picture into
     a landscape crop, which halves a portrait. Each group now gets a ratio
     its own pictures can survive, and the width is held back so a secondary
     case does not outweigh the research ones. */
  #more .minigrid.portraits{ grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px;
    max-width:720px; margin:0 auto }
  #more .minigrid.portraits img{ aspect-ratio:2/3; object-fit:cover; width:100%; border-radius:3px }

  /* Minor cases: the ID rule at the top of the sheet pins their h3 to 12px,
     well under the 32px the full-size cases breathe. Restore the intended
     step, and give the chips the same separation from the body text that
     the four-box brief gets in the bigger cases. */
  #more .case.ill.minor h3{ margin:0 0 24px }
  .case.ill.minor .storycols + .chips,
  .case.ill.minor p.story + .chips{ margin-top:var(--s4) }
  /* Balanced columns leave the left one a line short of the right, which
     reads as a mistake at the foot of the block. Filling the first column
     to a fixed ten lines (224px at 22.4px per line) puts the longer column on
     the left. Tied to this copy: past nineteen lines it wants a new height. */
  .case.ill.minor .storycols{ column-fill:auto; height:230px }

  /* chart schematics: the loop-diagram frame, but the type scale inside is
     the chart's own rather than the 11.5px diagram floor */
  .chartfig{border:1.5px solid var(--navy);border-radius:6px;padding:18px 20px;background:#fff;max-width:100%}
  .chartfig .dt{font-family:var(--sans);font-weight:500;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--blue);margin-bottom:12px}
  .chartfig svg{width:100%;min-width:0;height:auto;display:block}

  /* a screenshot shown at its own size instead of stretched to the panel:
     blowing an 814px capture up across a full-width row only makes the
     text in it mushy */
  .case.ill figure.slot.native .zoom{ display:flex; justify-content:center }
  .case.ill figure.slot.native img{ width:auto; max-width:100%; height:auto;
    margin-left:auto; margin-right:auto }

  /* small print sets in a narrow measure, so let it hyphenate rather
     than leave holes at the line ends. Labels never hyphenate. */
  .case.ill .cols3{ hyphens:auto; -webkit-hyphens:auto }
  .case.ill .cols3 .lab{ hyphens:none; -webkit-hyphens:none }

  /* Nothing is allowed to widen or escape its panel. A diagram that is
     too detailed for half a column is still shown whole and scaled down;
     the full-size viewer is what the reader clicks for the detail. No
     scrollbars, no min-widths, no figure setting the grid. */
  .case.ill figure.slot svg{ width:100%; min-width:0; height:auto; display:block }
  .case.ill figure.slot > div{ max-width:100%; min-width:0 }
  .case.ill figure.slot .matrix,
  .case.ill figure.slot .svgwrap{ overflow:visible; max-width:100% }
  .case.ill figure.slot table{ width:100%; table-layout:fixed }

  /* ── More Projects: the same layout, turned down ──────────────
     Same grid, same gaps, same plates, same captions, same left
     edge — so they read as the same family. Only the headline and
     the vertical rhythm are smaller, which is where the emphasis
     actually lives. */
  .case.ill.minor h3{ font-size:clamp(21px,1.85vw,26px); max-width:26ch; margin:0 0 24px }
  .case.ill.minor .meta{ margin:0 0 20px }
  .case.ill.minor .q{ font-size:clamp(15px,1.15vw,17px); padding:var(--s3) }
  .case.ill.minor .cols3{ padding:0 var(--s3) }
  .case.ill.minor p.story{ margin-top:var(--s3) }
  .case.ill.minor .minigrid{ display:grid; gap:10px; grid-template-columns:repeat(auto-fit,minmax(0,1fr)) }
  .case.ill.minor .minigrid img{ width:100%; height:auto; display:block; border-radius:3px }

  /* A full-size case's photo group, composed to fill its plate instead of
     sitting in a thin band at the bottom of it: the landscape shot across
     the top, the two portraits under it. Width scales the whole group, so
     nothing is cropped — the #more rule above would otherwise force every
     one of them to 4:3 and cut the tops off the portraits. */
  #more .case.ill:not(.minor) .minigrid,
  #work .case.ill:not(.minor) .minigrid{
    display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px;
    max-width:352px; margin:0 auto }
  #more .case.ill:not(.minor) .minigrid > a:first-child,
  #work .case.ill:not(.minor) .minigrid > a:first-child{ grid-column:1 / -1 }
  #more .case.ill:not(.minor) .minigrid img,
  #work .case.ill:not(.minor) .minigrid img{
    aspect-ratio:auto; object-fit:fill; width:100%; height:auto; display:block; border-radius:3px }

  /* an empty panel, honestly labelled, so the story can always keep the
     right-hand column even when a case has only one picture */
  .case.ill figure.slot.placeholder{ align-items:center; justify-content:center }
  .case.ill figure.slot.placeholder .ph{
    margin:auto; text-align:center; font-family:var(--sans);
    font-size:var(--t-label); letter-spacing:.14em; text-transform:uppercase;
    color:var(--navy); opacity:.32; line-height:2;
  }
  .case.ill figure.slot.placeholder .ph span{ letter-spacing:.06em; opacity:.8 }

  /* One column set per story, not one per paragraph: the text runs to the
     foot of the left column and continues at the head of the right. New
     paragraphs are marked by an indent, because a blank line inside a
     column looks like the end of the passage. */
  .case.ill .storycols{ columns:2; column-gap:var(--colgap) }
  .case.ill .storycols p.story{ columns:auto; margin:0 }
  .case.ill .storycols p.story + p.story{ text-indent:1.6em }

  /* an ID-specificity rule from the old More Projects styling was still
     capping the story at 36em, so its panel came out 12px short */
  #more .case.ill p.story,
  .case.ill p.story{ max-width:none }

  /* a full-size case placed in Beyond research keeps the case headline;
     only .minor turns it down. The old #more rule carries an id, so it
     has to be answered with one. */
  #more .case.ill:not(.minor) h3{ font-size:clamp(28px,2.7vw,38px); margin:0 0 32px }
  #more .case.ill:not(.minor) .meta{ font-size:var(--t-label) }

  .case.ill .chips{ margin:0 }

  /* ══ narrow screens: the two-panel rows stack ══
     Below the .figrow.split breakpoint the halves are too narrow for
     titles, story sub-columns and diagrams, so every row takes the
     single-column geometry of .ill-row.full instead. */
  @media(max-width:900px){
    .case.ill .ill-row{ grid-template-columns:minmax(0,1fr) }
    /* the minor story's fixed 230px column height was tuned to the
       desktop half-width; at full width the columns re-balance */
    .case.ill.minor .storycols{ height:auto; column-fill:balance }
  }
  /* phone widths: the story sub-columns go too — one readable column,
     ragged right, no hyphenation. The three-box small print stacks.
     Diagrams keep their drawn size and pan inside their frame rather
     than shrinking their type below legibility. */
  @media(max-width:560px){
    .case.ill p.story,
    .case.ill .storycols{ columns:1; text-align:left; hyphens:none; -webkit-hyphens:none }
    .case.ill .cols3{ grid-template-columns:1fr; gap:var(--s2) }
    .case.ill figure.slot .svgwrap{ overflow-x:auto; -webkit-overflow-scrolling:touch }
    .case.ill figure.slot .svgwrap svg{ min-width:480px }
    .case.ill figure.slot .chartfig{ overflow-x:auto; -webkit-overflow-scrolling:touch }
    .case.ill figure.slot .chartfig svg{ min-width:480px }
  }

  /* ══ full-size viewer ══
     Replaces the new-tab jump on figure links. The anchor keeps its href
     so it still works with JavaScript off; the script cancels the jump. */
  .zoom{ cursor:zoom-in }
  .lightbox{
    position:fixed; inset:0; z-index:200;
    display:flex; align-items:center; justify-content:center;
    padding:72px 40px 40px;
    background:rgba(5,13,40,.94);
    opacity:0; visibility:hidden;
    /* visibility flips instantly on open so the close button can take
       focus, and only after the fade on close */
    transition:opacity .18s ease, visibility 0s linear .18s;
  }
  .lightbox.open{ opacity:1; visibility:visible; transition:opacity .18s ease, visibility 0s }
  .lightbox img{
    max-width:100%; max-height:100%; width:auto; height:auto;
    display:block; border-radius:4px; box-shadow:0 30px 80px rgba(0,0,0,.5);
  }
  .lightbox video{
    max-width:100%; max-height:100%; width:auto; height:auto;
    display:block; border-radius:4px; box-shadow:0 30px 80px rgba(0,0,0,.5); background:#f5f7fc;
  }
  .lightbox img[hidden], .lightbox video[hidden]{ display:none }
  /* a transparent diagram keeps its light plate when enlarged, as in the small view */
  .lightbox img.plate{ background:#f5f7fc; padding:clamp(16px,3vw,40px); border-radius:6px; box-sizing:border-box }
  .lb-close{
    position:absolute; top:20px; left:24px;
    width:44px; height:44px; padding:0;
    display:flex; align-items:center; justify-content:center;
    font-family:var(--sans); font-size:26px; line-height:1;
    color:#fff; background:none; border:1.5px solid rgba(255,255,255,.45);
    border-radius:50%; cursor:pointer;
    transition:background .15s ease, border-color .15s ease;
  }
  .lb-close:hover{ background:rgba(255,255,255,.14); border-color:#fff }
  .lb-close:focus-visible{
    background:rgba(255,255,255,.14); border-color:#fff;
    outline:2px solid var(--lime); outline-offset:3px;
  }
  body.lb-open{ overflow:hidden }
  /* ══ interactive pass ══
     1. the two positioning maps share one frame; a toggle swaps the vertical question
     2. case chips are filters: click a tag and the cases without it fold to their titles
     3. the Idle builder is a poster until asked, then the real thing in an iframe */
  .maptabs{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;align-items:stretch;margin:0 0 14px;border-bottom:1.5px solid rgba(5,13,40,.15)}
  .mapsw{display:grid;grid-template-columns:1fr 1fr}
  .mapsw button{font-family:var(--sans);text-transform:uppercase;text-align:center;color:var(--navy);opacity:.5;background:none;border:0;border-bottom:2px solid transparent;padding:8px 8px 12px;margin-bottom:-1.5px;cursor:pointer;transition:opacity .15s,color .15s,border-color .15s}
  .mapsw button b{display:block;font-weight:500;font-size:13px;letter-spacing:.16em;line-height:1.3}
  .mapsw button:hover{opacity:.85}
  .mapsw button.on{color:var(--blue);opacity:1;border-bottom-color:var(--blue)}
  .mapsw button:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
  .mapx{align-self:start;width:32px;height:32px;padding:0;border-radius:50%;border:1.5px solid rgba(5,13,40,.3);background:#fff;color:var(--navy);font:16px/1 var(--sans);cursor:pointer;transition:background .15s,border-color .15s}
  .mapx:hover{background:var(--lime-soft);border-color:var(--navy)}
  .mapx:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
  .mapfig .svgwrap{cursor:zoom-in}
  /* enlarged: the same figure, lifted over the page like the image lightbox */
  .mapveil{position:fixed;inset:0;z-index:205;background:rgba(5,13,40,.94)}
  .mapfig.big{position:fixed;z-index:210;top:50%;left:50%;transform:translate(-50%,-50%);width:min(1040px,calc(100vw - 48px));max-width:none!important;max-height:calc(100vh - 48px);overflow:auto;padding:28px 32px;box-shadow:0 30px 80px rgba(0,0,0,.5)}
  .mapfig.big .svgwrap{cursor:zoom-out}
  .mapfig svg text{font-size:var(--map-fs,11.5px)}
  .mapfig.big .mapsub{font-size:12.5px} .mapfig.big .mapread{font-size:12.5px} .mapfig.big .mapnote{font-size:12px;line-height:1.6}
  .mapfig.big .mapsw button b{font-size:14px}
  .mapfig.big .mapx{font-size:20px}
  /* enlarged on a wide screen: the chart grows across the left, the words stand in a column beside it */
  @media(min-width:900px){
    .mapfig.big{display:grid;grid-template-columns:minmax(0,1fr) 300px;column-gap:36px;align-content:start;width:min(1400px,calc(100vw - 48px))}
    .mapfig.big .maptabs,.mapfig.big .mapsub{grid-column:1/-1}
    .mapfig.big .svgwrap{grid-area:3/1/6/2;align-self:center}
    .mapfig.big .mapread{grid-area:3/2;min-height:0;margin:0 0 18px;padding-bottom:14px;border-bottom:1.5px solid rgba(5,13,40,.15)}
    .mapfig.big .mapread:empty{border:0;padding:0;margin:0}
    .mapfig.big .mapnotes{grid-area:4/2;margin:0}
    .mapfig.big .confnote{grid-area:5/2}
  }
  @media(max-width:700px){ .mapfig.big{width:calc(100vw - 24px);max-height:calc(100vh - 24px);padding:18px 16px} }
  .mapsub{font-family:var(--sans);font-size:11px;line-height:1.5;color:#6E77A3;margin:-6px 0 12px}
  /* the frame, gridlines, x-axis and competitors persist; only what the question changes moves.
     A-only and B-only marks hand over in sequence: the leaving set fades first, the arriving set follows. */
  .mapfig .map-a,.mapfig .map-b{transition:opacity .22s ease}
  .mapfig[data-map="a"] .map-a,.mapfig[data-map="b"] .map-b{opacity:1;transition-delay:.2s;transition-duration:.3s}
  .mapfig[data-map="a"] .map-b,.mapfig[data-map="b"] .map-a{opacity:0;transition-delay:0s;pointer-events:none}
  .mapfig .lime{transition:stroke .6s ease,stroke-width .6s ease,stroke-dasharray .6s ease}
  .mapfig[data-map="a"] .lime{stroke:#2450e6;stroke-width:1.5;stroke-dasharray:5 4}
  .mapfig[data-map="b"] .lime{stroke:#e3e6f0;stroke-width:1;stroke-dasharray:1 0}
  .mapfig .comp rect{transition:opacity .6s ease;cursor:pointer;outline:none;stroke:rgba(0,0,0,0);stroke-width:10;paint-order:stroke}
  .mapfig[data-map="b"] .comp rect{opacity:.8}
  .mapfig .comp.pick rect{opacity:.3}
  .mapfig .comp.pick rect.hot,.mapfig .comp rect:focus-visible{opacity:1;fill:var(--blue)}
  .mapread{font-family:var(--sans);font-size:11px;line-height:1.5;color:var(--navy);margin:2px 0 0;min-height:2.1em}
  .mapread b{color:var(--blue);font-weight:600;letter-spacing:.02em}
  .mapread i{font-style:normal;color:#6E77A3}
  .mapnotes{display:grid;margin:12px 0 0}
  .mapnotes .mapnote{grid-area:1/1;margin:0;font-family:var(--sans);font-size:11px;line-height:1.55;color:#6E77A3;transition:opacity .22s ease}
  .mapnotes .mapnote b{color:var(--blue);font-weight:500;letter-spacing:.08em}
  .mapfig[data-map="a"] .map-b-note,.mapfig[data-map="b"] .map-a-note{opacity:0;pointer-events:none;transition-delay:0s}
  .mapfig[data-map="a"] .map-a-note,.mapfig[data-map="b"] .map-b-note{transition-delay:.2s;transition-duration:.3s}

  .chips button{background:transparent;cursor:pointer;line-height:inherit;transition:background .15s,color .15s,border-color .15s}
  .chips button:hover{background:var(--lime-soft)}
  .chips button.ai:hover{border-color:var(--navy)}
  .chips button.on,.chips button.ai.on{background:var(--navy);border-color:var(--navy);color:#fff}
  .chips button:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
  .case.dim{opacity:.5;padding:var(--s3) 0;transition:opacity .2s}
  .case.dim:hover{opacity:.8}
  .case.dim .q,.case.dim .cols3,.case.dim figure.slot,.case.dim .story,.case.dim .storycols,.case.dim .ill-row:not(:first-child){display:none}
  .case.dim .ill-row{grid-template-columns:minmax(0,1fr);margin:0}
  .case.dim .meta{margin-bottom:10px}
  .case.dim h3{margin-bottom:14px;font-size:clamp(20px,2vw,24px)}
  .case.dim .ill-brief .chips{margin:0}
  .filterbar{position:fixed;left:50%;bottom:20px;z-index:60;transform:translate(-50%,140%);display:flex;align-items:center;gap:14px;max-width:calc(100% - 32px);background:var(--navy);color:#fff;font-family:var(--sans);font-size:12px;letter-spacing:.04em;padding:8px 8px 8px 18px;border-radius:999px;box-shadow:0 10px 30px rgba(5,13,40,.35);transition:transform .25s ease}
  body.filtered .filterbar{transform:translate(-50%,0)}
  .filterbar b{color:var(--lime);font-weight:600}
  .filterbar button{font:inherit;font-weight:500;color:var(--navy);background:var(--lime);border:0;border-radius:999px;padding:7px 14px;cursor:pointer;white-space:nowrap}
  .filterbar .fl{line-height:1.4}
  .filterbar button:focus-visible{outline:2px solid #fff;outline-offset:2px}
  @media(max-width:640px){ .filterbar{left:16px;right:16px;max-width:none;transform:translateY(140%);border-radius:16px;padding:10px 10px 10px 16px} body.filtered .filterbar{transform:translateY(0)} }

  .case.ill.minor .ill-row.full .storycols{height:auto;column-fill:balance}
  .embedbox{position:relative;width:100%;min-width:0;aspect-ratio:16/10;max-height:700px;overflow:hidden;border-radius:4px;background:var(--navy)}
  .case.ill figure.slot .embedbox img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top left;opacity:.45;filter:saturate(.5);transition:opacity .3s,filter .3s}
  .embedbox:hover img{opacity:.6;filter:saturate(.8)}
  .embedveil{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;text-align:center;padding:24px}
  .embedveil button.cta{border:0;cursor:pointer}
  .embedveil .cta:hover{transform:translateY(-1px)}
  .embedout{font-family:var(--sans);font-size:12px;color:#fff;opacity:.85;text-decoration:underline;text-underline-offset:3px}
  .embedout:hover{opacity:1}
  .embedbox iframe{position:absolute;inset:0;width:100%;height:100%;border:0;background:#fff}
  @media(max-width:700px){ .embedbox{aspect-ratio:auto;height:72vh;max-height:none} }
  /* the crossword desk is centred in its poster, so the crop keeps the pile in view */
  /* the caption under a live box runs the full width of the box */
  .case.ill figure.slot.embed figcaption{max-width:none}
  #rairai .embedbox picture{display:contents}
  #rairai .embedbox img{object-position:center top}
  /* ══ TWO FONTS ══
     Forum (one weight, no italic) for every title and for the case
     question. Inter for every other word, with one label voice: medium
     weight, uppercase, tracked. Hierarchy comes from size, case and
     colour, never from weight. Lime lives only on the navy bands. */

  /* titles */
  .hero h1, h2.sec, .pillar h3, .case h3, .case.ill h3, #contact h2{
    font-family:var(--display); font-style:normal; font-weight:400;
    letter-spacing:.005em; word-spacing:normal; text-transform:none;
  }
  /* the heading is sized against its own text column (not the viewport), so
     "Hei Nordkapp," (the widest greeting used) — 5.75em wide in Forum — always holds one line: 16.8cqi
     puts it at ~97% of the column. Each line is a nowrap block; the vw
     clamp stays as the fallback for browsers without container units. */
  .hero .wrap > div{ container-type:inline-size }
  .hero h1{ font-size:clamp(56px,6.4vw,92px); font-size:clamp(42px,16.8cqi,92px); line-height:.98; margin:0 0 var(--s4) }
  .hero h1 .l1, .hero h1 .l2{ display:block; white-space:nowrap; padding-left:0 }
  @media(max-width:860px){ .hero h1{ font-size:clamp(42px,16.8cqi,64px) } }
  h2.sec{ font-size:clamp(38px,4.6vw,58px); line-height:1.02; text-wrap:balance }
  #contact h2{ font-size:clamp(38px,4.6vw,58px); line-height:1.02; margin:0 0 var(--s3) }
  .pillar h3{ font-size:25px; line-height:1.15; min-height:0; display:block; text-wrap:balance }
  .case h3, .case.ill h3{ font-size:clamp(34px,3.4vw,50px); line-height:1.04; max-width:none; margin:0 0 var(--s3) }
  #more .case.ill:not(.minor) h3{ font-size:clamp(34px,3.4vw,50px); margin:0 0 var(--s3) }
  .case.ill.minor h3, #more .case.ill.minor h3{ font-size:clamp(26px,2.3vw,32px); max-width:none; margin:0 0 var(--s3) }

  /* the one label voice */
  .eyebrow, .hero p.tag, .case .meta, .tldr b.lab, .case.ill .lab,
  .chips span, .chips button, .loopfig .dt, .chartfig .dt, .matrix caption, .evidence .cmd,
  .case.ill figure.slot.placeholder .ph, .mapsw button, .filterbar, .filterbar button{
    font-family:var(--sans); font-weight:500; text-transform:uppercase; letter-spacing:.14em;
  }
  .hero p.tag{ font-size:12px; display:block; width:auto; margin:0 0 var(--s3) }
  .hero p.tag i{ padding:0 .6em }
  .eyebrow, .case .meta{ font-size:var(--t-label) }
  .case.ill .meta{ margin:0 0 var(--s3) }
  .chips span, .chips button{ letter-spacing:.08em; padding:5px 13px; line-height:1.3 }
  .case.ill .lab, .tldr b.lab, .loopfig .dt, .chartfig .dt{ letter-spacing:.1em }
  .filterbar{ letter-spacing:.06em; text-transform:none } .filterbar button{ letter-spacing:.08em }

  /* the question: the title's second line, no plate, no label */
  .case.ill .q{
    background:none; padding:0; margin:0 0 var(--s4);
    font-family:var(--display); font-style:normal; font-weight:400;
    font-size:clamp(22px,1.8vw,26px); line-height:1.34; color:var(--blue);
    letter-spacing:.005em; max-width:none;
  }
  .case.ill.minor .q{ font-size:clamp(19px,1.45vw,22px); padding:0 }
  /* with no plate edge to hang from, the brief and chips return to the column edge */
  .case.ill .cols3, .case.ill.minor .cols3{ padding:0; font-size:13px; line-height:1.6 }
  .case.ill .cols3 .lab{ margin:0 0 var(--s1) }

  /* reading text that used to be mono: captions, records, tables */
  .case.ill figure.slot figcaption, .figrow figcaption, .rowcap{ font-family:var(--sans); font-size:var(--t-caption); opacity:.72 }
  .evidence, .matrix, .confnote, footer, #contact .links, .lb-close{ font-family:var(--sans) }
  .confnote{ font-size:11.5px; letter-spacing:.06em; opacity:.6; font-weight:400 }
  .evidence .merge{ font-style:normal; opacity:.75 }
  .cta{ font-size:15px; letter-spacing:.01em }


  /* ══ pillars: one shared row grid ══
     Each card subgrids the .pillars rows (drawing, title, body, chips),
     so a two-line title in one card pushes the body down in all three:
     the paragraphs start on one line and the chips end on one line,
     whatever the titles do. The titles step up; the body keeps the deck's 13px. */
  .pillar h3{ font-size:clamp(26px,2.4vw,31px); line-height:1.12 }
  @media(min-width:981px){
    .pillars{ row-gap:0 }
    .pillar{ display:grid; grid-template-rows:subgrid; grid-row:span 4 }
    .pillar .chips{ align-self:end }
  }
  /* ══ the lime field ══
     The skills band sits on its own photograph; the hero and the questions on white. Nothing
     is pinned or tied to the scroll (feedback: sticky, scroll-driven motion was hard to use). */
  .ground{ background:#fff; color:var(--navy) }
  .ground #skills{ background:#e9feb2 url(images/skills-bg.jpg) center/cover no-repeat }
  header.hero{ background:none; color:var(--navy); position:relative; display:flex; align-items:center; grid-template-columns:none }
  .hero .wrap{ max-width:var(--max); width:100%; margin:0 auto; padding-left:24px; padding-right:24px }
  @media(max-width:860px){ header.hero{ min-height:min(72svh,640px); display:flex } }
  .hero .wrap{ grid-template-columns:minmax(0,1fr) }
  .hero p.tag{ color:var(--blue) } .hero p.tag i{ opacity:.45 }
  .hero h1{ color:var(--navy); font-size:clamp(44px,9cqi,112px); margin:0 }
  .hero h1 b{ font-weight:400; color:var(--blue) }
  @media(max-width:860px){ .hero h1{ font-size:clamp(44px,15.5cqi,80px) } }
  /* ══ the pinned case title ══
     While a case's own headline is off the top of the screen, its name and number sit in a
     slim bar under the nav, so a fast scroll always says which project this is. The bar takes
     over exactly as the real headline leaves and steps away between cases and in the bands. */
  .casebar{ position:fixed; left:0; right:0; top:var(--navh); z-index:40; height:34px; background:rgba(255,255,255,.92);
    -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px); box-shadow:0 1px 0 #e3e6f0;
    transform:translateY(-100%); transition:transform .25s ease; pointer-events:none }
  .casebar.show{ transform:translateY(0) }
  .casebar .wrap{ display:flex; align-items:center; gap:14px; height:100%; padding:0 24px 0 var(--casex,24px); max-width:none; margin:0;
    font-family:var(--sans); font-weight:500; font-size:var(--t-label); letter-spacing:.12em; text-transform:uppercase; color:var(--navy);
    white-space:nowrap; overflow:hidden }
  .casebar .n{ color:var(--blue); font-variant-numeric:tabular-nums; flex:0 0 auto }
  .casebar .t{ overflow:hidden; text-overflow:ellipsis; min-width:0 }
  .case{ scroll-margin-top:calc(var(--navh) + 34px) }
  @media(prefers-reduced-motion:reduce){ .casebar{ transition:none } }
  /* ══ the seam between projects ══  a little more air than the spacing scale gives, so a project
     change reads as a change while the rows inside a project keep their spacing */
  .case{ padding-top:calc(var(--s6) + 16px); padding-bottom:calc(var(--s6) + 16px) }
  #more .case{ padding-top:calc(var(--s4) + 12px); padding-bottom:calc(var(--s4) + 12px) }
  .case.dim{ padding-top:var(--s3); padding-bottom:var(--s3) }

  /* ══ the overview: one Venn, two views ══
     Replaces the three pillars. Coordinates are in a 1000 × 930 frame; every child is placed
     with --x/--y in that frame and scales with the container, so the diagram keeps its
     geometry at any width. The switch fades between the framework and the projects in it.
     Under 760px the circles give way to a plain stacked list. */
  #skills{ padding:var(--s7) 0 }
  .vhead{ display:flex; align-items:flex-end; justify-content:space-between; gap:var(--s3); margin:0 0 var(--s3) }
  .vhead h2.sec{ margin:0 }
  .vswitch{ flex:none; display:inline-grid; grid-template-columns:1fr 1fr; position:relative; border:1px solid var(--navy); border-radius:999px; padding:3px; cursor:pointer; user-select:none; background:rgba(255,255,255,.7) }
  .vswitch span{ position:relative; z-index:1; font:500 11px/1 var(--sans); letter-spacing:.14em; text-transform:uppercase; padding:10px 18px; text-align:center; transition:color .3s }
  .vswitch .knob{ position:absolute; top:3px; bottom:3px; left:3px; width:calc(50% - 3px); border-radius:999px; background:var(--navy); transition:transform .35s cubic-bezier(.6,.1,.2,1) }
  .vswitch span.on{ color:#fff }
  .vswitch:focus-visible{ outline:2px solid var(--blue); outline-offset:3px }
  #skills.projects .vswitch .knob{ transform:translateX(100%) }
  /* the count-down to the cases: a small blue chevron fades in before "Cases" and nudges toward it, three
     times over the 5 s wait, then the knob slides over */
  .vswitch .fill{ position:absolute; pointer-events:none; left:calc(50% + 9px); top:50%; width:6px; height:6px; margin-top:-3px;
    border:solid var(--blue); border-width:1.5px 1.5px 0 0; transform:rotate(45deg); opacity:0; transition:opacity .2s }
  .vswitch.counting .fill{ animation:cdarrow 4s ease-in-out forwards }
  @keyframes cdarrow{ 0%{opacity:0; transform:translateX(-4px) rotate(45deg)} 8%{opacity:1; transform:translateX(0) rotate(45deg)}
    22%{transform:translateX(5px) rotate(45deg)} 36%{transform:translateX(0) rotate(45deg)} 52%{transform:translateX(5px) rotate(45deg)}
    66%{transform:translateX(0) rotate(45deg)} 82%{transform:translateX(5px) rotate(45deg)} 100%{opacity:1; transform:translateX(2px) rotate(45deg)} }
  #skills.projects .vswitch .fill{ opacity:0; animation:none }

  /* never taller than the window: with the heading row and the section's top padding, the
     whole overview fits under the nav when the reader lands on it */
  .venn{ position:relative; width:100%; max-width:1000px; aspect-ratio:1000/930; margin:0 auto; container-type:inline-size;
         width:min(100%, calc((100vh - var(--navh) - 190px) * 1000 / 930));
         width:min(100%, calc((100svh - var(--navh) - 190px) * 1000 / 930)) }
  .venn .vc{ position:absolute; inset:0; width:100%; height:100% }
  .venn .vc circle{ fill:rgba(255,255,255,.42); stroke:var(--navy); stroke-width:1.1 }
  .venn .vc{ overflow:visible }
  .venn .vc .vglow circle{ fill:#DFFF2F; stroke:none }   /* the illustrations' glow colour */
  .venn .vc .vglow.haze{ opacity:.55 }
  .venn .vc .vglow.core{ opacity:.9 }
  .venn .vc text{ font-family:var(--sans); font-weight:500; font-size:26.5px; letter-spacing:.14em; text-transform:uppercase; fill:var(--navy); text-anchor:middle }
  /* in the diagram the names are on the circles, so the headings stay for screen readers only */
  @media(min-width:761px){ .vd h3{ position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap } }
  .vlayer{ position:absolute; inset:0; transition:opacity .45s ease }
  .vlayer > *{ position:absolute; left:calc(var(--x) * .1%); top:calc(var(--y) / 9.3 * 1%) }
  .vpj{ opacity:0; pointer-events:none }
  #skills.projects .vfw{ opacity:0; pointer-events:none }
  #skills.projects .vpj{ opacity:1; pointer-events:auto }

  /* each circle's own field: a large drawing over one short line, set like the overlap labels */
  /* each circle's own field: a drawing and one short line, placed separately (the block itself draws no box) */
  .vd{ display:contents }
  .vd > img, .vd > p{ position:absolute; left:calc(var(--x) * .1%); top:calc(var(--y) / 9.3 * 1%); transform:translate(-50%,-50%) }
  .vd > img{ transform:translate(-50%,-50%) rotate(var(--r,0deg)) }   /* --r: a drawing's own tilt */
  .vd img{ display:block; height:calc(18cqi * var(--s,1)); width:auto; margin:0 }   /* --s: a drawing's own scale */
  .vd h3{ font-family:var(--display); font-weight:400; font-size:clamp(26px,4cqi,40px); line-height:1; margin:0 0 1.1cqi }
  .vd p{ width:21cqi; text-align:center; font-family:var(--display); font-size:clamp(13px,1.75cqi,18px); line-height:1.15; margin:0 }
  .vfw .vd:nth-of-type(2) > p, .vfw .vd:nth-of-type(3) > p{ width:25cqi }   /* Align's and (Re)design's lines run longest */
  .vo{ width:16cqi; transform:translate(-50%,-50%); text-align:center; font-family:var(--display); font-size:clamp(13px,1.75cqi,18px); line-height:1.15 }
  /* a width set in the Venn builder (--w, in cqi) wins over the defaults here */
  #venn .vlayer [style*="--w"]{ width:calc(var(--w) * 1cqi); white-space:normal }
  .vo.core{ width:auto; white-space:nowrap; font-size:clamp(17px,2.4cqi,25px); line-height:1.05 }   /* where all three meet: set larger */

  .vk{ width:14.2cqi; transform:translate(-50%,-50%); background:#fff; border-radius:4px; padding:.5cqi; color:var(--navy); text-decoration:none;
       box-shadow:0 1px 0 rgba(5,13,40,.08),0 4px 14px rgba(5,13,40,.1); transition:transform .25s, box-shadow .25s }
  a.vk:hover{ transform:translate(-50%,-50%) translateY(-3px); box-shadow:0 2px 0 rgba(5,13,40,.08),0 12px 26px rgba(5,13,40,.16); z-index:2 }
  /* no flicker on hover: each card keeps its own layer for good, so the browser doesn't re-draw its
     image at the start and end of every lift (cards sit at fractional pixels, so each re-draw shifts
     the image slightly); and a strip under the lifted card keeps the pointer on it, so a pointer
     near its bottom edge doesn't drop the hover, let the card fall back, and catch it again */
  .vk{ will-change:transform; backface-visibility:hidden }
  a.vk:hover::after{ content:""; position:absolute; left:0; right:0; top:100%; height:4px }
  .vk .vi{ display:block; aspect-ratio:16/10; border-radius:2px; background:#eef0f4 center/cover no-repeat }
  .vk .vi.ph{ background:var(--lime) }
  .vk .vi.fit, .vpop .vi.fit{ background-color:#fff; background-size:contain }   /* a diagram: shown whole, not cropped */
  .vk b{ display:block; font-family:var(--display); font-weight:400; font-size:clamp(10px,1.75cqi,19px); line-height:1.08; margin:.6cqi .2cqi .9cqi; text-wrap:balance }
  .vk s{ display:block; text-decoration:none; font:400 clamp(8px,1.05cqi,11.5px)/1.3 var(--sans); letter-spacing:.06em; color:rgba(5,13,40,.6); margin:0 .2cqi .2cqi; font-variant-numeric:tabular-nums }   /* faded by colour, not opacity, so a number in it can be full blue */
  .vk em{ display:none }
  /* the case's number, as in the case list and the bar over it: the year on the left of the card's foot,
     the number on the right in blue */
  .vk s{ display:flex; justify-content:space-between; align-items:baseline }
  .vk s::after{ content:attr(data-n); color:var(--blue); font-weight:500; font-variant-numeric:tabular-nums }

  /* ══ how I can help: the buyer's questions ══
     Its own screen between the hero and the overview, on the hero's white. Five questions a client
     might bring, as large rows; a row opens to the cases that answer it, one at a time. On a
     landscape screen it takes the overview's grid: heading left, the list in the right column. */
  #questions{ padding:var(--s7) 0 }
  #questions h2.sec{ margin:0 0 var(--s4) }
  .qbody{ container-type:inline-size }
  @media(min-width:1000px) and (min-aspect-ratio:4/3){
    #questions{ min-height:calc(100vh - var(--navh)); min-height:calc(100svh - var(--navh)); box-sizing:border-box; display:flex; align-items:flex-start; padding:var(--s6) 0 var(--s5) }   /* top-aligned, so the list arrives right behind the hero */
    #questions .wrap{ width:100%; box-sizing:border-box; display:grid; grid-template-columns:minmax(220px,300px) 1fr; gap:var(--s4); align-items:start }
    /* cap tops level with the first question's cap tops: -.12em lifts the heading's caps to the list's
       top rule, the 25px brings them down past the row's padding to the question's (measured at 1440 and 1280) */
    #questions h2.sec{ font-size:clamp(40px,4.2vw,58px); line-height:1; margin:calc(25px - .12em) 0 0 }
  }
  .qlist{ list-style:none; margin:0; padding:0; border-top:1px solid rgba(5,13,40,.22) }
  .qa{ border-bottom:1px solid rgba(5,13,40,.22) }
  .qa > button{ display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center; gap:var(--s3); width:100%; margin:0; padding:clamp(14px,2.8cqi,24px) 0;
    background:none; border:0; cursor:pointer; text-align:left; color:var(--navy);
    font-family:var(--display); font-weight:400; font-size:clamp(19px,3.3cqi,28px); line-height:1.15; text-wrap:balance; transition:color .2s }
  .qa > button i{ position:relative; width:14px; height:14px; flex:none }   /* a plus that becomes a minus */
  .qa > button i::before, .qa > button i::after{ content:""; position:absolute; left:0; right:0; top:50%; height:1.5px; margin-top:-.75px; background:currentColor; transition:transform .3s ease }
  .qa > button i::after{ transform:rotate(90deg) }
  .qa.open > button i::after{ transform:rotate(0) }
  .qa > button:hover{ color:var(--blue) }
  .qa > button:focus-visible{ outline:2px solid var(--blue); outline-offset:2px; color:var(--blue) }
  .qp{ display:grid; grid-template-rows:0fr; visibility:hidden; transition:grid-template-rows .35s ease, visibility 0s .35s }
  .qa.open .qp{ grid-template-rows:1fr; visibility:visible; transition:grid-template-rows .35s ease }
  .qp > div{ min-height:0; overflow:hidden }
  /* the pitch: how she would help with this question, and why the cases below are the proof */
  /* under the heading, one line on how to use the list */
  /* the intro keeps its distance from the list, so it reads as the heading's, not as another pitch */
  .qintro{ margin:var(--s3) 0 var(--s5); padding-right:var(--s5); font:300 15px/1.6 var(--sans); opacity:.8 }
  @media(max-width:760px){ .qintro{ font:400 18px/1.5 var(--display); opacity:.9 } }   /* on a phone it reads as the heading's own sentence */
  .qpitch{ margin:0 0 var(--s3); font:300 13px/1.55 var(--sans); opacity:.8 }
  .qp ul{ list-style:none; margin:0; padding:0 0 clamp(20px,3.4cqi,32px); display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px }
  .qp ul:has(> li:nth-child(4)){ grid-template-columns:repeat(2,minmax(0,1fr)) }   /* four cards sit two by two, not three and one */
  @media(max-width:760px){ .qp ul{ grid-template-columns:minmax(0,1fr); gap:8px } }
  .qk{ display:grid; grid-template-columns:auto minmax(0,1fr); align-items:center; gap:10px; height:100%; box-sizing:border-box; padding:5px 10px 5px 5px; background:#fff; border-radius:4px; color:var(--navy); text-decoration:none;
    box-shadow:0 1px 0 rgba(5,13,40,.08),0 4px 14px rgba(5,13,40,.1); transition:transform .25s, box-shadow .25s }
  /* the lift only for a pointer that hovers: on a touch screen a finger scrolling past would leave it behind */
  @media(hover:hover){
    .qk:hover{ transform:translateY(-2px); box-shadow:0 2px 0 rgba(5,13,40,.08),0 10px 22px rgba(5,13,40,.15) }
    .qk:hover b{ color:var(--blue) }
  }
  .qk:focus-visible{ outline:2px solid var(--blue); outline-offset:3px }
  .qk i{ display:block; width:64px; height:48px; border-radius:2px; background:#eef0f4 center/cover no-repeat }
  .qk i.fit{ background-color:#fff; background-size:contain }
  .qk b{ display:block; font-family:var(--display); font-weight:400; font-size:15px; line-height:1.15; margin:0 0 3px; transition:color .2s }
  /* year at the left, the case's number in blue at the right, as on the Venn's cards */
  .qk s{ display:flex; justify-content:space-between; align-items:baseline; text-decoration:none; font:400 11px/1.3 var(--sans); letter-spacing:.06em; color:rgba(5,13,40,.6); font-variant-numeric:tabular-nums }
  .qk s::after{ content:attr(data-n); color:var(--blue); font-weight:500 }
  @media(prefers-reduced-motion:reduce){ .qp, .qa.open .qp, .qa > button i::after, .qk{ transition:none } }

  /* landscape screens: the heading and switch move to a column on the left, so the
     diagram can use the full window height instead of sharing it with the heading row */
  @media(min-width:1000px) and (min-aspect-ratio:4/3){
    #skills{ padding:var(--s5) 0 }
    #skills .wrap{ display:grid; grid-template-columns:minmax(220px,300px) 1fr; gap:var(--s4); align-items:center }
    /* the column spans the diagram's height; the heading starts level with the left crossing of the
       Understand and (Re)design circles (y 587.7 of 930), the switch under it */
    .vhead{ flex-direction:column; align-items:flex-start; align-self:stretch; justify-content:flex-start; gap:var(--s4); margin:0 }
    .vhead::before{ content:""; flex:0 0 calc(587.7 / 930 * 100%); margin-bottom:calc(-1 * var(--s4)) }
    .vhead h2.sec{ font-size:clamp(40px,4.2vw,58px); line-height:1; margin-top:-.5em }   /* the cap tops, not the line box, meet the crossing */
    .venn{ width:min(100%, calc((100vh - var(--navh) - 2 * var(--s5)) * 1000 / 930));
           width:min(100%, calc((100svh - var(--navh) - 2 * var(--s5)) * 1000 / 930)) }
  }
  @media(max-width:760px){
    .vhead{ flex-direction:column; align-items:flex-start }
    .venn{ aspect-ratio:auto; container-type:normal; width:100% }
    .venn .vc, .vo{ display:none }
    .vlayer{ position:static; transition:none }
    .vlayer > *{ position:static }
    .vpj{ display:none } #skills.projects .vfw{ display:none } #skills.projects .vpj{ display:grid }
    .vfw{ display:grid; gap:var(--s4) }
    .vd{ display:block } .vd > img, .vd > p{ position:static; transform:none; width:auto; text-align:left } .vd > img{ transform:rotate(var(--r,0deg)) } .vd img{ height:calc(132px * var(--s,1)); margin:0 0 12px }
    .vd h3{ font-size:34px } .vd p{ font-size:20px }
    .vpj{ grid-template-columns:1fr 1fr; gap:14px }
    .vk{ width:auto; transform:none; padding:6px } a.vk:hover{ transform:translateY(-2px) }
    .vk b{ font-size:15px; margin:6px 0 3px } .vk s{ font-size:9px }
    .vk em{ display:inline-block; font:600 8.5px/1 var(--sans); letter-spacing:.08em; text-transform:uppercase; font-style:normal; background:var(--navy); color:#fff; border-radius:999px; padding:3px 7px; margin-top:6px }
    /* on a phone the section is the framework only, stacked: the cases are a tap away in the menu and
       under the questions, so the switch goes, and the turn to the cases it would make never shows */
    .vswitch{ display:none }
    .vhead{ margin-bottom:var(--s6) }
    #skills.projects .vfw{ display:grid; opacity:1; pointer-events:auto } #skills.projects .vpj{ display:none }
    #venn .vlayer .vd > p[style*="--w"]{ width:auto }   /* the diagram's line widths don't apply to the stack */
  }
  .vdlist{ display:none }
  /* on a phone: the Venn small and still under the heading, then a row for each competency (its name as
     on the circles, its line, an arrow) that opens to the cases in its circle. Understand starts open. */
  @media(max-width:760px){
    #venn .vc{ display:block; position:static; width:100%; height:auto; margin:0 0 var(--s4) }
    #venn .vc circle{ stroke-width:3 }
    #venn .vc text{ font-size:40px }
    #venn .vfw{ gap:0; border-bottom:1px solid rgba(5,13,40,.16) }
    #venn .vd{ display:grid; grid-template-columns:minmax(0,1fr) 20px; column-gap:18px; align-items:center;
      padding:18px 0; border-top:1px solid rgba(5,13,40,.16); cursor:pointer; -webkit-tap-highlight-color:transparent }
    #venn .vd img{ display:none }   /* the Venn above carries the picture */
    #venn .vd h3{ font:500 14px/1.2 var(--sans); letter-spacing:.14em; text-transform:uppercase; margin:0 0 6px; align-self:end }   /* as the names on the Venn's circles */
    #venn .vd p{ grid-column:1; font-size:16px; line-height:1.35; margin:0; align-self:start }
    #venn .vd::after{ content:""; grid-column:2; grid-row:1 / span 2; width:9px; height:9px; justify-self:center;
      border-right:1.5px solid var(--navy); border-bottom:1.5px solid var(--navy); transform:rotate(45deg) translate(-2px,-2px); transition:transform .2s }
    #venn .vd[aria-expanded="true"]::after{ transform:rotate(-135deg) translate(-2px,-2px) }
    #venn .vd:focus-visible{ outline:2px solid var(--blue); outline-offset:2px }
    .vdlist:not([hidden]){ display:grid; gap:8px; list-style:none; margin:0; padding:0 0 18px }
    /* a case in the list: picture, the number in a column of its own so title and years line up, the glyph */
    .qk.qg{ grid-template-columns:auto minmax(0,1fr) auto; gap:10px; padding-right:14px }
    /* the number shares the title's line, on its baseline, and the years start under the title */
    .qk.qg > span{ display:grid; grid-template-columns:1.6em minmax(0,1fr); column-gap:10px; align-items:baseline }
    .qk.qg > span b{ grid-column:2 } .qk.qg > span s{ grid-column:2 }
    .qk.qg em{ grid-column:1; grid-row:1; font:500 12px/1 var(--sans); font-style:normal; letter-spacing:.06em; color:var(--blue); font-variant-numeric:tabular-nums }
    .qk.qg .glyph{ width:30px; height:auto }
  }

  /* ══ an opened card ══
     A click on a project card opens a larger copy of it over the page, grown from the card: the same
     image, title and client · year, plus the case's question, and a Read more that is the only way on. */
  .vpop-veil{ position:fixed; inset:0; z-index:150; background:rgba(5,13,40,.28); opacity:0; transition:opacity .25s ease }
  .vpop-veil.on{ opacity:1 }
  .vpop{ position:fixed; left:50%; top:50%; z-index:151; width:min(440px, calc(100vw - 32px)); max-height:calc(100svh - 32px); overflow:auto;
    translate:-50% -50%; background:#fff; color:var(--navy); border-radius:6px; padding:12px 12px 20px;
    box-shadow:0 30px 70px rgba(5,13,40,.3); transform-origin:0 0; transition:transform .32s cubic-bezier(.2,.8,.2,1), opacity .2s ease }
  .vpop .vi{ display:block; aspect-ratio:16/9.5; border-radius:3px; background:#eef0f4 center/cover no-repeat }
  .vpop .vi.ph{ background:var(--lime) }
  .vpop b{ display:block; font-family:var(--display); font-weight:400; font-size:28px; line-height:1.1; margin:16px 8px 6px }
  .vpop s{ display:block; text-decoration:none; font:500 11px/1.3 var(--sans); letter-spacing:.1em; text-transform:uppercase; opacity:.6; margin:0 8px }
  .vpop .vq{ font-family:var(--display); font-size:19px; line-height:1.35; margin:16px 8px 20px; color:var(--blue) }
  .vpop .more{ display:inline-flex; align-items:center; gap:10px; margin:0 8px 4px; padding:12px 18px 12px 22px; border-radius:999px;
    background:var(--navy); color:#fff; text-decoration:none; font:500 11px/1 var(--sans); letter-spacing:.14em; text-transform:uppercase; transition:background .2s }
  .vpop .more i{ font-style:normal; font-size:14px; letter-spacing:0; transition:transform .2s }
  .vpop .more:hover i, .vpop .more:focus-visible i{ transform:translateX(3px) }
  .vpop .more:hover{ background:var(--blue) }
  .vpop .more:focus-visible{ outline:2px solid var(--blue); outline-offset:3px }
  .vpop .x{ position:absolute; top:20px; right:20px; width:34px; height:34px; border-radius:50%; border:0; background:rgba(255,255,255,.92);
    color:var(--navy); font:18px/1 var(--sans); cursor:pointer; box-shadow:0 2px 8px rgba(5,13,40,.2) }
  div.vk[role=button]{ cursor:pointer }

  /* ══ the hero says what's on offer ══
     The greeting keeps the room; under it one line on what she does, and the two ways
     to reach her, right where a buyer's eye already is. The portrait comes back as a
     second column inside the shared 1120px container (not the old full-bleed split,
     which would cut through the lime field), so it lifts away with the text on scroll. */
  .hero .wrap{ grid-template-columns:minmax(0,1fr) minmax(0,380px); column-gap:var(--s7); align-items:center }
  /* the headline column is narrower now, so it takes a larger share of it to keep its size */
  /* air between the three blocks: greeting, the offer line, the actions */
  /* the headline is now the buyer's question, a sentence rather than a two-word greeting, so it sets smaller and wraps */
  .hero h1{ font-size:clamp(40px,9.5cqi,68px); line-height:1.08; text-wrap:balance; margin:0 0 var(--s5) }
  /* desktop: text on the left, the framed portrait on the right, both centred in the first screen */
  .hero p.sub.who{ font-size:19px; line-height:1.5; text-wrap:pretty }
  @media(min-width:861px){
    .hero .wrap{ grid-template-columns:minmax(0,600px) minmax(0,360px); justify-content:space-between; align-items:center }
    /* the headline sets as three fixed lines, never breaking inside "going on" */
    .hero h1{ font-size:clamp(30px,7.9cqi,52px); line-height:1.08; margin:0 0 var(--s2) }
    .hero h1 .ln{ display:block; white-space:nowrap }
    /* headline and who-she-is read as one statement, the actions as a separate step below */
    .hero p.sub{ margin:0 0 var(--s5) }
  }
  .hero p.sub{ font-size:var(--t-lede); line-height:1.6; max-width:none; opacity:1; margin:0 0 var(--s5) }
  /* the photo has a lot of wall above her, so the frame crops in on her rather than showing it
     whole: a 4:5 window over x 150–910, y 180–1130 of the 1006 × 1200 original */
  .hero .pic{ position:relative; height:auto; padding:0; margin:0; aspect-ratio:4/5; overflow:hidden;
    border-radius:4px; box-shadow:0 18px 50px rgba(5,13,40,.18) }
  .hero .pic img{ position:absolute; left:-19.7%; top:-18.9%; width:132.4%; height:auto; max-width:none;
    aspect-ratio:auto; object-fit:fill; border-radius:0; box-shadow:none; margin:0 }
  /* the action row: a primary, a quiet secondary, and a status note on the same line */
  .acts{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--s1) var(--s2) }
  .acts .cta{ padding:12px 22px; border:1.5px solid transparent; font:500 15px/1.3 var(--sans); cursor:pointer }
  .acts .cta.ghost{ background:transparent }
  .hero .acts .cta{ background:var(--navy); color:#fff }
  .hero .acts .cta.ghost{ background:transparent; color:var(--navy); border-color:var(--navy) }
  /* the availability sentence follows the offer line as its second paragraph */
  .hero p.sub:has(+ p.sub){ margin-bottom:var(--s2) }
  /* the three roles carry what she is */
  .hero p.sub strong{ font-weight:inherit; color:var(--blue) }
  #contact .acts{ justify-content:center }
  /* the contact buttons in the shape of the opening's Book a call: a pill, the text's own size, an arrow
     on the link that leaves; the call to book filled lime, the email in outline */
  #contact .acts .cta{ display:inline-flex; align-items:center; gap:.5em; padding:.7em 1.3em; border-radius:999px; border:1.5px solid var(--lime);
    font:500 16px/1.2 var(--sans); letter-spacing:.04em; transition:background .2s, color .2s, border-color .2s }
  #contact .acts a.cta::after{ content:"→"; transition:transform .2s }
  #contact .acts a.cta:hover, #contact .acts a.cta:focus-visible{ transform:none; background:#fff; border-color:#fff }
  #contact .acts a.cta:hover::after{ transform:translateX(3px) }
  #contact .acts .cta.ghost{ color:#fff; border-color:rgba(255,255,255,.7) }
  #contact .acts .cta.ghost:hover, #contact .acts .cta.ghost:focus-visible{ transform:none; background:#fff; color:var(--navy); border-color:#fff }
  #contact button:focus-visible{ outline-color:var(--lime) }
  /* the copied state: the button carries the full address for a moment, so it may wrap on a phone */
  .copy-email{ white-space:normal; text-align:center }
  .copy-fallback{ font:500 15px/1.3 var(--sans); user-select:all; -webkit-user-select:all; overflow-wrap:anywhere }
  .copy-fallback[hidden]{ display:none }
  #contact p.avail{ max-width:58ch; text-wrap:balance; line-height:1.65; margin:var(--s5) auto var(--s5) }   /* room above and below, so it reads apart from the heading and the buttons */
  @media(max-width:860px){
    /* stacked: a small portrait above the eyebrow, so the headline and the actions stay in the first screen */
    .hero .wrap{ grid-template-columns:minmax(0,1fr); row-gap:var(--s3); padding-bottom:var(--s5) }
    /* a full screen here too: the Venn below starts pulled up by the hand-over script, and
       over a shorter hero it lands on the buttons */
    header.hero{ min-height:calc(100vh - var(--navh)); min-height:calc(100svh - var(--navh)) }
    .hero .pic{ order:-1; width:128px; box-shadow:none }
    .hero h1{ font-size:clamp(44px,15.5cqi,80px) }
  }

  /* ══ a case on its own page ══
     Each case has its own address now. Its header says where it sits in the Venn (a small copy of
     the diagram with its area filled, and the area's name), its number in the card's blue, the title
     and the meta line; the case follows as it was on the long page. At the foot: the next case,
     big enough to be the obvious way on, the way back to the overview, and the contact band. */
  #work.casepage, #more.casepage{ padding-bottom:0 }   /* one case, then straight on to the next */
  #work.casepage .case, #more.casepage .case{ padding-top:var(--s6); padding-bottom:var(--s5); border-top:none }
  .glyph{ display:block; flex:none; border-radius:0; overflow:visible }
  .glyph .gc{ fill:#fff }
  .glyph .gr{ fill:var(--navy) }
  .glyph .gl{ fill:none; stroke:var(--navy); stroke-width:26 }   /* in the figure's own units, as in the mobile mockups: it scales with the glyph */
  /* under the brief, the glyph with its area's name */
  .casepage .where{ display:flex; align-items:center; gap:12px; margin:var(--s4) 0 0;
    font:500 var(--t-label)/1.2 var(--sans); letter-spacing:.14em; text-transform:uppercase; color:var(--navy) }
  .casepage .where .glyph{ width:34px; height:auto; flex:none }
  .casepage .meta .no{ font-weight:700; letter-spacing:.06em; font-variant-numeric:tabular-nums }
  /* client and years, then the title, at the top of the first brief */
  .casepage h1{ font-family:var(--display); font-weight:400; font-size:clamp(34px,3.4vw,50px); line-height:1.04; letter-spacing:.005em;
    margin:0 0 var(--s3); text-wrap:balance; max-width:24ch }
  .case.ill .ill-brief > .meta:first-child{ margin:0 0 var(--s2) }

  /* under a case, three more like it, as cards like those under the front page's questions */
  .related{ border-top:1.5px solid #e3e6f0; padding:var(--s6) 0 var(--s5) }
  .related h2{ font:400 clamp(26px,2.6vw,36px)/1.1 var(--display); letter-spacing:.005em; color:var(--navy); margin:0 0 var(--s4) }
  .related ul{ list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px }
  @media(max-width:760px){ .related ul{ grid-template-columns:minmax(0,1fr); gap:8px } }
  .related .back{ display:inline-block; margin:var(--s5) 0 0; padding:6px 0; font:500 var(--t-label)/1.2 var(--sans); letter-spacing:.14em; text-transform:uppercase;
    color:var(--navy); text-decoration:none; opacity:.75 }
  .related .back:hover, .related .back:focus-visible{ opacity:1; text-decoration:underline; text-underline-offset:4px }

  /* the contact band, short: the heading and the two ways to reach her */
  #contact.brief{ padding:var(--s6) 0; min-height:0 }   /* the front page's close holds a screen; this one only the way to reach her */
  #contact.brief h2{ font-size:clamp(26px,3vw,42px); text-wrap:balance }   /* the longer question on one line on a wide screen */

  /* ══ the front page opens on the lime ══
     One lime ground runs behind the opening and the Venn (it used to be the Venn's alone). The opening is
     the name, large, starting where the Venn's column starts, the three roles under it, and one sentence on
     what she does in the top-left corner, over the column where "Core competencies" sits below. */
  .limeground{ background:#e9feb2 url(images/lime-bg.jpg) center/cover no-repeat }
  @media (max-width:860px){ .limeground{ background-image:url(images/lime-bg-portrait.jpg) } }
  .ground .limeground #skills{ background:none }
  #questions{ background:#fff }
  header.hero.intro{ background:none; display:block; min-height:calc(100vh - var(--navh)); min-height:calc(100svh - var(--navh)) }
  /* the name and its line, centred in the opening screen */
  header.hero.intro .wrap{ display:flex; flex-direction:column; justify-content:center; align-items:center; text-align:center;
    max-width:var(--max); margin:0 auto; padding:var(--s5) 24px; box-sizing:border-box; min-height:inherit }
  header.hero.intro .who{ width:100% }
  header.hero.intro h1{ font:400 clamp(64px,9.8vw,146px)/.95 var(--display); letter-spacing:-.005em; color:var(--navy-soft); margin:0 0 var(--s3); white-space:nowrap }
  /* the roles and the call to book share a line under the name */
  header.hero.intro .line{ display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:22px }
  /* stacked on a phone, the name, the roles and the button sit at even steps: the name's line box runs
     below its letters, so its own margin is the smaller one */
  @media(max-width:760px){ header.hero.intro h1{ margin-bottom:14px } }
  header.hero.intro .roles{ font:400 clamp(14px,1.25vw,18px)/1.4 var(--sans); letter-spacing:.04em; color:var(--navy-soft); margin:0 }
  /* the call to book reads as part of the line: the text's own blue and size, a thin outline, filling on hover */
  header.hero.intro .book{ display:inline-flex; align-items:center; gap:.5em; padding:.55em 1.1em; border:1.5px solid var(--navy-soft); border-radius:999px;
    color:var(--navy-soft); text-decoration:none; font:500 clamp(14px,1.25vw,18px)/1.2 var(--sans); letter-spacing:.04em; white-space:nowrap;
    transition:background .2s, color .2s }
  header.hero.intro .book::after{ content:"→"; transition:transform .2s }
  header.hero.intro .book:hover, header.hero.intro .book:focus-visible{ background:var(--navy-soft); color:#fff }
  header.hero.intro .book:hover::after{ transform:translateX(3px) }
  header.hero.intro .roles b{ font-weight:600 }

  /* ══ the nav ══
     Contact and Cases, just the words, held in the top-right corner of the content's column on every page.
     They stay as one scrolls, with nothing behind them: white words blended by difference come out dark on
     the lime and white and light on the navy, so they read everywhere without changing as one scrolls.
     Open, the blend is dropped: the words turn navy, Cases becomes a white tab, and the menu runs on out of it. --navh is
     the strip they float in: pages keep that much clear at the top, and anchors land below it. */
  .sitenav{ position:fixed; top:0; left:0; right:0; z-index:50; height:var(--navh); pointer-events:none; mix-blend-mode:difference }
  .sitenav:has([aria-expanded="true"]){ mix-blend-mode:normal }
  body.front .limeground, body.casepg{ padding-top:var(--navh) }
  body.front section, body.front header.hero{ scroll-margin-top:0 }
  /* on a case page it is a white bar with a hairline, the name at the left going home */
  body.casepg{ --navh:48px }   /* a slimmer bar than the strip the front page's words float in */
  body.casepg .sitenav{ mix-blend-mode:normal; pointer-events:auto; background:rgba(255,255,255,.94); box-shadow:0 1px 0 #eceef4 }
  body.casepg .sitenav .links{ height:32px; font-size:11px }
  body.casepg .sitenav .name{ font-size:18px }
  body.casepg .sitenav .bar{ justify-content:space-between }
  body.casepg .sitenav .links > li > a, body.casepg .sitenav .cases > button{ color:var(--navy) }
  .sitenav .name{ font:400 21px/1 var(--display); letter-spacing:.005em; color:var(--navy); text-decoration:none; padding:10px 0; white-space:nowrap }
  .sitenav .name:hover, .sitenav .name:focus-visible{ color:var(--blue) }
  .sitenav .bar{ display:flex; justify-content:flex-end; align-items:center; height:100%; max-width:var(--max); margin:0 auto; padding:0 24px; box-sizing:border-box }
  .sitenav .links{ pointer-events:auto; position:relative; list-style:none; margin:0 -12px 0 0; padding:0; height:38px; display:flex; align-items:stretch;
    border-radius:6px; transition:background .15s;
    font:500 12px/1 var(--sans); letter-spacing:.12em; text-transform:uppercase; white-space:nowrap }
  .sitenav .links > li{ display:flex }
  .sitenav .links > li > a, .sitenav .cases > button{ display:inline-flex; align-items:center; gap:7px; padding:0 12px; border:0; background:none;
    font:inherit; letter-spacing:inherit; text-transform:inherit; color:#fff; text-decoration:none; cursor:pointer; transition:opacity .25s; -webkit-tap-highlight-color:transparent }
  .sitenav .links > li > a:hover, .sitenav .links > li > a:focus-visible, .sitenav .links .on, .sitenav .cases > button:hover,
  .sitenav .cases > button[aria-expanded="true"]{ text-decoration:none }
  /* Cases is a tab: open, it turns white and runs on into the menu, so the menu reads as coming out of it */
  .sitenav .cases > button{ position:relative; z-index:2; border:1px solid transparent; border-bottom:0; border-radius:6px 6px 0 0 }
  .sitenav .cases > button[aria-expanded="true"]{ background:#fff; border-color:#e3e6f0 }
  .sitenav .links:has([aria-expanded="true"]) > li > a, .sitenav .links:has([aria-expanded="true"]) .cases > button{ color:var(--navy) }
  .sitenav .links > li > a:focus-visible, .sitenav .cases > button:focus-visible{ outline:2px solid #fff; outline-offset:-4px; border-radius:6px }
  .sitenav.has .links > li > a, .sitenav.has .cases > button{ opacity:.55 }
  .sitenav.has .links .on, .sitenav.has .links > li > a:hover, .sitenav.has .cases > button:hover, .sitenav.has .cases > button[aria-expanded="true"]{ opacity:1 }
  .sitenav .cases svg{ display:block; transition:transform .2s }
  .sitenav .cases > button[aria-expanded="true"] svg{ transform:rotate(180deg) }

  /* the Cases menu: the overview, then every case as glyph | number | title */
  .sitenav .cases{ position:relative }
  .casemenu{ position:absolute; top:calc(100% - 1px); right:0; width:416px; padding:6px; background:#fff; border:1px solid #e3e6f0; border-radius:6px 0 6px 6px;
    box-shadow:0 16px 36px rgba(5,13,40,.13); text-transform:none; letter-spacing:normal; white-space:normal }
  .casemenu[hidden]{ display:none }
  .casemenu ul{ list-style:none; margin:0; padding:0 }
  .casemenu a{ display:grid; grid-template-columns:18px 1.7em minmax(0,1fr); column-gap:12px; align-items:start; padding:6px 10px; border-radius:4px;
    color:var(--navy); text-decoration:none }
  .casemenu a:hover{ background:#f4f5f9 }
  .casemenu a:focus-visible{ outline-offset:-2px }
  .casemenu a:hover .t, .casemenu a:focus-visible .t{ color:var(--blue) }
  .casemenu a[aria-current="page"]{ background:var(--lime-soft) }
  .casemenu .glyph{ width:18px; height:auto; margin-top:2px }
  .casemenu .glyph .gl{ stroke-width:46 }
  .casemenu .no{ font:500 12px/21px var(--sans); letter-spacing:.06em; color:var(--blue); font-variant-numeric:tabular-nums }
  .casemenu .t{ font:400 14px/21px var(--sans); letter-spacing:.01em }
  .casemenu .sep{ height:1px; margin:5px 10px; background:#e3e6f0 }

  /* narrower, the menu hangs from the bar's right edge instead, as wide as fits */
  @media(max-width:760px){
    .sitenav .cases{ position:static }
    .sitenav .bar{ padding:0 16px }
    .sitenav .links{ margin-right:0 }
    body.casepg .casemenu{ top:calc(var(--navh) / 2 + 15px) }
    .casemenu{ position:fixed; top:calc(var(--navh) / 2 + 18px); right:16px; width:min(416px, calc(100% - 32px)); max-height:calc(100svh - var(--navh)); overflow:auto; overscroll-behavior:contain }
  }
  @media(max-width:520px){
    .sitenav .links{ font-size:11px; letter-spacing:.08em }
    .casemenu{ left:16px; width:auto }
  }
  @media(max-width:420px){
    .sitenav .links > li > a, .sitenav .cases > button{ padding:0 12px }
  }
