/* Generated by work-v14/design/halftone/build/stage.py from the current homepage source parts. */
@font-face{font-family:"Archivo";src:url("/assets/writing/archivo.woff2") format("woff2");font-weight:100 900;font-stretch:62% 125%;font-display:swap}
/* ── src/css/base.css (verbatim) ── */
:root{
  /* Warm umber, not black: travertine in late light. Cream type and dots, one ochre accent kept scarce. */
  --ground:#2a2019;
  --band:#35281f;
  --stone:#f6ecdc;
  --stone-2:rgba(246,236,220,.74);
  --rule:rgba(246,236,220,.17);
  --accent:#e3a857;       /* ochre: dots, the lens ring, the orb's done state */
  --accent-deep:#87541a;  /* the accent when it is text on the cream band */
  --ink:#231a12;
  --s1:8px;--s2:16px;--s3:24px;--s4:40px;--s5:56px;--s6:96px;
  --display:"Archivo","Arial Narrow",Arial,sans-serif;
  --ease:cubic-bezier(.23,1,.32,1);
  --gutter:clamp(20px,4vw,56px);
  --col:min(calc(42vw - var(--gutter) - 24px),520px);  /* the left column; stops short of the portrait plate (right 58%) */
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{margin:0;background:var(--ground);color:var(--stone);font:400 16px/1.6 var(--display);font-stretch:100%;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
a{color:inherit}
img{max-width:100%;display:block}
:focus-visible{outline:2px solid var(--stone);outline-offset:3px}
.skip{position:absolute;left:var(--gutter);top:-80px;z-index:50;background:var(--stone);color:var(--ink);padding:10px 16px;font-weight:700;text-decoration:none}
.skip:focus{top:12px}
.wrap{padding-inline:var(--gutter);max-width:1600px;margin-inline:auto}
.label{font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;font-stretch:112%}


/* ── src/css/header.css (verbatim) ── */
/* ── Header ───────────────────────────────── */
.site-header{position:absolute;inset:0 0 auto 0;z-index:20}
.nav-row{display:flex;align-items:center;justify-content:space-between;gap:8px;height:76px}
.wordmark{font-weight:650;font-stretch:92%;font-size:17px;letter-spacing:-.005em;line-height:1;color:inherit;text-decoration:none;display:inline-flex;align-items:center;gap:10px;padding:6px 0;min-width:0}
.wordmark svg{display:block;flex:none;width:16px;height:16px;color:var(--accent);transform:translateY(-1px)}
.nav-links{display:flex;gap:2px;list-style:none;margin:0;padding:0}
.nav-links a{display:block;padding:9px 12px;text-decoration:none;font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;font-stretch:112%;border-radius:999px;transition:background-color .16s var(--ease)}
.nav-links a:hover{background:rgba(246,236,220,.1)}
.nav-links a:active{background:rgba(246,236,220,.18)}
.nav-links a[aria-current="true"]{box-shadow:inset 0 -1.5px 0 var(--accent);border-radius:0}
.menu-btn{display:none;align-items:center;gap:10px;background:none;border:1px solid var(--rule);color:var(--stone);font:600 12px/1 var(--display);letter-spacing:.12em;text-transform:uppercase;padding:11px 14px;border-radius:999px;cursor:pointer;transition:background-color .16s var(--ease),transform .12s var(--ease)}
.menu-btn:hover{background:rgba(246,236,220,.1)}
.menu-btn:active{transform:scale(.97)}
.menu-btn .bars{width:14px;height:9px;position:relative}
.menu-btn .bars::before,.menu-btn .bars::after{content:"";position:absolute;left:0;right:0;height:1.5px;background:currentColor;transition:transform .2s var(--ease)}
.menu-btn .bars::before{top:0}.menu-btn .bars::after{bottom:0}
.menu-btn[aria-expanded="true"] .bars::before{transform:translateY(3.75px) rotate(45deg)}
.menu-btn[aria-expanded="true"] .bars::after{transform:translateY(-3.75px) rotate(-45deg)}


/* ── src/css/sections.css (verbatim) ── */
/* ── Sections ─────────────────────────────── */
section{scroll-margin-top:24px}
.band{background:var(--band)}
.band-stone{background:var(--stone);color:var(--ink)}
.sec{padding-block:var(--s6)}
/* v14 sections: the label's optical centre matches its paragraph's wherever the two sit side by side
   (align-items:end bottom-aligned the label to a multi-line paragraph: ownership +23.9px, work -3.1px at 1440).
   Stacked (<=860) there is nothing to align across: the label stays flush at the top of its own column. */
.sec-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--s4);align-items:center;margin-bottom:var(--s5)}
@media (max-width:860px){.sec-head{align-items:start}}
h2{margin:0;font-weight:700;font-stretch:80%;text-transform:uppercase;font-size:clamp(26px,2.3vw,34px);line-height:1;letter-spacing:.01em}
.sec-head p{margin:0;max-width:46ch;color:var(--stone-2)}
.band-stone .sec-head p{color:rgba(35,26,18,.76)}

.areas{list-style:none;margin:0;padding:0;border-top:1px solid var(--rule);counter-reset:area;transform-origin:50% 0}
#work{overflow-x:clip}
.area{display:grid;grid-template-columns:56px minmax(0,1fr) minmax(0,1.1fr);gap:var(--s2) var(--s5);padding:var(--s4) 0;border-bottom:1px solid var(--rule)}
.area::before{counter-increment:area;content:counter(area,decimal-leading-zero);font-size:12px;font-weight:600;font-stretch:112%;letter-spacing:.08em;color:var(--accent);padding-top:5px}
.area h3{margin:0;font-weight:650;font-stretch:92%;font-size:clamp(19px,1.5vw,22px);line-height:1.2}
.area .q{margin:8px 0 0;font-size:16px;line-height:1.45;color:var(--stone-2);max-width:32ch}
.area-body p{margin:0 0 12px;max-width:52ch;color:var(--stone-2)}
.area-body .eg{margin:var(--s2) 0 0;padding-top:12px;border-top:1px solid var(--rule);color:var(--stone)}
.area-body .eg b{display:block;font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;font-stretch:112%;color:var(--stone-2);margin-bottom:4px}
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion:no-preference){
    .areas{animation:settle linear both;animation-timeline:view();animation-range:entry 0% cover 30%}
    @keyframes settle{from{transform:perspective(1400px) rotateX(10deg) scale(.96)}to{transform:perspective(1400px) rotateX(0) scale(1)}}
  }
}

.about-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.6fr);gap:var(--s5);align-items:start}
.about-text p{margin:0 0 var(--s2);font-size:clamp(17px,1.3vw,19px);line-height:1.5;max-width:44ch}
.about-text p.small{font-size:16px;color:var(--stone-2);max-width:52ch}
.contact{margin-top:var(--s6);padding-top:var(--s4);border-top:1px solid var(--rule);display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.6fr);gap:var(--s5);align-items:baseline}
.contact-links{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4);align-items:center;list-style:none;margin:0;padding:0}
.big-link{font-size:clamp(17px,1.4vw,20px);font-weight:600;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.24em;text-decoration-color:var(--rule);padding:6px 0;display:inline-block;transition:text-decoration-color .16s var(--ease)}
.big-link:hover{text-decoration-color:var(--accent)}
.big-link:active{opacity:.75}
footer{padding-block:var(--s4);border-top:1px solid var(--rule);color:var(--stone-2);font-size:13px}
footer .wrap{display:flex;justify-content:space-between;gap:var(--s3);flex-wrap:wrap}
.alias{display:block;height:0;overflow:hidden}


/* ── src/css/responsive.css (verbatim) ── */
/* ── Responsive ───────────────────────────── */
@media (max-width:1100px){
  .area{grid-template-columns:44px minmax(0,1fr)}
  .area-body{grid-column:2}
}
@media (max-width:860px){
  :root{--s6:72px}
  .menu-btn{display:inline-flex}
  .nav-links{display:none;position:absolute;top:70px;left:var(--gutter);right:var(--gutter);flex-direction:column;background:var(--band);padding:var(--s2);border:1px solid var(--rule)}
  .nav-links.is-open{display:flex}
  .nav-links a{padding:14px 12px;border-radius:0}
  .menu-btn{min-height:44px}           /* touch target: 44px, not the 36px desktop pill size */
  .wordmark{flex:1 1 auto;max-width:108px}  /* stops short of the menu button at 320 */
  /* Phone: the portrait takes the top of the screen; then the name, the introduction, the pill and chips. */
  :root{--col:calc(100vw - 2 * var(--gutter))}
  .hero{--stage-h:calc(36vh + 50px)}
  /* Hold the dots solid through the face, then clear them before the name. */
  .plate{width:100%;top:76px;bottom:auto;height:calc(var(--stage-h) - 76px);-webkit-mask-image:linear-gradient(180deg,#000 0,#000 70%,transparent 82%);mask-image:linear-gradient(180deg,#000 0,#000 70%,transparent 82%)}
  /* First screen on phones: the name starts inside the portrait's fade (the plate is clear by 82%), and the vertical rhythm is tight so the pill and all chips clear the fold at 320x640. */
  .hero-copy{min-height:0;justify-content:flex-start;padding-top:calc(var(--stage-h) - 56px);padding-bottom:var(--s4)}
  .h1-line{margin-top:var(--s1)}
  .lede{margin-top:10px;line-height:1.45}
  .orb-stage{margin-top:12px}
  .chips{margin-top:8px}
  /* Touch layouts: chips are touch targets, never smaller than desktop (33px). 40px tall, same 13px type. */
  .chip{font-size:13px;min-height:36px;padding:0 14px;display:inline-flex;align-items:center}
  .hero-copy > *{max-width:none}
  .sec-head,.about-grid,.contact{grid-template-columns:minmax(0,1fr);gap:var(--s3)}
}
/* Short phones (320x640, 375x667): tighter rhythm and a slightly smaller sub-line so the pill and every chip clear the fold. The name keeps its size. */
@media (max-width:860px) and (max-height:700px){
  .hero-copy{padding-top:calc(var(--stage-h) - 64px)}
  .h1-line{font-size:16px;line-height:1.3;margin-top:6px}
  .lede{font-size:14px;line-height:1.4;margin-top:8px}
  .orb-stage{margin-top:8px}
  .chips{margin-top:6px;gap:6px}
  .chip{min-height:34px}
}
@media (max-width:340px) and (max-height:700px){
  .hero-copy{padding-top:calc(var(--stage-h) - 72px)}
  .h1-line{font-size:15px}
  .chip{min-height:32px}
}
@media (max-width:620px){
  .wordmark{font-size:16px;min-width:0}
  .wordmark svg{width:14px;height:14px}
  .menu-btn{padding-inline:10px}
  .area{grid-template-columns:minmax(0,1fr);gap:8px}
  .area-body{grid-column:1}
  .area::before{padding-top:0}
  .h1-name{font-size:clamp(38px,11vw,52px)}
  .chips{margin-top:12px}
  .asked{margin-top:0}
}
.faq{margin:0;padding:0;border-top:1px solid var(--rule)}
.js-motion .faq[data-reveal]:not(.in) > *{opacity:1;transform:none}
.faq-item{border-bottom:1px solid var(--rule)}
.faq-item summary{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);padding:18px 0;cursor:pointer;font-weight:650;font-stretch:92%;font-size:clamp(17px,1.3vw,19px);line-height:1.35;list-style:none}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{content:"+";flex:none;font-weight:500;font-stretch:100%;color:var(--accent);font-size:18px;line-height:1}
.faq-item[open] summary::after{content:"–"}
.faq-item summary:hover{color:var(--stone)}
.faq-item p{margin:0;padding:0 0 18px;max-width:62ch;color:var(--stone-2)}
.faq-note{margin:var(--s3) 0 0;color:var(--stone-2)}
.faq-note a{color:inherit}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .hero-copy > h1,.hero-copy > .lede{transition:none}
  .areas{animation:none}
}

/* ── src/css/colorway-tokens.css (verbatim) ── */

/* ── Colourway: Porcelain & Cobalt. Generated by colorways/build-colorways.mjs from ../index.html. Tokens first, then every
      selector in the base page that hard-codes a colour. Nothing about layout, type or motion changes. ── */
:root{
  --ground:#f4f6f9;--band:#e8edf3;--stone:#0f1d33;
  --stone-2:rgba(15,29,51,.76);--rule:rgba(15,29,51,.15);
  --accent:#1f4fd6;--accent-deep:#a3bdff;--ink:#f4f6f9;
  --ink-2:rgba(244,246,249,.8);--ink-rule:rgba(244,246,249,.26);
  --hover:rgba(15,29,51,.06);--press:rgba(15,29,51,.11);
  --focus:#1f4fd6;
}
.nav-links a:hover,.menu-btn:hover{background:var(--hover)}
.nav-links a:active{background:var(--press)}
/* Language: same type as the nav links, cobalt on the current language. Sits outside the menu so it stays visible on phones. */
.lang-switch{display:flex;align-items:center;gap:0;flex:none;margin-left:8px}
.lang-switch a{display:inline-flex;align-items:center;justify-content:center;min-width:32px;min-height:32px;padding:9px 8px;text-decoration:none;font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;font-stretch:112%;border-radius:999px;transition:background-color .16s var(--ease)}
.lang-switch a:hover{background:var(--hover)}
.lang-switch a:active{background:var(--press)}
.lang-switch a[aria-current="true"]{color:var(--accent);box-shadow:inset 0 -1.5px 0 var(--accent);border-radius:0}
@media (max-width:860px){
  .lang-switch a{min-width:44px;min-height:44px;padding:0 8px}
}

/* ── src/css/colorway-sections.css (verbatim) ── */
/* fix5: content-to-content rhythm: 112px desktop / 80px phone, plus hairlines. */
.sec{padding-block:var(--s5)}
#work .area:last-child{padding-bottom:0}
#about .about-text > :last-child{margin-bottom:0}
#contact .contact{padding-top:0}
@media(max-width:860px){.sec{padding-block:var(--s4)}}
/* fix4: text-only bands and secondary proof captions; existing spacing/colour tokens. */
#contact .contact{margin-top:0}
#ownership .sec-head{margin-bottom:0}
.area-body .eg{font-size:14px;line-height:1.5;color:var(--stone-2)}
#autonomy .wrap{display:grid;grid-template-columns:1fr 1fr;gap:var(--s4);align-items:start}
#autonomy .sec-head,#autonomy .how-lead{margin:0}
#autonomy .how-lead{font-size:18px;line-height:1.5;font-weight:400;max-width:46ch}
@media (max-width:620px){#autonomy .wrap{grid-template-columns:1fr;gap:var(--s3)}}
::selection{background:rgba(31,79,214,.18)}
/* t_536a0c37, AI-slop pass. Decoration that said nothing about the work is removed:
   the dot before the location line, the 01–04 numbers on the unordered rules, the glass blur on the chips
   (they sit on bare ground), and the 3D tilt-in on the work list. */
.eyebrow::before{content:none}
.chip{-webkit-backdrop-filter:none;backdrop-filter:none}
.areas{animation:none}
@media (max-width:860px){
  .hero{--stage-h:calc(36vh + 50px)}
}
/* t_03063ab1: the brief's section structures and a light motion layer.
   Diagrams are ordered lists: the labels are the content, dots and hairlines are pseudo-elements.
   Motion runs only when JS has set html.js-motion (never under reduced motion); without it every element is
   simply there. Transform and opacity only. The MorphOrb and the halftone canvas are not touched. */
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.area > div:first-child h3{max-width:20ch}
.flow{margin:var(--s3) 0 0;padding-top:var(--s3);border-top:1px solid var(--rule);max-width:620px}
.flow figcaption{margin-top:var(--s3);font-size:15px;line-height:1.5;color:var(--stone);max-width:52ch}
.chain{--d:11px;list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(var(--n),minmax(0,1fr));position:relative}
.chain::before{content:"";position:absolute;top:calc(var(--d) / 2);left:calc(50% / var(--n));right:calc(50% / var(--n));height:1px;background:var(--stone-2);transform-origin:0 50%}
.chain > li{position:relative;padding-top:calc(var(--d) + 12px);text-align:center;font-size:11px;line-height:1.25;font-weight:600;letter-spacing:.1em;text-transform:uppercase;font-stretch:112%;color:var(--stone)}
.chain > li::before{content:"";position:absolute;top:0;left:50%;width:var(--d);height:var(--d);margin-left:calc(var(--d) / -2);border-radius:50%;background:var(--accent)}
.chain > li.is-person::before{background:var(--band);box-shadow:inset 0 0 0 2px var(--accent)}
.grid81{display:block;margin-top:var(--s2);color:var(--accent-deep)}
.grid81 circle{fill:currentColor}
.grid81 circle.e{fill:var(--ink-rule)}
.dial{list-style:none;margin:var(--s2) 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px 24px;font-size:14px;color:var(--ink)}
.dial li{display:flex;align-items:center;gap:8px}
.dial li::before{content:"";flex:none;width:11px;height:11px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--accent-deep)}
.dial .d-solid::before{background:var(--accent-deep)}
.dial .d-half::before{background:linear-gradient(90deg,var(--accent-deep) 50%,transparent 50%)}
.contact-body{display:flex;flex-direction:column;gap:var(--s2)}
.contact-note{margin:0;color:var(--stone-2);max-width:52ch}
/* t_676e4a3a: the three work rows and the four rules no longer share one template. */
.sec-intro{margin:0;max-width:42ch;color:var(--stone-2);font-size:clamp(16px,1.3vw,18px);line-height:1.5}
.qlist{list-style:none;margin:4px 0 14px;padding:0;counter-reset:q}
.qlist li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:8px;align-items:baseline;padding:7px 0;border-bottom:1px solid var(--rule);font-size:16px;line-height:1.35;color:var(--stone);max-width:36ch}
.qlist li::before{counter-increment:q;content:counter(q);font-size:13px;font-weight:650;font-stretch:112%;letter-spacing:.04em;color:var(--accent)}
.area--note{display:block;padding:var(--s5) 0 var(--s4);border-bottom:none}
.area--note::before{content:none}
.area--note p{margin:0;max-width:62ch;font-size:16px;line-height:1.5;color:var(--stone-2)}
.how-lead{margin:0 0 var(--s5);max-width:38ch;font-weight:650;font-stretch:92%;font-size:clamp(22px,2.1vw,28px);line-height:1.3;color:var(--ink)}
.exhibits{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--s4) var(--s5);align-items:start}
.exhibit{margin:0;min-width:0;padding-top:var(--s3);border-top:1px solid var(--ink-rule)}
.exhibit figcaption{margin:var(--s2) 0 0;max-width:42ch;font-size:15px;line-height:1.5;color:var(--ink-2)}
.exhibit .dial{margin-top:2px}
.layers{color:var(--accent)}
@media (max-width:620px){
  .exhibits{grid-template-columns:minmax(0,1fr);gap:var(--s4)}
  .how-lead,.sec-intro,.qlist li,.area--note p,.exhibit figcaption{max-width:none}
}
@media (max-width:320px){
  .qlist li{grid-template-columns:24px minmax(0,1fr);font-size:15px}
}
/* Narrow screens: the chain turns vertical, dots on the left, the hairline running down through them. */
@media (max-width:520px){
  .chain{grid-template-columns:minmax(0,1fr);row-gap:12px}
  .chain::before{top:calc(var(--d) / 2);bottom:calc(var(--d) / 2);left:calc(var(--d) / 2);right:auto;width:1px;height:auto;transform-origin:50% 0}
  .chain > li{padding:0 0 0 calc(var(--d) + 14px);text-align:left;line-height:var(--d)}
  .chain > li::before{left:0;margin-left:0}
}
@media (prefers-reduced-motion:no-preference){
  /* Staggered reveal: 8px and opacity, 480ms ease-out, 70ms between children. */
  .js-motion [data-reveal] > *{transition:opacity .48s var(--ease),transform .48s var(--ease);transition-delay:calc(var(--i,0) * 70ms)}
  .js-motion [data-reveal] > :nth-child(2){--i:1}
  .js-motion [data-reveal] > :nth-child(3){--i:2}
  .js-motion [data-reveal]:not(.in) > *{opacity:0;transform:translateY(8px)}
  /* The chain draws itself once its row is in: the hairline first, then each dot lands in order. */
  .js-motion .chain::before{transition:transform .72s var(--ease) .2s}
  .js-motion [data-reveal]:not(.in) .chain::before{transform:scaleX(0)}
  .js-motion .chain > li::before{transition:transform .34s var(--ease);transition-delay:calc(.25s + var(--k,0) * 90ms)}
  .js-motion [data-reveal]:not(.in) .chain > li::before{transform:scale(0)}
  .chain > li:nth-child(2){--k:1}.chain > li:nth-child(3){--k:2}.chain > li:nth-child(4){--k:3}.chain > li:nth-child(5){--k:4}.chain > li:nth-child(6){--k:5}
  /* The person's ring settles once, after the four solid dots: it is the step that waits. */
  .js-motion .in .chain > li.is-person::before{animation:ring-settle .6s var(--ease) .95s both}
  @keyframes ring-settle{from{box-shadow:inset 0 0 0 2px var(--accent),0 0 0 6px rgba(31,79,214,.22)}to{box-shadow:inset 0 0 0 2px var(--accent),0 0 0 0 rgba(31,79,214,0)}}
  /* The 81 filled dots come up once with their row. */
  .js-motion .grid81 circle:not(.e){transition:opacity .4s var(--ease) .3s}
  .js-motion [data-reveal]:not(.in) .grid81 circle:not(.e){opacity:.15}
  @media (max-width:520px){.js-motion [data-reveal]:not(.in) .chain::before{transform:scaleY(0)}}
}
@media print{.js-motion [data-reveal] > *,.js-motion .chain::before,.js-motion .chain > li::before{opacity:1 !important;transform:none !important}}

/* v14 sections: #work stops reading as a second copy of #ownership. Porcelain band instead of the shared
   --band, a hairline drawn as an inset shadow (a border-top would push everything below it down 1px), and the
   list header drawn in ink instead of the pale rule. Tokens only: no size, spacing or type changes. */
#work{background:var(--ground);box-shadow:inset 0 1px 0 var(--rule)}
#work .areas{border-top-color:var(--stone)}

/* ── src/partials/head-close.html #goldfish-mark (verbatim) ── */

.wordmark svg.gf{display:block;flex:none;width:40.8px;height:28.05px;color:#132758;transform:none}
@media (min-width:861px){.wordmark{margin-right:-40.8px}}
@media (max-width:860px){.wordmark{gap:8px}.wordmark svg.gf{width:27.2px;height:18.7px}}
@media (min-width:621px) and (max-width:860px){.wordmark{max-width:116px}}
@media (max-width:345px){.wordmark{gap:5px}.wordmark svg.gf{display:block;width:23px;height:15.75px}}

.gf-s1,.gf-s2,.gf-s3,.gf-s4{opacity:0}
@media(prefers-reduced-motion:no-preference){.gf-tail{animation:1300ms steps(1,end) infinite}.gf-fin{animation:gf-fin 1000ms steps(1,end) infinite;animation-delay:-170ms}.gf-pelvic{animation-delay:-310ms}.gf-side{animation-delay:-430ms}.gf-s0{animation-name:gf-s0}.gf-s1{animation-name:gf-s1}.gf-s2{animation-name:gf-s2}.gf-s3{animation-name:gf-s3}.gf-s4{animation-name:gf-s4}}
@keyframes gf-s0{0%{opacity:1}20%{opacity:0}30%{opacity:0}40%{opacity:0}50%{opacity:0}70%{opacity:0}80%{opacity:0}90%{opacity:0}100%{opacity:1}}
@keyframes gf-s1{0%{opacity:0}20%{opacity:1}30%{opacity:0}40%{opacity:0}50%{opacity:0}70%{opacity:0}80%{opacity:0}90%{opacity:1}100%{opacity:0}}
@keyframes gf-s2{0%{opacity:0}20%{opacity:0}30%{opacity:1}40%{opacity:0}50%{opacity:0}70%{opacity:0}80%{opacity:1}90%{opacity:0}100%{opacity:0}}
@keyframes gf-s3{0%{opacity:0}20%{opacity:0}30%{opacity:0}40%{opacity:1}50%{opacity:0}70%{opacity:1}80%{opacity:0}90%{opacity:0}100%{opacity:0}}
@keyframes gf-s4{0%{opacity:0}20%{opacity:0}30%{opacity:0}40%{opacity:0}50%{opacity:1}70%{opacity:0}80%{opacity:0}90%{opacity:0}100%{opacity:0}}
@keyframes gf-fin{0%,20%,100%{transform:translateX(0)}35%,50%,65%{transform:translateX(-1px)}80%{transform:translateX(0)}}

/* ── Writing (blog index + articles). Porcelain & Cobalt, appended after the homepage's own
      base/header/sections/responsive/colorway CSS so every token, the header, the goldfish and the footer
      are the same rules as the homepage. 8px rhythm only. No shadows, gradients or new colours. ── */
.wr .site-header{position:relative}
.wr .nav-links a[aria-current="page"]{box-shadow:inset 0 -1.5px 0 var(--accent);border-radius:0;color:var(--accent)}
.wr main{display:block}
.wr a{text-decoration-thickness:1px;text-underline-offset:.2em}
.wr :focus-visible{outline-color:var(--focus)}

/* Masthead */
.wr-head{padding-block:var(--s5) var(--s4);border-bottom:1px solid var(--rule)}
.crumbs{display:flex;flex-wrap:wrap;gap:8px;list-style:none;margin:0 0 var(--s3);padding:0;color:var(--stone-2)}
.crumbs li+li::before{content:"/";margin-right:8px;color:var(--rule)}
.crumbs a{color:inherit;text-decoration:none}
.crumbs a:hover{color:var(--accent);text-decoration:underline}
.wr-title{margin:0;font-weight:700;font-stretch:80%;text-transform:uppercase;font-size:clamp(32px,4.4vw,60px);line-height:.95;letter-spacing:.01em;max-width:22ch;overflow-wrap:break-word}
.wr-lede{margin:var(--s3) 0 0;max-width:58ch;font-size:clamp(17px,1.4vw,19px);line-height:1.5;color:var(--stone-2)}
.byline{display:flex;flex-wrap:wrap;gap:8px 24px;margin:var(--s3) 0 0;color:var(--stone-2);font-size:14px}
.byline b{font-weight:650;color:var(--stone)}
.tag{display:inline-flex;align-items:center;gap:8px}
.tag::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--accent);flex:none}

/* Figure: the dot diagram sits on the pale band, flat, with a hairline top like the homepage exhibits */
.wr-fig{margin:0;padding:var(--s4) 0 var(--s3);border-bottom:1px solid var(--rule)}
.wr-fig .panels{display:grid;gap:var(--s4)}
.wr-fig .panels.two{grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:end}
.wr-fig .panel{margin:0;min-width:0}
.wr-fig .panel h3{margin:0 0 var(--s2)}
.dotfig{display:block;width:100%;height:auto;max-height:300px}
.wr-fig .panel .dotfig{max-height:none}
/* halftone lane: wide figures carry a coarser-grid twin for phones, so phone dot pitch stays ~5-6px, inside the portrait's 3.8-11px range */
.wr-fig .ht-narrow{display:none}
@media (max-width:620px){.wr-fig .ht-wide{display:none}.wr-fig .ht-narrow{display:block}}  /* both panels are 27 cells wide: same width = same dot size */
.fig-key{list-style:none;margin:var(--s2) 0 0;padding:0;display:grid;grid-template-columns:repeat(var(--n,4),minmax(0,1fr));gap:8px;counter-reset:k}
.fig-key li{counter-increment:k;font-size:11px;line-height:1.3;font-weight:600;letter-spacing:.08em;text-transform:uppercase;font-stretch:112%;color:var(--stone);text-align:center}
.fig-key li::before{content:counter(k);display:block;margin-bottom:4px;color:var(--accent)}
.wr-fig figcaption{margin:var(--s3) 0 0;max-width:62ch;font-size:15px;line-height:1.5;color:var(--stone-2)}
.wr-fig .label{display:block;color:var(--stone-2);margin-bottom:var(--s1)}

/* Article layout: contents rail + a 66ch reading column */
.wr-body{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s4);padding-block:var(--s5)}
@media (min-width:1100px){.wr-body{grid-template-columns:240px minmax(0,1fr);gap:var(--s6)}}
.toc{font-size:14px}
.toc .label{display:block;color:var(--stone-2);margin-bottom:var(--s2)}
.toc ol{list-style:none;margin:0;padding:0;border-top:1px solid var(--rule)}
.toc li{border-bottom:1px solid var(--rule)}
.toc a{display:block;padding:10px 0;line-height:1.35;text-decoration:none;color:var(--stone)}
.toc a:hover{color:var(--accent)}
.toc-rail{display:none}
@media (min-width:1100px){.toc-rail{display:block;position:sticky;top:var(--s3);align-self:start}.toc-fold{display:none}}
.toc-fold{border:1px solid var(--rule);padding:0 var(--s2)}
.toc-fold summary{cursor:pointer;padding:12px 0;min-height:44px;display:flex;align-items:center;justify-content:space-between;list-style:none}
.toc-fold summary::-webkit-details-marker{display:none}
.toc-fold summary::after{content:"+";color:var(--accent);font-size:18px;line-height:1}
.toc-fold[open] summary::after{content:"–"}
.toc-fold ol{margin-bottom:var(--s2)}

.prose{max-width:66ch;font-size:18px;line-height:1.65;min-width:0}
.prose > p:first-child{font-size:clamp(19px,1.6vw,21px);line-height:1.5;color:var(--stone)}
/* Article subheads are questions, not homepage section labels: sentence case, the homepage h3 cut, larger. */
.prose h2{margin:var(--s5) 0 var(--s2);text-transform:none;font-weight:650;font-stretch:92%;font-size:clamp(22px,1.9vw,27px);line-height:1.2;letter-spacing:-.005em;scroll-margin-top:var(--s3)}
.prose p{margin:0 0 var(--s2)}
.prose ul,.prose ol{margin:0 0 var(--s3);padding:0;list-style:none;border-top:1px solid var(--rule)}
.prose li{position:relative;padding:10px 0 10px 24px;border-bottom:1px solid var(--rule)}
.prose li::before{content:"";position:absolute;left:4px;top:1.15em;width:7px;height:7px;border-radius:50%;background:var(--accent)}
.prose strong{font-weight:650}
.prose a{color:var(--accent)}
.prose a:hover{text-decoration-thickness:2px}

/* After the article: related writing and contact, same row rhythm as the homepage */
.wr-next{border-top:1px solid var(--rule);padding-block:var(--s5)}
.wr-next h2,.wr-index h2{margin:0 0 var(--s3)}
.cards{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(var(--cols,2),minmax(0,1fr));gap:var(--s4);border-top:1px solid var(--rule);padding-top:var(--s3)}
.card{display:flex;flex-direction:column;gap:12px;min-width:0}
/* Thumbnails share one frame so cards line up whatever the diagram's proportions. */
.card .thumb{display:flex;align-items:center;justify-content:center;height:200px;padding:var(--s3);background:var(--band)}
@media (max-width:620px){.card .thumb{height:160px;padding:var(--s2)}}
.wr-next .card .thumb{background:var(--ground)}
.card .thumb svg{display:block;width:100%;height:100%;max-height:none}
/* v14 merge: the card thumbnail is one halftone motif filling the card edge to edge (svg slices to the box) */
.card .thumb:has(.ht-thumb){padding:0;overflow:hidden}
.card .thumb .ht-thumb{width:100%;height:100%}
.card h2,.card h3{margin:0;text-transform:none;letter-spacing:-.005em;font-weight:650;font-stretch:92%;font-size:clamp(19px,1.5vw,22px);line-height:1.2}
.card h2 a,.card h3 a{text-decoration:none;color:inherit}
.card h2 a:hover,.card h3 a:hover{color:var(--accent);text-decoration:underline}
.card p{margin:0;color:var(--stone-2);max-width:52ch}
.card .more{margin-top:auto;font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;font-stretch:112%;color:var(--accent);text-decoration:none;padding:8px 0}
.card .more:hover{text-decoration:underline}
.wr-contact{border-top:1px solid var(--rule);padding-block:var(--s5)}
.wr-contact .contact{margin-top:0;padding-top:0;border-top:0}
.wr-note{margin:0 0 var(--s3);max-width:62ch;color:var(--stone-2)}
.wr-foot-nav{display:flex;flex-wrap:wrap;gap:8px 24px;list-style:none;margin:0;padding:0}
.wr-foot-nav a{text-decoration:none}
.wr-foot-nav a:hover{color:var(--accent);text-decoration:underline}

.wr-index{padding-block:var(--s5)}
.wr-index .cards{--cols:3}

@media (max-width:1100px){.wr-index .cards{--cols:2}}
@media (max-width:860px){
  .wr-head{padding-block:var(--s4) var(--s3)}
  .wr-fig .panels.two{grid-template-columns:minmax(0,1fr)}
  .wr-body,.wr-next,.wr-contact,.wr-index{padding-block:var(--s4)}
}
@media (max-width:620px){
  .cards,.wr-index .cards{--cols:1}
  .prose{font-size:17px}
  .fig-key{grid-template-columns:minmax(0,1fr);text-align:left}
  .fig-key li{display:grid;grid-template-columns:24px minmax(0,1fr);text-align:left;font-size:12px}
  .fig-key li::before{margin:0}
}

/* fix3: at <=345px the labelled MENU pill (87px) ran 5px into the "Jonathan" wordmark. Same rule the homepage
   uses (src/css/zz-lane-header.css, <=345px): 44px icon-only button, tighter row gap. 360px+ untouched. */
@media (max-width:345px){
  .wr .nav-row{gap:8px}
  .wr .menu-btn{justify-content:center;padding:0;width:44px;min-width:44px;gap:0;font-size:0;letter-spacing:0}
}

/* v14 sections: the diagram key sits under the part it names. The generator emits --cN (the part's centre as a
   share of the viewBox width) and --wN (2x the nearest neighbour gap) on the <ol>; every item shares one grid
   cell, offset to its part's centre and centred inside a box wide enough to wrap to two lines without reaching
   its neighbour. The values here are the same ones figures.py writes on the <ol>, so the rules still work if the
   inline attribute is dropped. Phones keep the stacked list: there is no room to position labels under a
   drawing that is 350px wide. */
.wr-fig .fig-key--parts{display:grid;grid-template-columns:minmax(0,1fr);gap:0;
  --c1:12.591%;--w1:25.182%;--c2:48.864%;--w2:54.091%;--c3:75.909%;--w3:37.682%;--c4:94.750%;--w4:10.500%}
.wr-fig .fig-key--parts > li{grid-area:1/1;justify-self:start;position:relative;text-align:center}
.wr-fig .fig-key--parts > li:nth-child(1){left:calc(var(--c1) - var(--w1) / 2);width:var(--w1)}
.wr-fig .fig-key--parts > li:nth-child(2){left:calc(var(--c2) - var(--w2) / 2);width:var(--w2)}
.wr-fig .fig-key--parts > li:nth-child(3){left:calc(var(--c3) - var(--w3) / 2);width:var(--w3)}
.wr-fig .fig-key--parts > li:nth-child(4){left:calc(var(--c4) - var(--w4) / 2);width:var(--w4)}
@media (max-width:620px){.wr-fig .fig-key--parts > li{grid-area:auto;position:static;left:auto;width:auto;
  justify-self:stretch;text-align:left;grid-template-columns:24px minmax(0,1fr)}}
