/* ---------- tokens: every size, colour and gap on the site comes from here ---------- */
:root{
  /* colour */
  --paper:#ffffff;
  --ink:#0a0a0a;
  --ink-2:#6b6b6b;            /* secondary text, 5.3:1 on paper */
  --ink-3:#a3a3a3;            /* placeholders only */
  --line:rgba(10,10,10,.09);  /* hairlines between rows */
  --pill:rgba(255,255,255,.72);
  /* liquid glass: a clear tint, strong blur and saturation, a lit top edge and a soft drop */
  --glass-bg:linear-gradient(180deg,rgba(255,255,255,.42),rgba(255,255,255,.22));
  --glass-blur:blur(18px) saturate(1.8);
  --glass-edge:inset 0 1px 0 rgba(255,255,255,.85),inset 0 -1px 0 rgba(255,255,255,.25),inset 0 0 0 1px rgba(255,255,255,.35),0 1px 2px rgba(0,0,0,.06),0 10px 30px -10px rgba(0,0,0,.22);
  --peek-shadow:0 24px 60px -24px rgba(0,0,0,.35),0 0 0 1px rgba(0,0,0,.06);
  --pill-shadow:0 1px 2px rgba(0,0,0,.06),0 8px 24px -8px rgba(0,0,0,.12),inset 0 0 0 1px rgba(0,0,0,.06);
  --quiet:.58;                /* secondary text over the surface, where blending decides the colour */

  /* type: five steps, two weights (400, 500) */
  --t-display:clamp(2.75rem,1.6rem + 4.4vw,7rem);    /* page titles */
  --t-lead:clamp(1.25rem,.9rem + 1.3vw,2.5rem);      /* the hero line, page intros */
  --t-heading:clamp(1.125rem,1rem + .4vw,1.5rem);    /* project names, About text, what people type */
  --t-body:clamp(1rem,.92rem + .12vw,1.125rem);      /* descriptions, lists */
  --t-small:clamp(.875rem,.82rem + .1vw,1rem);       /* chrome, labels, group headings, meta */

  /* space: each step roughly double the one inside it */
  --s-1:6px;                     /* inside a control: label to field, line to line */
  --s-2:12px;                    /* a heading to what it heads */
  --s-3:20px;                    /* between rows, fields, paragraphs */
  --s-4:32px;                    /* between blocks in a group */
  --s-5:clamp(56px,9vh,96px);    /* between groups */
  --s-top:clamp(104px,16vh,168px);  /* page top to title */
  --s-end:var(--s-top);            /* room after the last thing on a page */
  --gutter:clamp(16px,2.4vw,40px);  /* screen edge */

  --control:48px;
  --ease-out:cubic-bezier(.16,1,.3,1);
  color-scheme:light;
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{background:var(--paper);color:var(--ink);height:100%;overflow:hidden}
body{
  font-family:"Geist",ui-sans-serif,system-ui,sans-serif;
  font-size:var(--t-small);line-height:1.4;letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;font-variant-numeric:tabular-nums;
}
a{color:inherit;text-decoration:none}
button,input,textarea{font:inherit;color:inherit}
button{background:none;border:0;cursor:pointer}
b{font-weight:500}
::selection{background:var(--ink);color:var(--paper)}
:focus-visible{outline:1.5px solid currentColor;outline-offset:4px;border-radius:4px}
[tabindex="-1"]:focus{outline:none}
.ulink{text-decoration:underline;text-decoration-color:var(--line);text-underline-offset:3px;transition:text-decoration-color .2s}
.ulink:hover{text-decoration-color:currentColor}

/* ---------- hero: the surface, never scrolls ---------- */
.hero{position:fixed;inset:0;min-height:480px;overflow:hidden;background:var(--paper);touch-action:pan-y}
.hero canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
/* off the home view the surface is covered anyway; don't keep a full-screen layer alive under the pages */
html:not([data-view="home"]) .hero{visibility:hidden}
/* text over the surface reads through the colour: difference turns white text black on paper */
.corners{position:absolute;inset:0;pointer-events:none;color:var(--paper);mix-blend-mode:difference}
.corner{position:absolute;pointer-events:auto}
.corners .bl{bottom:calc(var(--gutter) + env(safe-area-inset-bottom));left:calc(var(--gutter) + env(safe-area-inset-left))}
.meta{display:grid}
.meta .quiet,.since{opacity:var(--quiet)}
.lead{font-size:var(--t-lead);line-height:1.08;letter-spacing:-.03em;font-weight:500;max-width:15ch;text-wrap:balance}
.since{margin-top:var(--s-2);max-width:38ch;text-wrap:balance}

/* ---------- chrome: wordmark, availability and switcher stay put on every view ---------- */
.avail{position:fixed;z-index:40;top:calc(var(--gutter) + env(safe-area-inset-top));right:calc(var(--gutter) + env(safe-area-inset-right));
  text-align:right;color:var(--paper);mix-blend-mode:difference;pointer-events:none}
.avail-link{pointer-events:auto;justify-self:end}
.mark{position:fixed;z-index:40;top:calc(var(--gutter) + env(safe-area-inset-top));left:calc(var(--gutter) + env(safe-area-inset-left));
  color:var(--paper);mix-blend-mode:difference;font-weight:500;font-size:var(--t-body);letter-spacing:-.01em}

.switch{position:fixed;z-index:40;right:calc(var(--gutter) + env(safe-area-inset-right));bottom:calc(var(--gutter) + env(safe-area-inset-bottom));
  display:flex;padding:4px;border-radius:999px;background:var(--glass-bg);box-shadow:var(--glass-edge);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur)}
.switch a{position:relative;z-index:1;display:grid;place-items:center;height:calc(var(--control) - 12px);padding:0 16px;border-radius:999px;
  color:var(--ink);transition:color .22s var(--ease-out)}
.switch a[aria-current="page"]{color:var(--paper)}
.switch a:not([aria-current="page"]):hover{color:var(--ink-2)}
.switch .thumb{position:absolute;z-index:0;top:4px;left:0;height:calc(var(--control) - 12px);border-radius:999px;background:var(--ink);
  transition:transform .32s var(--ease-out),width .32s var(--ease-out),opacity .2s var(--ease-out)}
.switch .thumb.instant{transition:none}
.switch .thumb.off{opacity:0}

html:not([data-view="home"]) .mark,html:not([data-view="home"]) .avail{mix-blend-mode:normal;color:var(--ink)}
html:not([data-view="home"]) .avail .quiet{opacity:1;color:var(--ink-2)}

.mark-roll{display:inline-grid;vertical-align:bottom;overflow:hidden;height:1.3em;line-height:1.3em}
.mark-roll > span{grid-area:1/1;display:block;white-space:nowrap}

/* tucked: while you scroll down a page, the header lifts away and the menu keeps only where you are */
.switch a{max-width:12em;overflow:hidden;white-space:nowrap;transition:color .22s var(--ease-out),max-width .32s var(--ease-out),padding .32s var(--ease-out),opacity .2s}
html.tucked .switch a:not([aria-current="page"]){max-width:0;padding-left:0;padding-right:0;opacity:0}
/* the menu button only exists while tucked: three uneven lines beside the page you're on */
.menu-btn{position:relative;z-index:1;display:grid;place-items:center;height:calc(var(--control) - 12px);max-width:0;padding:0;overflow:hidden;
  opacity:0;color:var(--ink);border-radius:999px;transition:max-width .32s var(--ease-out),padding .32s var(--ease-out),opacity .2s}
html.tucked .menu-btn{max-width:4em;padding:0 14px 0 12px;opacity:1}
.menu-btn:hover{color:var(--ink-2)}
@media (max-width:560px){.menu-btn{height:calc(var(--control) - 8px)}}
/* header frost: once a page scrolls under the header, a soft white blur sits behind it so text never runs into it */
.frost{position:fixed;z-index:39;top:0;left:0;right:0;height:calc(var(--gutter) * 2 + 2.6em + env(safe-area-inset-top));pointer-events:none;
  background:rgba(255,255,255,.94);
  -webkit-mask-image:linear-gradient(#000 70%,transparent);mask-image:linear-gradient(#000 70%,transparent);
  opacity:0;transition:opacity .25s var(--ease-out)}
html.scrolled:not([data-view="home"]) .frost{opacity:1}

/* entry: the chrome settles in after the first stroke has started */
.js .corner,.js .switch,.js .mark,.js .avail{opacity:0;transform:translateY(8px)}
.ready .corner,.ready .switch,.ready .mark,.ready .avail{opacity:1;transform:none;transition:opacity .6s var(--ease-out),transform .6s var(--ease-out)}
.ready .avail{transition-delay:.06s}.ready .bl{transition-delay:.12s}.ready .switch{transition-delay:.18s}
.ready .meta .quiet,.ready .since{opacity:var(--quiet)}

/* ---------- pages: one structure for Work, About and Contact ----------
   title, intro, then groups. A group is a small heading over rows or text.
   .split puts the main column beside a quieter side column that stays in view. */
.page{position:fixed;inset:0;z-index:20;overflow-y:auto;overscroll-behavior:contain;background:var(--paper);
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.page::-webkit-scrollbar{display:none}
.page[hidden]{display:none}
section[data-view="about"]{--s-end:clamp(220px,36vh,420px)}   /* About gets extra room to scroll the story past the photo */
.page-inner{padding:calc(var(--s-top) + env(safe-area-inset-top)) calc(var(--gutter) + env(safe-area-inset-right)) calc(var(--s-end) + env(safe-area-inset-bottom)) calc(var(--gutter) + env(safe-area-inset-left))}

.title{font-size:var(--t-display);line-height:.95;letter-spacing:-.045em;font-weight:500}
.intro{margin-top:var(--s-3);font-size:var(--t-lead);line-height:1.2;letter-spacing:-.02em;color:var(--ink-2);max-width:26ch;text-wrap:balance}
.intro b{color:var(--ink)}

.group{margin-top:var(--s-5)}
.group > h2{font-size:var(--t-small);font-weight:500;color:var(--ink-2);margin-bottom:var(--s-2)}

.split{display:grid;gap:var(--s-5)}
.split > .side > .group:first-child,.split > .main > .group:first-child{margin-top:0}
@media (min-width:900px){
  .split{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:clamp(48px,6vw,112px);align-items:start}
  .split > .side{position:sticky;top:var(--s-top)}
}

/* Work's group headings: a step above the rows. While you scroll, the wordmark says which group you're in */
section[data-view="work"] .group > h2{font-size:var(--t-body);color:var(--ink)}

/* project rows: name, what it is, then when and where */
.item{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--s-1) var(--s-4);padding:var(--s-3) 0;border-top:1px solid var(--line)}
.item h3{grid-column:1;grid-row:1;font-size:var(--t-heading);font-weight:500;letter-spacing:-.02em;line-height:1.2}
.item h3 .aka{color:var(--ink-2);font-weight:400}
.item .when{grid-column:2;grid-row:1;color:var(--ink-2);text-align:right;white-space:nowrap}
.item .what{grid-column:1/-1;font-size:var(--t-body);line-height:1.5;color:var(--ink-2);max-width:62ch;text-wrap:pretty}
.item .what b{color:var(--ink)}
.item .where{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-1) var(--s-2);color:var(--ink-2)}
.item .where > * + *::before{content:"";display:inline-block;width:1px;height:.85em;margin-right:var(--s-2);background:currentColor;opacity:.35;vertical-align:-.1em}
@media (min-width:900px){
  .item{grid-template-columns:minmax(12rem,.75fr) minmax(0,1.6fr) minmax(9rem,.5fr);align-items:baseline;column-gap:var(--s-4)}
  .item h3{grid-column:1;grid-row:1 / span 2}
  .item .what{grid-column:2;grid-row:1 / span 2}
  .item .when{grid-column:3;grid-row:1}
  .item .where{grid-column:3;grid-row:2;justify-content:flex-end;text-align:right}
}

/* project clips: on hover the clip plays behind its row, wiping in from the edge you enter by
   and out by the edge you leave. On touch screens it sits inside the row instead. */
.item{position:relative}
.item > *{position:relative;z-index:1}
.item > .shot{display:none}
@media (hover:none){
  .item > .shot{display:block;grid-column:1/-1;width:100%;height:auto;aspect-ratio:16/10;object-fit:cover;object-position:top;
    border-radius:8px;margin-top:var(--s-2);background:var(--line)}
}
@media (hover:hover) and (pointer:fine){
  .item > .shot{display:block;position:absolute;z-index:0;top:0;bottom:0;left:calc(-1 * var(--gutter));right:calc(-1 * var(--gutter));
    width:calc(100% + 2 * var(--gutter));height:100%;object-fit:cover;object-position:center 30%;background:var(--ink);
    clip-path:inset(0 0 100% 0);transition:clip-path .38s var(--ease-out);pointer-events:none}
  .item.lit > .shot{clip-path:inset(0 0 0 0)}
  /* the wash: black wipes in by the edge you came in. With a clip it quickly thins to a shade so the clip shows through.
     A translucent layer instead of a filter on the video keeps it cheap to draw. */
  .item > .wash{position:absolute;z-index:0;top:0;bottom:0;left:calc(-1 * var(--gutter));right:calc(-1 * var(--gutter));
    background:var(--ink);clip-path:inset(0 0 100% 0);pointer-events:none;transition:clip-path .38s var(--ease-out),opacity .25s var(--ease-out)}
  .item.lit > .wash{clip-path:inset(0 0 0 0)}
  .item.lit.cleared > .wash{opacity:.5}
  .item h3,.item .what,.item .what b,.item .when,.item .where,.item .ulink{transition:color .25s var(--ease-out)}
  .item.lit h3,.item.lit .what b,.item.lit .ulink{color:var(--paper)}
  .item.lit .what,.item.lit .when,.item.lit .where,.item.lit .aka{color:rgba(255,255,255,.78)}
  .item.lit .ulink{text-decoration-color:rgba(255,255,255,.45)}
}
@media (prefers-reduced-motion:reduce){.item > .shot{transition:none}}

/* cursor: one dot, never the system pointer. It reads through anything (difference),
   grows over things you can press, becomes an open-me disc over a project with a clip,
   steps aside for text fields, and spins a ring while something loads. */
@media (hover:hover) and (pointer:fine){
  html.has-cursor,html.has-cursor *{cursor:none!important}
  html.has-cursor input,html.has-cursor textarea{cursor:text!important}
}
.cursor{position:fixed;left:0;top:0;z-index:60;width:10px;height:10px;margin:-5px 0 0 -5px;
  mix-blend-mode:difference;pointer-events:none;opacity:0;will-change:transform}
.cursor::after{content:"";position:absolute;inset:0;border-radius:50%;background:var(--paper);
  transform:scale(var(--cs,1));transition:transform .25s var(--ease-out),opacity .2s}
.cursor.on{opacity:1}
.cursor.press{--cs:.7}
.cursor.link{--cs:4}
.cursor.link.press{--cs:3.4}
.cursor.open{--cs:7}
.cursor.open.press{--cs:6}
.cursor.text::after{opacity:0}
.cursor svg{position:absolute;left:50%;top:50%;width:18px;height:18px;margin:-9px 0 0 -9px;color:var(--ink);opacity:0;transform:scale(.6);
  transition:opacity .2s var(--ease-out),transform .25s var(--ease-out)}
.cursor.open svg{opacity:1;transform:none}
.cursor::before{content:"";position:absolute;inset:-10px;border-radius:50%;border:1.5px solid var(--paper);border-right-color:transparent;
  opacity:0;transition:opacity .2s}
.cursor.busy::before{opacity:1;animation:cursor-spin .8s linear infinite}
.cursor.open.busy::before{inset:-34px}
@keyframes cursor-spin{to{transform:rotate(1turn)}}
.ripple{position:fixed;left:0;top:0;z-index:59;width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;
  border:1px solid var(--paper);mix-blend-mode:difference;pointer-events:none}
@media (hover:none),(pointer:coarse){.cursor{display:none}}

/* lightbox: a project's clip, large; it grows out of where you clicked and shrinks back there */
.lightbox{position:fixed;inset:0;z-index:50;display:grid;place-items:center;padding:clamp(56px,8vh,96px) var(--gutter)}
.lightbox[hidden]{display:none}
/* the page clears to white around the clip as it grows, so only the project is left */
.lb-back{position:absolute;inset:0;background:var(--paper)}
.lb-fig{position:relative;width:min(100%,calc((100svh - 220px) * 1.6),1200px);transform-origin:50% 50%}
.lb-fig video{display:block;width:100%;aspect-ratio:16/10;object-fit:cover;object-position:top;border-radius:12px;background:var(--line);box-shadow:var(--peek-shadow)}
.lb-fig figcaption{display:flex;justify-content:center;align-items:baseline;gap:var(--s-1);margin-top:var(--s-3);font-size:var(--t-small);color:var(--ink-2)}
.lb-name{color:var(--ink)}
.lb-link{color:var(--ink-2)}
.lb-sep{color:var(--ink-3)}
.lb-close{position:absolute;top:calc(var(--gutter) + env(safe-area-inset-top));right:var(--gutter);width:var(--control);height:var(--control);
  display:grid;place-items:center;border-radius:999px;background:var(--glass-bg);box-shadow:var(--glass-edge);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);color:var(--ink)}
.lb-close:hover{color:var(--ink-2)}

/* How I work: a full screen of its own. The four phases arrive as pills joined by arrows, merge into one bar,
   and the water from the homepage carries you from one phase to the next */
.how{position:fixed;inset:0;z-index:55;background:var(--paper);display:grid;place-items:center;overflow:hidden}
.how[hidden]{display:none}
.how-water{position:absolute;inset:0;width:100%;height:100%;display:block}
.how-stage{position:relative;z-index:2;display:grid;justify-items:center;padding:0 var(--gutter)}
.how-row{display:flex;align-items:center;padding:6px;border-radius:999px;transition:background .5s var(--ease-out),box-shadow .5s var(--ease-out),gap .5s var(--ease-out)}
.how-row.merged{gap:4px}
.how-pill{display:grid;place-items:center;height:calc(var(--control) - 8px);padding:0 22px;border-radius:999px;white-space:nowrap;cursor:pointer;
  background:var(--paper);color:var(--ink);box-shadow:var(--pill-shadow);font-size:var(--t-small);
  opacity:0;transform:translateY(14px) scale(.92);transition:opacity .5s var(--ease-out),transform .6s cubic-bezier(.34,1.3,.64,1),background .3s,color .3s,box-shadow .5s}
.how-row i{position:relative;display:block;flex:none;width:clamp(20px,4vw,56px);margin:0 var(--s-2);height:1px;background:var(--ink);opacity:.35;transform:scaleX(0);transform-origin:left;
  transition:transform .5s var(--ease-out),width .55s var(--ease-out),margin .55s var(--ease-out),opacity .35s}
.how-row i::after{content:"";position:absolute;right:-1px;top:-3px;width:7px;height:7px;border-top:1px solid var(--ink);border-right:1px solid var(--ink);transform:rotate(45deg)}
.how-row .in{opacity:1;transform:none}
.how-row i.in{transform:scaleX(1);opacity:.35}
.how-row.merged{background:var(--glass-bg);box-shadow:var(--glass-edge);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur)}
.how-row.merged i{width:0;margin:0;opacity:0}
.how-and{display:inline-grid;overflow:hidden;width:0;height:1.4em;line-height:1.4em;color:var(--ink-3);font-size:var(--t-small);transition:width .5s var(--ease-out)}
.how-and > span{display:block;transform:translateY(110%);transition:transform .55s cubic-bezier(.34,1.4,.64,1) .15s}
.how-row.merged .how-and{width:1.6em;justify-content:center}
.how-row.merged .how-and > span{transform:none}
.how.casing .how-and{width:0}
.how.casing .how-and > span{transform:translateY(110%)}
.how-row.merged .how-pill{box-shadow:none;background:transparent}
.how-row.merged .how-pill:not(.now):hover{color:var(--ink-2)}
.how-row{position:relative}
.how-row .how-pill{position:relative;z-index:1}
.how-row .how-pill.now{color:var(--paper)}
.how-thumb{position:absolute;z-index:0;top:6px;left:0;height:calc(var(--control) - 8px);border-radius:999px;background:var(--ink);pointer-events:none;
  transition:transform .32s var(--ease-out),width .32s var(--ease-out),opacity .2s var(--ease-out)}
.how-thumb.instant{transition:none}
.how-thumb.off{opacity:0}
/* the phase's description, in plain black under the bar */
/* the phase bar sits in the dead centre; its words and the call hang just below it, together */
.how-below{width:min(calc(var(--t-lead) * 25),calc(100vw - 2 * var(--gutter)));margin-top:var(--s-4);display:grid;justify-items:center;gap:var(--s-4)}
.how-text{text-align:center;min-height:4.1em;font-size:var(--t-lead);line-height:1.35;letter-spacing:-.02em;font-weight:500;text-wrap:balance;
  color:var(--ink-2);transition:opacity .35s var(--ease-out),filter .45s var(--ease-out)}
.how-text b{font-weight:500;color:var(--ink)}
.how-text.out{opacity:0;filter:blur(10px)}
.how-text.pre{opacity:0;filter:blur(10px);transition:none}
.how-below[hidden]{display:none}
.how-close{position:absolute;z-index:3;top:calc(var(--gutter) + env(safe-area-inset-top));right:var(--gutter);width:var(--control);height:var(--control);
  display:grid;place-items:center;border-radius:999px;background:var(--glass-bg);box-shadow:var(--glass-edge);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);color:var(--ink)}
@media (max-width:560px){
  .how-pill{padding:0 9px;height:calc(var(--control) - 10px)}
  .how-thumb{height:calc(var(--control) - 10px)}
  .how-row.merged .how-and{width:1.2em}
  .how-row.merged{gap:0}
  .how-row i{width:10px;margin:0 6px}
  .how-row i::after{display:none}
  .how-text{min-height:5.4em}
}
@media (max-width:360px){
  .how-pill{padding:0 7px}
  .how-row i{width:6px;margin:0 3px}
}

/* the call to see a real case, under the last phase */
.how-cta{white-space:nowrap;
  font-size:var(--t-body);color:var(--ink);text-decoration:underline;text-decoration-color:var(--ink-3);text-underline-offset:4px;
  transition:opacity .45s var(--ease-out),transform .45s var(--ease-out)}
.how-cta[hidden]{display:inline-block;visibility:hidden;opacity:0;transform:translateY(8px);transition:opacity .2s var(--ease-out),transform .2s var(--ease-out),visibility 0s linear .2s}
.how-cta:hover{text-decoration-color:currentColor}
/* case mode: the bar settles at the top and the case scrolls underneath it */
.how.casing .how-stage{position:absolute;top:calc(var(--gutter) + env(safe-area-inset-top));left:0;right:0;z-index:4}
.how.casing .how-below{display:none}
.how-case{position:absolute;inset:0;z-index:3;overflow-y:auto;background:var(--paper);scrollbar-width:none}
.how-case::-webkit-scrollbar{display:none}
.how-case[hidden]{display:none}
.how-case-inner{padding:calc(var(--gutter) * 2 + var(--control) + var(--s-5)) var(--gutter) var(--s-end)}
.how-case-inner > .group:first-child,.how-case-inner > .split:first-child{margin-top:0}
.how-case-inner.swap{animation:case-in .4s var(--ease-out)}
@keyframes case-in{from{opacity:0;transform:translateX(calc(var(--dir,1) * 24px))}}
.case-lead{font-size:var(--t-lead);line-height:1.2;letter-spacing:-.02em;max-width:30ch;text-wrap:balance;color:var(--ink-2);margin-top:var(--s-4)}
.case-lead b{color:var(--ink);font-weight:500}
.how-case-inner > .case-lead:first-child{margin-top:0}

/* research */
.case-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-3);margin-top:var(--s-5)}
.case-stats div{display:grid;gap:2px;padding-top:var(--s-2);border-top:1px solid var(--ink)}
.case-stats b{font-size:var(--t-display);font-weight:500;letter-spacing:-.04em;line-height:1}
.case-stats span{font-size:var(--t-body)}
.case-stats small{font-size:var(--t-small);color:var(--ink-2)}
.quotes{display:grid;gap:var(--s-3)}
.quotes blockquote{font-size:var(--t-heading);line-height:1.35;letter-spacing:-.01em}
.quotes cite{display:block;margin-top:var(--s-1);font-style:normal;font-size:var(--t-small);color:var(--ink-2)}
.pairs{display:grid}
.pairs li{list-style:none;display:grid;grid-template-columns:minmax(0,1fr) 40px minmax(0,1.3fr);align-items:center;gap:var(--s-2);padding:var(--s-3) 0;border-top:1px solid var(--line);font-size:var(--t-body)}
.pairs span{color:var(--ink-2)}
.pairs b{font-weight:500}
.pairs i{height:1px;background:var(--ink);opacity:.4;position:relative}
.pairs i::after{content:"";position:absolute;right:0;top:-3px;width:7px;height:7px;border-top:1px solid var(--ink);border-right:1px solid var(--ink);transform:rotate(45deg)}

/* charts: one series, ink marks, the one that matters in the accent; hover for the exact value */
.chart{position:relative;margin:0}
.chart svg{display:block;width:100%;height:auto;overflow:visible}
.chart .mk{fill:var(--ink)}
.chart .mk.pk{fill:#C2532B}
.chart .ln{fill:none;stroke:var(--ink);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.chart .dt{fill:var(--ink);stroke:var(--paper);stroke-width:2}
.chart .dt.pk{fill:#C2532B}
.chart .base{stroke:var(--line)}
.chart .ticks text{font-size:12px;fill:var(--ink-2)}
.chart .hit{fill:transparent;cursor:crosshair}
.chart .hit.on{fill:rgba(10,10,10,.05)}
.chart figcaption{margin-top:var(--s-1);font-size:var(--t-small);color:var(--ink-2)}
.chart figcaption b{color:var(--ink);font-weight:500}
.chart .tip{position:absolute;top:-6px;transform:translate(-50%,-100%);padding:4px 10px;border-radius:999px;background:var(--ink);color:var(--paper);font-size:var(--t-small);white-space:nowrap;pointer-events:none}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* design: a mosaic of the work in the world, edge to edge, no gaps */
/* the first thing on Design fills the whole screen, under the floating tabs */
.mock-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-rows:50svh;grid-auto-flow:dense;gap:0;position:relative;
  margin:calc(-1 * (var(--gutter) * 2 + var(--control) + var(--s-5))) calc(-1 * var(--gutter)) 0}
.mock-grid .tile{position:relative;margin:0;overflow:hidden;background:#EFE4D2}
.mock-grid img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease-out)}
.mock-grid .tall{grid-row:span 2}
.mock-grid .wide{grid-column:span 2}
/* a warm shade over the whole grid so the logo reads; hovering a photo lifts it and lets the rest fall back */
.mock-grid::after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(to top,rgba(30,20,15,.72),rgba(30,20,15,.18) 38%,rgba(30,20,15,0) 60%);transition:opacity .4s var(--ease-out)}
.mock-grid .tile::after{content:"";position:absolute;inset:0;background:rgba(30,20,15,.5);opacity:0;transition:opacity .35s var(--ease-out);pointer-events:none}
.mock-brand{position:absolute;left:var(--gutter);bottom:var(--s-5);z-index:1;display:grid;gap:var(--s-1);color:#FAF6EF;pointer-events:none;transition:opacity .35s var(--ease-out),transform .5s var(--ease-out)}
.mock-brand span{display:inline-flex;align-items:center;gap:.28em;font-family:"Instrument Serif",Georgia,serif;font-size:clamp(3rem,1.6rem + 5vw,7.5rem);line-height:.9;letter-spacing:-.01em}
.mock-brand svg{width:.82em;height:.82em;flex:none}
.mock-brand small{font-size:var(--t-small);opacity:.8}
@media (hover:hover) and (pointer:fine){
  .mock-grid:hover .tile::after{opacity:1}
  .mock-grid .tile:hover::after{opacity:0}
  .mock-grid .tile:hover img{transform:scale(1.04)}
  .mock-grid:hover::after{opacity:.45}
  .mock-grid:hover .mock-brand{opacity:.35;transform:translateY(6px)}
}
@media (prefers-reduced-motion:reduce){.mock-grid img,.mock-brand{transition:none}}
.brand-mark{display:grid;gap:var(--s-2);padding:var(--s-4);border-radius:14px;background:#EFE4D2}
.brand-mark img{width:min(320px,80%);height:auto}
.brand-mark p{font-size:var(--t-small);color:#7A6A5E}
.principles{display:grid;gap:var(--s-2);counter-reset:p}
.principles li{list-style:none;counter-increment:p;font-size:var(--t-heading);line-height:1.3;letter-spacing:-.01em}
.principles li::before{content:counter(p);display:inline-block;width:1.6em;color:var(--ink-3);font-size:var(--t-body)}
.swatch span:last-child{opacity:.75}
.type-spec{display:grid;gap:var(--s-2);padding:var(--s-4);border-radius:14px;background:#FAF6EF;color:#2B1D16}
.ts-serif{font-family:"Instrument Serif",Georgia,serif;font-size:clamp(2.5rem,1.6rem + 3vw,4.5rem);line-height:1}
.ts-sans{font-family:Manrope,system-ui,sans-serif;font-size:var(--t-body)}
.b7-ui{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-2);padding:var(--s-4);border-radius:14px;background:#FAF6EF;font-family:Manrope,system-ui,sans-serif;color:#2B1D16}
.s-chip{display:inline-flex;align-items:center;height:34px;padding:0 14px;border-radius:999px;background:#fff;box-shadow:inset 0 0 0 1px rgba(43,29,22,.12);font-size:14px;font-weight:500}
.s-chip.on{background:#2B1D16;color:#FAF6EF;box-shadow:none}
.s-btn{display:inline-flex;align-items:center;height:48px;padding:0 22px;border-radius:999px;background:#C2532B;color:#fff;font-weight:600}
.s-stamp{width:44px;height:44px;border-radius:50%;background:#C2532B}
.s-stamp.off{background:none;box-shadow:inset 0 0 0 2px #C2532B}
.s-ticket{padding:10px 14px;border-radius:12px;background:#fff;box-shadow:0 1px 0 rgba(43,29,22,.12);font-size:14px;line-height:1.4}
/* design: the brand, the system and the screens, in the cafe's own colours */
.ds-brand{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.6fr);gap:var(--s-2)}
.ds-grid{margin:0;display:grid;gap:var(--s-2);padding:var(--s-3);border-radius:14px;background:#FAF6EF}
.ds-grid svg{width:100%;height:auto;aspect-ratio:1}
.ds-grid figcaption{font-size:var(--t-small);color:#7A6A5E}
.ds-lockups{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-2)}
.lk{display:grid;grid-template-rows:1fr auto;gap:var(--s-2);padding:var(--s-3);border-radius:14px;background:#EFE4D2;color:#2B1D16;min-height:180px}
.lk span{align-self:center;justify-self:center;display:inline-flex;align-items:center;gap:.3em;font-family:"Instrument Serif",Georgia,serif;font-size:clamp(1.6rem,1rem + 1.6vw,2.6rem);line-height:1}
.lk svg{width:1em;height:1em;flex:none}
.lk small{font-size:var(--t-small);opacity:.7}
.lk-dark{background:#2B1D16;color:#FAF6EF}
.lk-icon{background:#F8F3EA}
.lk-icon i{align-self:center;justify-self:center;display:grid;place-items:center;width:84px;height:84px;border-radius:20px;background:#C2532B;color:#fff;box-shadow:0 10px 24px -10px rgba(43,29,22,.5)}
.lk-icon i svg{width:46px;height:46px}
.lk-min{background:#FAF6EF}
.lk-min span{font-size:16px;gap:var(--s-3)}
.lk-min span svg{width:48px;height:48px}

.ds-scales{display:grid;gap:var(--s-4)}
.ds-scale{display:grid;grid-template-columns:minmax(0,.7fr) minmax(0,2.3fr);gap:var(--s-1) var(--s-4);align-items:start}
.ds-scale-h{display:grid;gap:2px}
.ds-scale-h b{font-weight:500;font-size:var(--t-heading)}
.ds-scale-h span,.ds-aa{font-size:var(--t-small);color:var(--ink-2)}
.ds-aa{grid-column:2}
.ds-steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s-1)}
.ds-steps > div{display:grid;gap:2px;font-size:var(--t-small)}
.ds-steps i{height:72px;border-radius:10px;background:var(--c);box-shadow:inset 0 0 0 1px var(--line);margin-bottom:var(--s-1)}
.ds-steps b{font-weight:500}
.ds-steps span{color:var(--ink-2);font-variant-numeric:tabular-nums}
.ds-steps small{color:var(--ink-2);line-height:1.35}

.ds-type{display:grid}
.ds-type > div{display:grid;grid-template-columns:minmax(0,.7fr) minmax(0,1.6fr) minmax(0,.7fr);gap:var(--s-4);align-items:baseline;padding:var(--s-3) 0;border-top:1px solid var(--line)}
.ds-t-role{display:grid;gap:2px;font-size:var(--t-body)}
.ds-t-role small,.ds-t-use{font-size:var(--t-small);color:var(--ink-2)}
.ds-t-sample{color:#2B1D16;line-height:1.1;overflow-wrap:anywhere}
.ds-t-sample.serif{font-family:"Instrument Serif",Georgia,serif}
.ds-t-sample.sans{font-family:Manrope,system-ui,sans-serif}
.ds-t-sample.b{font-weight:700}.ds-t-sample.m{font-weight:600}
.ds-t-sample.tab{font-variant-numeric:tabular-nums;letter-spacing:.02em;white-space:pre}

.ds-space{display:grid}
.ds-space > div{display:grid;grid-template-columns:6rem 2.5rem 170px minmax(0,1fr);gap:var(--s-2);align-items:center;padding:var(--s-2) 0;border-top:1px solid var(--line);font-size:var(--t-small)}
.ds-space code{font:13px ui-monospace,"Geist Mono",Menlo,monospace}
.ds-space span{color:var(--ink-2);font-variant-numeric:tabular-nums}
.ds-space i{display:block;height:10px;border-radius:3px;background:#C2532B}
.ds-space small{color:var(--ink-2)}
.ds-radius{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-2)}
.ds-radius > div{display:grid;gap:2px;font-size:var(--t-small)}
.ds-radius i{display:block;width:72px;height:72px;margin-bottom:var(--s-1);background:#EFE4D2;box-shadow:inset 0 0 0 1.5px #2B1D16}
.ds-radius b{font-weight:500}
.ds-radius small{color:var(--ink-2)}

.ds-states{display:grid;gap:var(--s-3);align-items:stretch}
.ds-row{display:grid;grid-template-columns:5rem repeat(4,minmax(0,1fr));gap:var(--s-2);align-items:center}
.ds-row > small{font-size:13px;color:#7A6A5E}
.ds-row > span{justify-self:start}
.ds-legend span{font-size:12px;color:#7A6A5E}
.s-btn{height:48px;font-size:15px;white-space:nowrap}
.s-btn.press{background:#A8431F;transform:scale(.97)}
.s-btn.busy{gap:8px}
.s-btn.busy i{width:14px;height:14px;border-radius:50%;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;animation:spin .8s linear infinite}
.s-btn.off{background:#E3D5BF;color:#7A6A5E}
.s-chip.off{color:#7A6A5E;text-decoration:line-through;background:transparent}
.s-ticket .t{color:#C2532B;font-weight:600}
.s-ticket{box-shadow:0 1px 0 rgba(43,29,22,.12)}
.s-ticket.ready{background:#EEF2E6}
.s-stamp{display:grid;place-items:center;color:#fff}
.s-stamp svg{width:22px;height:22px}
@keyframes spin{to{transform:rotate(1turn)}}

.ds-map{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s-2)}
.ds-map-col{display:grid;align-content:start;gap:var(--s-2)}
.ds-map-root{display:grid;gap:2px;padding:var(--s-2) var(--s-3);border-radius:12px;background:var(--ink);color:var(--paper)}
.ds-map-root b{font-weight:500;font-size:var(--t-body)}
.ds-map-root small{font-size:var(--t-small);opacity:.6}
.ds-map-g{position:relative;padding-left:var(--s-3);border-left:1px solid var(--line);margin-left:var(--s-2)}
.ds-map-g span{font-size:var(--t-small);color:var(--ink-2)}
.ds-map-g ul{display:grid;gap:2px;margin-top:4px}
.ds-map-g li{list-style:none;font-size:var(--t-body);line-height:1.4;color:var(--ink-2)}
.ds-map-g li b{font-weight:500;color:var(--ink)}

.ds-flow{display:grid;grid-template-columns:1fr 1fr 2.2fr 1fr 1fr;gap:var(--s-3);align-items:end;counter-reset:f}
.ds-flow li{list-style:none;display:grid;gap:4px;position:relative}
.ds-flow img{display:block;width:100%;height:auto;border-radius:16px;box-shadow:var(--peek-shadow);margin-bottom:var(--s-1)}
.ds-flow li.wide img{border-radius:10px}
.ds-flow b{font-weight:500;font-size:var(--t-small);line-height:1.35}
.ds-flow small{font-size:var(--t-small);color:var(--ink-2);font-variant-numeric:tabular-nums}
.ds-flow li:not(:last-child)::after{content:"";position:absolute;right:calc(var(--s-3) / -2 - 5px);top:40%;width:10px;height:10px;border-top:1.5px solid var(--ink-3);border-right:1.5px solid var(--ink-3);transform:rotate(45deg)}

.ds-wall{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:var(--s-2);padding:var(--s-4);border-radius:14px;background:#EFE4D2;margin-bottom:var(--s-3)}
.ds-wall img{display:block;width:100%;height:auto;border-radius:14px;box-shadow:0 12px 30px -16px rgba(43,29,22,.45)}
.ds-wall img:nth-child(even){transform:translateY(var(--s-4))}
.ds-wall{padding-bottom:calc(var(--s-4) * 2)}
.screens-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-3);max-width:900px}
.screens-row img{display:block;width:100%;height:auto;border-radius:22px;box-shadow:var(--peek-shadow)}
.case-refs{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:var(--s-1)}
.case-refs img{display:block;width:100%;aspect-ratio:1;object-fit:cover;border-radius:8px}

/* develop */
.case-shots{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:var(--s-3);margin-top:var(--s-5);align-items:start}
.case-shots img{display:block;width:100%;height:auto;border-radius:12px;box-shadow:var(--peek-shadow)}

/* aftercare: what's switched on */
.plan{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s-2)}
.plan > div{display:grid;align-content:start;gap:var(--s-1);padding:var(--s-3);border-radius:14px;box-shadow:inset 0 0 0 1px var(--line)}
.plan > div.on{background:var(--ink);color:var(--paper);box-shadow:none}
.plan b{font-size:var(--t-heading);font-weight:500}
.plan .state{font-size:var(--t-small);opacity:.6}
.plan p{font-size:var(--t-body);line-height:1.45;opacity:.85}

.plan-top{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s-2)}
.plan .on .state{opacity:1;display:inline-flex;align-items:center;gap:6px}
.plan .on .state::before{content:"";width:7px;height:7px;border-radius:50%;background:#6FCF8E}
.plan small{font-size:var(--t-small);opacity:.6}
.plan .meter{height:4px;margin-top:var(--s-2);border-radius:9px;background:rgba(250,246,239,.18);overflow:hidden}
.plan .meter i{display:block;height:100%;width:calc(var(--v) * 100%);border-radius:inherit;background:var(--paper);transform-origin:left;animation:meter .9s var(--ease-out) both .2s}
@keyframes meter{from{transform:scaleX(0)}}

/* develop: what it runs on */
.stack{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-2)}
.stack > div{display:grid;grid-template-columns:28px minmax(0,1fr);column-gap:var(--s-2);row-gap:2px;align-items:center;padding:var(--s-3);border-radius:14px;box-shadow:inset 0 0 0 1px var(--line)}
.stack img{grid-row:span 2;width:24px;height:24px;opacity:.85}
.stack b{font-weight:500;font-size:var(--t-body)}
.stack span{font-size:var(--t-small);color:var(--ink-2);line-height:1.4}

/* develop: the handbook */
.hb-intro{font-size:var(--t-body);color:var(--ink-2);max-width:60ch;margin-bottom:var(--s-4)}
.handbook{display:grid;gap:var(--s-4);counter-reset:hb}
.handbook li{list-style:none;display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:var(--s-4);align-items:start;padding-top:var(--s-3);border-top:1px solid var(--line)}
.handbook b{font-weight:500;font-size:var(--t-heading)}
.handbook p{margin-top:var(--s-1);font-size:var(--t-body);line-height:1.5;color:var(--ink-2)}
.handbook pre{margin:0;padding:var(--s-3);border-radius:12px;background:#141414;color:#EDEDED;font:13px/1.65 ui-monospace,"Geist Mono",Menlo,monospace;overflow-x:auto;scrollbar-width:none}

/* aftercare: ask for more (mock-up) */
.add-fab{position:relative;display:flex}
.add-fab[hidden]{display:none}
.add-fab .add-menu{position:absolute;right:0;bottom:calc(100% + var(--s-1))}
.add-fab > *{pointer-events:auto}
.add-btn{order:2;display:inline-flex;align-items:center;gap:8px;height:var(--control);padding:0 20px;border:0;border-radius:999px;background:var(--ink);color:var(--paper);font:inherit;font-size:var(--t-small);box-shadow:0 10px 30px rgba(0,0,0,.18);cursor:pointer;transition:transform .2s var(--ease-out)}
.add-btn:active{transform:scale(.97)}
.add-btn svg{transition:transform .25s var(--ease-out)}
.add-btn[aria-expanded="true"] svg{transform:rotate(45deg)}
.add-menu{order:1;display:grid;width:min(300px,calc(100vw - 2 * var(--gutter)));padding:var(--s-1);border-radius:16px;background:rgba(255,255,255,.92);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);box-shadow:0 18px 50px rgba(0,0,0,.14),inset 0 0 0 1px var(--line);transform-origin:bottom right;animation:addin .22s var(--ease-out)}
.add-menu[hidden]{display:none}
.add-menu p{padding:var(--s-1) var(--s-2);font-size:var(--t-small);color:var(--ink-2)}
.add-menu button{display:grid;text-align:left;gap:2px;padding:var(--s-2);border:0;border-radius:10px;background:none;font:inherit;font-size:var(--t-body);color:var(--ink);cursor:pointer}
.add-menu button:hover{background:rgba(0,0,0,.05)}
.add-menu button span{font-size:var(--t-small);color:var(--ink-2)}

.add-menu.out{animation:addout .15s ease-in forwards}
@keyframes addout{to{opacity:0;transform:translateY(6px) scale(.97)}}
@keyframes addin{from{opacity:0;transform:translateY(8px) scale(.96)}}

.swatches{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:var(--s-1)}
.swatch{display:grid;align-content:end;gap:2px;aspect-ratio:1.1;padding:var(--s-2);border-radius:12px;background:var(--c);color:var(--on);font-size:var(--t-small);box-shadow:inset 0 0 0 1px var(--line)}
.swatch b{font-weight:500;font-size:var(--t-body)}
@media (max-width:700px){
  .case-stats{grid-template-columns:1fr}
  .mock-grid{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:calc(100svh / 3)}
  .mock-grid::after{background-size:100% 100svh;background-repeat:no-repeat}
  .mock-brand{bottom:auto;top:calc(100svh - var(--s-5));transform:translateY(-100%)}
  .s-btn{white-space:normal;height:auto;min-height:48px;padding:8px 18px;text-align:center;line-height:1.2}
  .mock-grid .wide{grid-column:span 2}
  .case-refs{grid-template-columns:repeat(3,minmax(0,1fr))}
  .pairs li{grid-template-columns:1fr;gap:4px}
  .pairs i{display:none}
  .screens-row{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-1)}
  .case-shots,.plan,.stack{grid-template-columns:1fr}
  .ds-brand,.ds-scale{grid-template-columns:1fr}
  .ds-aa{grid-column:1}
  .ds-type > div{grid-template-columns:1fr;gap:4px}
  .ds-space > div{grid-template-columns:5.5rem 2rem minmax(0,1fr)}
  .ds-space small{grid-column:1 / -1}
  .ds-space i{max-width:100%}
  .ds-row{grid-template-columns:repeat(2,minmax(0,1fr))}
  .ds-row > small{grid-column:1 / -1}
  .ds-legend{display:none}
  .ds-map{grid-template-columns:1fr 1fr;row-gap:var(--s-4)}
  .ds-flow{grid-template-columns:repeat(2,minmax(0,1fr))}
  .ds-flow li.wide{grid-column:1 / -1}
  .ds-flow li::after{display:none}
  .ds-wall{grid-template-columns:repeat(3,minmax(0,1fr));padding:var(--s-2);padding-bottom:calc(var(--s-2) + var(--s-3))}
  .ds-wall img:nth-child(even){transform:translateY(var(--s-3))}
  .handbook li{grid-template-columns:1fr;gap:var(--s-2)}
  .plan{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* short rows: a label column and a line, used for experience, recognition and steps */
.timeline{display:grid}
.timeline li{list-style:none;display:grid;grid-template-columns:7.5rem minmax(0,1fr);gap:var(--s-3);padding:var(--s-2) 0;border-top:1px solid var(--line);
  font-size:var(--t-body);line-height:1.5}
.timeline .yr,.timeline .at{color:var(--ink-2)}
.timeline.steps li{grid-template-columns:2rem minmax(0,1fr)}

/* the photo: black and white with film grain until you point at it; caption underneath */
.me{--me-w:min(100%,320px);width:var(--me-w);margin:0}
.me-photo{position:relative;border-radius:10px;overflow:hidden}
.me-photo img{display:block;width:100%;height:auto;aspect-ratio:900/1100;object-fit:cover;filter:grayscale(1) contrast(1.08);transition:filter .5s var(--ease-out)}
.me-photo::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:.38;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E")}
.me:hover img{filter:none}
.me figcaption{margin-top:var(--s-1);font-size:var(--t-small);color:var(--ink-2)}
.prose .me{margin-top:var(--s-3)}
/* bigger screens: the photo sits in the bottom-left corner of the screen while you're on About. It grows with the
   screen but never takes more than about a third of the height; the page leaves room so text never ends under it */
@media (min-width:900px) and (min-height:700px){
  .prose .me{--me-w:clamp(220px,min(26vw,31vh),510px);position:fixed;z-index:0;left:calc(var(--gutter) + env(safe-area-inset-left));bottom:calc(var(--gutter) + env(safe-area-inset-bottom));margin:0}
  section[data-view="about"] .page-inner{padding-bottom:calc(clamp(220px,min(26vw,31vh),510px) * 1.23 + var(--gutter) * 2 + 2em)}
  /* the story passes over the photo like a negative: text is drawn in white and inverted against what's under it,
     so it reads black on the page and turns white over the photo */
  section[data-view="about"] .prose > p{position:relative;z-index:1;color:#fff;mix-blend-mode:difference}
  section[data-view="about"] .prose > p b{color:#fff}
  section[data-view="about"] .prose > p:not(:first-child){color:#949494}
  section[data-view="about"] .prose > p .ulink{text-decoration-color:rgba(255,255,255,.4)}
  html section[data-view="about"].opening .fde-p b.fde{color:#fff}
  /* when About is long enough to scroll, the photo would cover the story: it waits behind a button instead */
  .prose .me{transform-origin:0 100%;transition:opacity .35s var(--ease-out),transform .45s var(--ease-out)}
  .prose .me{opacity:0;transform:translateY(12px) scale(.6);pointer-events:none;
    bottom:calc(var(--gutter) + var(--control) + var(--s-2) + env(safe-area-inset-bottom))}
  .photo-open .prose .me{opacity:1;transform:none;pointer-events:auto}
  .photo-fits .prose .me{opacity:1;transform:none;pointer-events:auto;bottom:calc(var(--gutter) + env(safe-area-inset-bottom))}
  section[data-view="about"]:not(.photo-fits) .page-inner{padding-bottom:calc(var(--s-end) + env(safe-area-inset-bottom))!important}
  .me-toggle{position:fixed;z-index:3;left:calc(var(--gutter) + env(safe-area-inset-left));bottom:calc(var(--gutter) + env(safe-area-inset-bottom));
    height:var(--control);padding:0;color:var(--ink);font-size:var(--t-body);
    text-decoration:underline;text-decoration-color:var(--ink-3);text-underline-offset:4px;
    opacity:0;transform:translateY(8px);pointer-events:none;transition:opacity .25s,transform .3s var(--ease-out),text-decoration-color .2s}
  section[data-view="about"]:not(.photo-fits) .me-toggle{opacity:1;transform:none;pointer-events:auto}
  .me-toggle:hover{text-decoration-color:currentColor}
}
/* smaller screens: the photo waits under the story behind the same underlined line */
@media not ((min-width:900px) and (min-height:700px)){
  .me-toggle{display:block;justify-self:start;padding:6px 0;color:var(--ink);font-size:var(--t-body);
    text-decoration:underline;text-decoration-color:var(--ink-3);text-underline-offset:4px}
  .prose .me{display:none}
  .photo-open .prose .me{display:block;animation:me-in .45s var(--ease-out)}
}
@keyframes me-in{from{opacity:0;transform:translateY(10px) scale(.97)}}

/* questions and answers: same rows as the timeline, question first */
.qa{display:grid}
.qa > div{padding:var(--s-2) 0;border-top:1px solid var(--line);font-size:var(--t-body);line-height:1.5}
.qa dt{font-weight:500}
.qa dd{color:var(--ink-2);max-width:52ch}

/* reading text */
.prose{display:grid;gap:var(--s-3);max-width:58ch}
.prose p{font-size:var(--t-heading);line-height:1.45;letter-spacing:-.012em;text-wrap:pretty;color:var(--ink-2)}
.prose p b,.prose p:first-child{color:var(--ink)}
.prose p.quiet{color:var(--ink-2)}
.links{display:flex;flex-wrap:wrap;gap:var(--s-1) var(--s-3);font-size:var(--t-body)}

/* form */
.form{display:grid;gap:var(--s-3)}
.field{display:grid;gap:var(--s-1)}
.field label{color:var(--ink-2)}
.field input,.field textarea{width:100%;border:0;border-bottom:1px solid var(--line);background:none;padding:var(--s-1) 0 var(--s-2);font-size:var(--t-heading);
  letter-spacing:-.01em;border-radius:0;caret-color:var(--ink);transition:border-color .2s}
.field textarea{resize:none;min-height:3.2em;overflow:hidden;line-height:1.4}
.field input:focus,.field textarea:focus{outline:none;border-bottom-color:var(--ink)}
.field input::placeholder,.field textarea::placeholder{color:var(--ink-3)}
.hp{position:absolute;left:-9999px}
.send-row{display:flex;align-items:center;gap:var(--s-3);margin-top:var(--s-2);min-height:var(--control)}
.btn{height:var(--control);padding:0 24px;border-radius:999px;background:var(--ink);color:var(--paper);font-size:var(--t-body);font-weight:500;
  transition:opacity .2s,transform .2s var(--ease-out)}
.btn:hover{opacity:.86}
.btn:active{transform:scale(.97)}
.btn:disabled{opacity:.4;cursor:default}
.how-open{display:inline-flex;align-items:center;gap:10px;margin-top:var(--s-4)}
.how-open svg{transition:transform .25s var(--ease-out)}
.how-open:hover svg{transform:translateX(3px)}
.text-btn{padding:0;color:var(--ink);font:inherit;text-decoration:underline;text-decoration-color:var(--line);text-underline-offset:3px;transition:text-decoration-color .2s}
.text-btn:hover{text-decoration-color:currentColor}
.status,.or{font-size:var(--t-body);color:var(--ink-2)}
.status a{text-decoration:underline;text-underline-offset:3px}
.or{margin-top:var(--s-4)}

/* About opens on one phrase: everything else waits, then arrives together */
.prose p,.prose p b{transition:color .6s var(--ease-out)}
section[data-view="about"] .rise{transform:none!important;transition:opacity .6s var(--ease-out)!important}
section[data-view="about"].opening .rise,section[data-view="about"].opening .me-toggle,section[data-view="about"].opening .me{opacity:0!important;transform:none!important}
section[data-view="about"].opening .fde-p{opacity:1!important;color:transparent!important}
section[data-view="about"].opening .fde-p b:not(.fde){color:transparent!important}
section[data-view="about"].opening .fde-p b.fde{color:var(--ink)}
section[data-view="about"].landing .fde-p b.fde{color:transparent!important}
.fde-fly{position:absolute;z-index:2;white-space:nowrap;font-weight:500;line-height:.95;letter-spacing:-.04em;color:var(--ink);
  transform-origin:50% 50%;pointer-events:none;will-change:transform}

/* things in a page rise in as the page arrives */
.rise{opacity:0;transform:translateY(12px)}
.page.shown .rise.seen{opacity:1;transform:none;transition:opacity .55s var(--ease-out),transform .55s var(--ease-out);transition-delay:calc(var(--i,0) * 45ms)}

@media (max-width:560px){
  .switch a{padding:0 13px;height:calc(var(--control) - 8px)}
  .switch .thumb{height:calc(var(--control) - 8px)}
  .lead{max-width:12ch}
  /* phones: the statement sits above the switcher instead of beside it */
  .corners .bl{bottom:calc(var(--gutter) + env(safe-area-inset-bottom) + var(--control) + var(--s-3))}
  .timeline li{grid-template-columns:6rem minmax(0,1fr)}
}
@media (prefers-reduced-motion:reduce){
  .js .corner,.js .switch,.js .mark,.js .avail,.rise{opacity:1;transform:none}
  .switch .thumb,.switch a{transition:none}
}

/* the case: every tab is a cover, an overview (one sentence and its key facts), a row of sub-tabs, then one
   chapter at a time. Inside a chapter each section keeps its label on a left rail and lets its content take the
   rest of the width, so the eye runs down the labels and reads across into what it wants. Galleries and grids
   of alike things put the label on top and use the full width. Everything is fluid: no fixed reading column. */
.case-cover{position:relative;margin:calc(-1 * (var(--gutter) * 2 + var(--control) + var(--s-5))) calc(-1 * var(--gutter)) 0;height:100svh;overflow:hidden;background:#EFE4D2}
.case-cover img{display:block;width:100%;height:100%;object-fit:cover}
.case-cover::after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(to top,rgba(30,20,15,.72),rgba(30,20,15,.18) 38%,rgba(30,20,15,0) 60%)}
.case-cover figcaption{position:absolute;left:var(--gutter);right:var(--gutter);bottom:var(--s-5);z-index:1;display:grid;gap:var(--s-1);color:#FAF6EF}
.case-cover figcaption span{font-family:"Instrument Serif",Georgia,serif;font-size:clamp(3rem,1.6rem + 5vw,7.5rem);line-height:.95;letter-spacing:-.01em;text-wrap:balance}
.case-cover figcaption small{font-size:var(--t-small);opacity:.8}

.case-open{margin-top:var(--s-5);display:grid;justify-items:start}
.case-open .case-lead{margin-top:0;max-width:34ch;color:var(--ink-2);text-wrap:balance}
.case-open .case-stats,.case-open .plan{margin-top:var(--s-5);width:100%}

/* the body: a sticky list of the tab's chapters on the left (like Apple's docs), the chapters in one long scroll
   on the right. The list is plain text: the chapter you're in is ink, the rest are quiet. */
.case-body{display:grid;grid-template-columns:minmax(9rem,.18fr) minmax(0,1fr);gap:var(--s-5);margin-top:calc(var(--s-5) * 1.5);align-items:start}
.case-side{position:sticky;isolation:isolate;top:calc(var(--gutter) + env(safe-area-inset-top) + var(--control) + 4px + var(--s-4));display:grid;justify-items:start;gap:2px}
.case-side{max-height:calc(100svh - var(--gutter) * 2 - var(--control) - var(--s-4) - var(--control) - var(--s-3));overflow-y:auto;scrollbar-width:none}
.case-side::-webkit-scrollbar{display:none}
.case-side a{display:block;padding:5px 0;font-size:var(--t-body);line-height:1.35;color:var(--ink-3);text-decoration:none;transition:color .2s var(--ease-out)}
.case-side .subs{display:grid;justify-items:start;margin:2px 0 var(--s-2);padding-left:var(--s-2);border-left:1px solid var(--line)}
.case-side .side-mark{position:absolute;left:0;top:0;width:2px;border-radius:2px;background:var(--ink);pointer-events:none;transition:transform .3s var(--ease-out),height .3s var(--ease-out),width .3s var(--ease-out),opacity .2s}
.case-side .side-mark.instant{transition:none}
.case-side .side-mark.off{opacity:0}
.case-side .ch{padding-left:var(--s-2)}
.case-side .subs{margin-left:0}
.case-side .sub{padding:3px 0;font-size:var(--t-small)}
.case-side .ch + .ch{margin-top:var(--s-1)}
.case-side a:hover{color:var(--ink-2)}
.case-side a[aria-current]{color:var(--ink);font-weight:500}
/* keep each label as wide as its bold self, so marking it never nudges anything */
.case-side a::after{content:attr(data-t);display:block;height:0;overflow:hidden;visibility:hidden;font-weight:500}
.case-side a:focus-visible{outline:2px solid var(--ink);outline-offset:2px;border-radius:4px}

.how-case .group > h2,.how-case .fold summary h2{font-size:var(--t-body);font-weight:500;color:var(--ink);margin:0 0 var(--s-2);line-height:1.35}
.how-case .group > h2 small{display:block;margin-top:2px;font-size:var(--t-small);font-weight:400;color:var(--ink-3)}
.chapter + .chapter{margin-top:calc(var(--s-5) * 1.5);padding-top:var(--s-3);border-top:1px solid var(--ink)}
.chapter > header{display:grid;gap:var(--s-1);margin-bottom:var(--s-4)}
.chapter > header h2{font-size:clamp(2rem,1.3rem + 2.4vw,3.5rem);font-weight:500;letter-spacing:-.03em;line-height:1.02}
.chapter > header p{font-size:var(--t-body);line-height:1.5;color:var(--ink-2);max-width:52ch;text-wrap:pretty}
.chapter-body{display:grid;gap:var(--s-5)}
.chapter-body > *,.chapter-body .group{margin-top:0}
.chapter-body .case-shots{margin-top:0}
.chapter-body .timeline li{grid-template-columns:minmax(7rem,.3fr) minmax(0,1fr)}

/* folding sections (Aftercare): the label is the button; opens and closes with height, not a jump */
.fold{border-top:1px solid var(--line)}
.chapter-body .fold + .fold{margin-top:calc(var(--s-5) * -1)}
.fold summary{display:flex;align-items:center;justify-content:space-between;gap:var(--s-2);min-height:56px;cursor:pointer;list-style:none}
.fold summary::-webkit-details-marker{display:none}
.fold summary h2{margin:0!important}
.fold summary svg,.log summary svg{flex:none;color:var(--ink-3);transition:transform .3s var(--ease-out)}
.fold[open] > summary svg,.log details[open] > summary svg{transform:rotate(180deg)}
.fold summary:hover h2{color:var(--ink-2)}
.fold > .group-body{padding:var(--s-1) 0 var(--s-4)}
details.fold,.log details{interpolate-size:allow-keywords}
.fold::details-content,.log details::details-content{height:0;overflow:clip;opacity:0;transition:height .32s var(--ease-out),opacity .25s var(--ease-out),content-visibility .32s allow-discrete}
.fold[open]::details-content,.log details[open]::details-content{height:auto;opacity:1}

/* change logs: one row per change, open it for the detail */
.log{display:grid}
.log li{list-style:none;border-top:1px solid var(--line)}
.log li:last-child{border-bottom:1px solid var(--line)}
.log summary{display:grid;grid-template-columns:4rem minmax(0,1fr) auto auto 16px;align-items:center;gap:var(--s-2);min-height:52px;padding:var(--s-1) 0;cursor:pointer;list-style:none;font-size:var(--t-body)}
.log summary::-webkit-details-marker{display:none}
.log .v{color:var(--ink-3);font-variant-numeric:tabular-nums}
.log .t{font-weight:500;color:var(--ink)}
.log .d{color:var(--ink-3);font-size:var(--t-small);font-variant-numeric:tabular-nums;white-space:nowrap}
.log .tag{display:inline-block;padding:1px 8px;border-radius:999px;background:var(--ink);color:var(--paper);font-size:.75em}
.log summary:hover .t{color:var(--ink-2)}
.log p{padding:0 0 var(--s-3) calc(4rem + var(--s-2));font-size:var(--t-body);line-height:1.5;color:var(--ink-2);max-width:70ch}

/* tablets and phones: no sidebar; the chapters become a strip of words over a hairline, stuck under the bar */
@media (max-width:899px){
  .case-body{grid-template-columns:minmax(0,1fr);gap:var(--s-4)}
  .case-side{z-index:3;top:0;display:flex;gap:var(--s-3);
    margin:0 calc(-1 * var(--gutter));padding:calc(var(--gutter) + env(safe-area-inset-top) + var(--control) + 4px) var(--gutter) 0;overflow-x:auto;scrollbar-width:none;background:color-mix(in srgb,var(--paper) 86%,transparent);
    -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);box-shadow:inset 0 -1px 0 var(--line)}
  .case-side::-webkit-scrollbar{display:none}
  .case-side{max-height:none;overflow-y:hidden}
  .case-side .subs{display:none}
  .case-side .ch + .ch{margin-top:0}
  .case-side a{flex:none;padding:14px 0 12px;font-size:var(--t-small);box-shadow:inset 0 -2px 0 transparent;transition:color .2s var(--ease-out),box-shadow .25s var(--ease-out)}
  .case-side a[aria-current]{box-shadow:none}
  .case-side .ch{padding-left:0}
  .case-side .side-mark{top:auto;bottom:0;height:2px;width:0}
}
@media (max-width:560px){
  .log summary{grid-template-columns:3rem minmax(0,1fr) 16px;row-gap:2px}
  .log .tag,.log .d{grid-column:2;justify-self:start}
  .log summary svg{grid-column:3;grid-row:1}
  .log p{padding-left:calc(3rem + var(--s-2))}
}

/* references: a picture, what it gave the brand, and where it's from */
.case-refs{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:var(--s-3) var(--s-2)}
.case-refs a{display:grid;gap:2px;align-content:start;color:var(--ink);text-decoration:none}
.case-refs img{display:block;width:100%;aspect-ratio:4/5;object-fit:cover;border-radius:10px;margin-bottom:var(--s-1);transition:transform .5s var(--ease-out)}
.case-refs a:hover img{transform:scale(1.02)}
.case-refs b{font-weight:500;font-size:var(--t-body)}
.case-refs span{font-size:var(--t-small);color:var(--ink-2)}
.case-refs small{display:inline-flex;align-items:center;gap:4px;font-size:var(--t-small);color:var(--ink-3)}
.case-refs a:hover small{color:var(--ink)}
.ds-wall{align-items:start}
.ds-wall img:nth-child(even){transform:none}
.ds-wall{padding-bottom:var(--s-4)}

@media (max-width:1100px){.case-refs{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:560px){
  .plan{grid-template-columns:1fr}
  .case-open .case-lead{max-width:none}
  .case-refs{grid-template-columns:repeat(2,minmax(0,1fr))}
  .chapter > header p{font-size:var(--t-body)}
  .chart .ticks text{font-size:26px}
  .chart .dt{r:7px}
}
.chart .ln,.chart .base{vector-effect:non-scaling-stroke}

/* the dock: the way back to the site, and on Aftercare the way to ask for more; where the site's own nav sits */
.case-dock{position:absolute;z-index:5;right:var(--gutter);bottom:calc(var(--gutter) + env(safe-area-inset-bottom));display:flex;align-items:center;gap:var(--s-1)}
.case-dock[hidden]{display:none}
.dock-home{display:inline-flex;align-items:center;gap:6px;height:var(--control);padding:0 18px 0 14px;border-radius:999px;font-size:var(--t-small);color:var(--ink);
  background:var(--glass-bg);box-shadow:var(--glass-edge);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);transition:transform .2s var(--ease-out)}
.dock-home:active{transform:scale(.97)}
.dock-home:focus-visible,.add-btn:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.how.casing .how-case-inner{padding-bottom:calc(var(--s-end) + var(--control) + var(--s-4))}
@media (max-width:560px){.add-btn{padding:0 16px}}

.case-note{margin-top:var(--s-3);max-width:52ch;font-size:var(--t-body);line-height:1.5;color:var(--ink-2);text-wrap:pretty}
.case-note b{font-weight:500;color:var(--ink)}

/* sound on or off: a small speaker beside the clock; waves when on, a cross when off */
.sound-btn{display:inline-grid;place-items:center;width:28px;height:28px;margin:-6px -6px -6px 4px;vertical-align:middle;border-radius:999px;color:inherit;pointer-events:auto;cursor:pointer;opacity:.8;transition:opacity .2s var(--ease-out)}
.sound-btn:hover{opacity:1}
.sound-btn:focus-visible{outline:2px solid currentColor;outline-offset:1px}
.sound-btn .x{opacity:0}
.sound-btn .w1,.sound-btn .w2{transition:opacity .2s var(--ease-out)}
.sound-btn.muted .w1,.sound-btn.muted .w2{opacity:0}
.sound-btn.muted .x{opacity:1}

/* now playing: a glass pill in the dead centre of the home page; opens into a card holding Spotify's player */
.np{position:absolute;z-index:3;left:0;right:0;bottom:calc(var(--gutter) + env(safe-area-inset-bottom));margin:0 auto;width:min(320px,calc(100vw - 2 * var(--gutter)));
  padding:6px;border-radius:30px;background:var(--glass-bg);box-shadow:var(--glass-edge);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  color:var(--ink);transition:border-radius .35s var(--ease-out)}
.np.open{border-radius:22px}
.now-bar{display:flex;align-items:center;gap:12px}
.now-play{flex:none;display:grid;place-items:center;width:44px;height:44px;border-radius:999px;background:var(--ink);color:var(--paper);transition:transform .2s var(--ease-out)}
.now-play:active{transform:scale(.94)}
.now-play:focus-visible,.now-close:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.now-play .i-pause,.np.playing .now-play .i-play{display:none}
.np.playing .now-play .i-pause{display:block}
.now-play .i-play{transform:translateX(1px)}
.np.busy .now-play{animation:now-busy 1s ease-in-out infinite}
@keyframes now-busy{50%{opacity:.55}}
.now-text{flex:1;min-width:0;display:grid;line-height:1.25}
.now-text b{font-weight:500;font-size:var(--t-body);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.now-text small{font-size:var(--t-small);color:var(--ink-2)}
.now-eq{flex:none;display:flex;align-items:flex-end;gap:2px;height:14px;margin-right:10px}
.now-eq i{width:2px;height:4px;border-radius:2px;background:var(--ink-3);transition:height .3s var(--ease-out)}
.np.playing .now-eq i{background:var(--ink);animation:now-eq .9s ease-in-out infinite alternate}
.np.playing .now-eq i:nth-child(2){animation-delay:-.3s;animation-duration:.7s}
.np.playing .now-eq i:nth-child(3){animation-delay:-.6s;animation-duration:1.1s}
.np.playing .now-eq i:nth-child(4){animation-delay:-.15s;animation-duration:.8s}
@keyframes now-eq{from{height:3px}to{height:14px}}
.now-close{display:none;flex:none;width:32px;height:32px;margin-right:4px;place-items:center;border-radius:999px;color:var(--ink-2)}
.np.open .now-close{display:grid}
.np.open .now-eq{margin-right:0}
.now-close:hover{color:var(--ink)}
.now-drawer{display:grid;grid-template-rows:0fr;transition:grid-template-rows .4s var(--ease-out)}
.now-drawer > div{overflow:hidden;min-height:0}
.np.open .now-drawer{grid-template-rows:1fr}
.now-embed{margin-top:6px;border-radius:14px;overflow:hidden;min-height:80px;background:rgba(10,10,10,.06)}
.now-embed iframe{display:block;border:0}
.now-note{padding:8px 6px 2px;font-size:var(--t-small);line-height:1.4;color:var(--ink-2)}
.np.failed .now-note::after{content:" Spotify didn’t load; try again later.";color:var(--ink)}
html:not([data-view="home"]) .np{visibility:hidden}
@media (prefers-reduced-motion:reduce){.np.playing .now-eq i{animation:none;height:10px}.now-drawer{transition:none}}

/* the fine print under the contact form */
.fine{margin-top:var(--s-2);font-size:var(--t-small);color:var(--ink-2)}
.fine a{color:var(--ink-2);text-decoration:underline;text-decoration-color:var(--ink-3);text-underline-offset:3px}
.fine a:hover{color:var(--ink)}

/* the player sits at the bottom centre and arrives last, quietly: a soft rise out of a blur */
.js .np{opacity:0;transform:translateY(14px);filter:blur(8px)}
.ready .np{opacity:1;transform:none;filter:none;transition:opacity .9s var(--ease-out) .5s,transform 1s var(--ease-out) .5s,filter .9s var(--ease-out) .5s,border-radius .35s var(--ease-out)}
@media (max-width:900px){
  /* phones and tablets: above the menu, and the hero line moves up to make room */
  .np{bottom:calc(var(--gutter) + env(safe-area-inset-bottom) + var(--control) + var(--s-2))}
  .corners .bl{bottom:calc(var(--gutter) + env(safe-area-inset-bottom) + var(--control) + var(--s-2) + 56px + var(--s-4))}
}
@media (prefers-reduced-motion:reduce){.js .np{opacity:1;transform:none;filter:none}}
