:root {
  --radius: 16px; /* one corner radius for every image, card and frame */
  --paper: #FBFDFD;   /* near-white page and text-on-dark color */
  --page: var(--paper);
  --paper-2: #D3E0E1;
  --ink: #12303A;
  --muted: #4E6A73;
  --rule: #C2D2D3;
  --ultra: #1FB58A;   /* green: highlighter, guides, notes, links, hover sweeps */
  --hl: var(--ultra);
  --ultra-text: #0F7358; /* deeper green for text: 5.7:1 on the page, WCAG AA */

  --display: "Anton", Impact, sans-serif;
  --text: "Inter Tight", "Helvetica Neue", Arial, sans-serif;
  --sans: var(--text);
  --serif: var(--display);

  --gutter: clamp(16px, 2.2vw, 28px);
  --margin: clamp(16px, 5vw, 72px);
  --max: 1360px;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Typesetting: real kerning and ligatures, lining figures, and no automatic hyphenation (lines break at word spaces only) */
  font-kerning: normal; font-optical-sizing: auto; text-rendering: optimizeLegibility;
  font-variant-ligatures: common-ligatures contextual; font-variant-numeric: lining-nums;
  hyphens: manual;
}
img, svg { display: block; max-width: 100%; }
/* No widows or orphans: headings balance their lines, running text avoids a lone last word.
   js/site.js also ties the last two words together for browsers without text-wrap: pretty. */
h1, h2, h3, blockquote p { text-wrap: balance; }
p, li, dd, figcaption { text-wrap: pretty; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--ultra); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--ultra); color: var(--paper); }

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 var(--margin); }
.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); }

.skip { position: absolute; left: -9999px; }
.skip:focus { left: 16px; top: 16px; background: var(--ink); color: var(--paper); padding: 8px 12px; z-index: 10; }

/* ---------- Header ---------- */
.site-header { font-size: .9375rem; padding: 22px 0; }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.wordmark { font-family: var(--sans); font-weight: 400; font-size: 1.1875rem; letter-spacing: 0; text-decoration: none; }
.wordmark b { font-weight: 800; }
.nav { display: flex; gap: clamp(14px, 2.4vw, 32px); list-style: none; margin: 0; padding: 0; flex-wrap: wrap; }
.nav a[aria-current] { color: var(--ultra-text); }

/* ---------- Hero / artboard ---------- */
.hero { padding: clamp(24px, 5vw, 56px) 0 clamp(56px, 9vw, 120px); }
.board {
  position: relative;
  padding: clamp(40px, 8vw, 112px) clamp(8px, 3vw, 40px) clamp(48px, 6vw, 88px);
}
.guides { position: absolute; inset: 0; pointer-events: none; transition: opacity .35s ease; }
.guides .cols {
  position: absolute; inset: 0 clamp(8px, 3vw, 40px);
  display: grid; grid-template-columns: repeat(12, 1fr); column-gap: var(--gutter);
}
.guides .cols i {
  background: color-mix(in srgb, var(--ultra) 3.5%, transparent);
  border-left: 1px solid color-mix(in srgb, var(--ultra) 18%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--ultra) 18%, transparent);
  transform-origin: top;
  animation: drop .9s cubic-bezier(.2,.7,.1,1) both;
  animation-delay: calc(var(--i) * 40ms);
}
.crop { position: absolute; width: 22px; height: 22px; }
.crop::before, .crop::after { content: ""; position: absolute; background: var(--ultra); }
.crop::before { width: 22px; height: 1px; }
.crop::after { width: 1px; height: 22px; }
.crop.tl { left: -30px; top: -30px; } .crop.tl::before { bottom: 0; left: 0; } .crop.tl::after { right: 0; top: 0; }
.crop.tr { right: -30px; top: -30px; } .crop.tr::before { bottom: 0; right: 0; } .crop.tr::after { left: 0; top: 0; }
.crop.bl { left: -30px; bottom: -30px; } .crop.bl::before { top: 0; left: 0; } .crop.bl::after { right: 0; bottom: 0; }
.crop.br { right: -30px; bottom: -30px; } .crop.br::before { top: 0; right: 0; } .crop.br::after { left: 0; bottom: 0; }
.note {
  position: absolute; font-size: .75rem; color: var(--ultra-text);
  white-space: nowrap; animation: fade .6s ease both .7s;
}
.note.top { top: 12px; left: clamp(8px, 3vw, 40px); }
.note.side { right: clamp(8px, 3vw, 40px); top: 12px; }
.measure {
  position: absolute; left: clamp(8px, 3vw, 40px); right: clamp(8px, 3vw, 40px); bottom: 14px;
  height: 9px; border-left: 1px solid var(--ultra); border-right: 1px solid var(--ultra);
  animation: fade .6s ease both .8s;
}
.measure::before { content: ""; position: absolute; left: 0; right: 0; top: 4px; height: 1px; background: var(--ultra); }

.hero h1 {
  position: relative;
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(2.5rem, 6.6vw, 6.25rem);
  line-height: 1.02;
  letter-spacing: -.02em;
  max-width: 15ch;
  text-wrap: balance;
}

/* A quiet text link into the work */
.hero-link { position: relative; margin: clamp(32px, 5vw, 56px) 0 0; animation: wipe .9s cubic-bezier(.2,.7,.1,1) both .6s; }
.hero-link a {
  font-family: var(--serif); font-style: italic; font-size: clamp(1.125rem, 1.6vw, 1.375rem);
}

.guide-toggle {
  position: absolute; right: clamp(8px, 3vw, 40px); bottom: 26px; z-index: 2;
  font: inherit; font-size: .75rem; color: var(--ultra-text);
  border: 0; padding: 6px 0 2px; cursor: pointer;
}
.board.clean .guides { opacity: 0; }

@keyframes drop { from { transform: scaleY(0); } }
@keyframes fade { from { opacity: 0; } }
/* Text draws in from the top, like the grid columns. The clip extends past the box
   so descenders and underlines are never trimmed once revealed. */
/* Set line breaks put "good" and "story" on a diagonal, so the two loops never stack.
   On phones the headline scales with the screen so "starts with a story" always fits one line. */
.hero h1 { max-width: none; text-wrap: nowrap; }
@media (max-width: 599px) {
  .hero h1 { font-size: min(9vw, 2.5rem); }
}
@keyframes wipe { from { clip-path: inset(-.6em -.6em 100% -.6em); } to { clip-path: inset(-.6em); } }

/* The green marker behind "good" and "story" is drawn by the Highlighter pen styles at the end of this file. */
.marked { position: relative; white-space: nowrap; }
.marked .fw { position: relative; z-index: 1; } /* keeps the letters above the swipe */

/* ---------- Sections ---------- */
section.block { padding: clamp(64px, 10vw, 136px) 0; }
.block-head { margin-bottom: clamp(32px, 5vw, 64px); align-items: baseline; row-gap: 12px; }
.block-head h2 {
  grid-column: 1 / span 4; margin: 0;
  font-family: var(--serif); font-weight: 500; letter-spacing: -.015em; line-height: 1.08;
  font-size: clamp(1.9rem, 3.4vw, 3rem);
}

/* ---------- Work ---------- */
.projects { row-gap: clamp(48px, 7vw, 96px); }
.project { text-decoration: none; display: block; }
.project .art { overflow: hidden; border-radius: var(--radius); background: var(--paper-2); }
.project .art svg, .project .art img { width: 100%; height: auto; transition: transform .6s cubic-bezier(.2,.7,.1,1); }
.project:hover .art svg, .project:hover .art img { transform: scale(1.025); }
.project .meta { display: flex; justify-content: space-between; align-items: baseline; gap: 4px 16px; flex-wrap: wrap; margin-top: 16px; }
.project h3 { margin: 0; font-family: var(--serif); font-size: 1.3125rem; font-weight: 600; letter-spacing: -.01em; }
.project .what { color: var(--muted); font-size: .9375rem; margin: 0; text-align: right; }

.p1 { grid-column: 1 / span 8; }
.p2 { grid-column: 9 / span 4; align-self: end; }
.p3 { grid-column: 2 / span 5; }
.p4 { grid-column: 8 / span 5; margin-top: clamp(0px, 12vw, 180px); }
.p5 { grid-column: 1 / -1; }

/* ---------- About ---------- */
.about-body { row-gap: 48px; align-items: center; }
/* The portrait is framed like a layout proof, echoing the hero's artboard */
.portrait { grid-column: 1 / span 5; margin: 0; position: relative; padding: 40px; }
.portrait .crop.tl { left: 10px; top: 10px; }
.portrait .crop.tr { right: 10px; top: 10px; left: auto; }
.portrait .crop.bl { left: 10px; bottom: 10px; top: auto; }
.portrait .crop.br { right: 10px; bottom: 10px; left: auto; top: auto; }
.proof-note { position: absolute; left: 40px; font-size: .75rem; color: var(--ultra-text); white-space: nowrap; margin: 0; }
.proof-note.top { top: 14px; }
.proof-note.bottom { bottom: 14px; }
.portrait-frame { overflow: hidden; border-radius: var(--radius); background: var(--paper-2); aspect-ratio: 1 / 1; }
.portrait-frame img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
.about-text { grid-column: 7 / -1; }
.about-text h2 { margin: 0 0 20px; font-family: var(--serif); font-weight: 500; letter-spacing: -.015em; line-height: 1.08; font-size: clamp(1.9rem, 3.4vw, 3rem); }
.about-text .lede { font-family: var(--serif); font-size: clamp(1.4rem, 2.2vw, 1.75rem); line-height: 1.4; font-weight: 400; margin: 0 0 24px; letter-spacing: 0; }
.about-text p { margin: 0 0 18px; max-width: 34em; }
.spec { margin: 28px 0 0; display: grid; grid-template-columns: max-content 1fr; gap: 8px 24px; font-size: .9375rem; }
.spec dt { color: var(--ultra-text); }
.spec dd { margin: 0; }

/* ---------- Contact ---------- */
.contact { padding: clamp(72px, 12vw, 160px) 0 clamp(40px, 6vw, 72px); }
.contact h2 { margin: 0 0 20px; font-family: var(--serif); font-weight: 500; font-size: clamp(1.9rem, 3.4vw, 3rem); letter-spacing: -.015em; line-height: 1.08; }
.email {
  font-family: var(--serif); font-weight: 500; letter-spacing: -.025em; line-height: 1.05;
  font-size: clamp(1.5rem, 5.6vw, 5.25rem); display: inline-block;
  padding-bottom: 6px; overflow-wrap: anywhere;
}
.contact-row { margin-top: 28px; display: flex; gap: 16px 28px; flex-wrap: wrap; align-items: center; font-size: .9375rem; }
.copy { font: inherit; border: 1.5px solid var(--ink); border-radius: 999px; min-height: 40px; padding: 0 16px; cursor: pointer; color: var(--ink); }

footer { font-size: .875rem; color: var(--muted); padding: 28px 0 40px; }
footer .wrap { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }

/* ---------- Case study ---------- */
.case-head { padding-top: clamp(32px, 6vw, 80px); padding-bottom: clamp(32px, 5vw, 56px); }
.crumb { font-size: .9375rem; color: var(--muted); margin: 0 0 clamp(24px, 4vw, 48px); }
.case-head h1 {
  width: fit-content; /* hugs the text like .next .t, which slides and grows into this spot */
  margin: 0 0 clamp(20px, 3vw, 32px);
  font-family: var(--serif); font-weight: 500; letter-spacing: -.02em; line-height: 1.02;
  font-size: clamp(2.5rem, 6.2vw, 5.75rem);
}
.case-intro { row-gap: 32px; align-items: start; }
.standfirst { grid-column: 1 / span 7; margin: 0; font-family: var(--serif); font-size: clamp(1.3rem, 2vw, 1.625rem); line-height: 1.42; }
.case-side { grid-column: 9 / -1; }
.case-side .tags { margin-top: 24px; }
.facts { margin: 0; display: grid; grid-template-columns: max-content 1fr; gap: 8px 20px; font-size: .9375rem; padding-top: 6px; }
.facts dt { color: var(--muted); }
.facts dd { margin: 0; }
.tags { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.tags li { font-size: .8125rem; line-height: 1; padding: 6px 12px; border: 1px solid var(--ink); border-radius: 999px; white-space: nowrap; }

.fig { margin: 0; }
.fig .frame { overflow: hidden; border-radius: var(--radius); background: var(--paper-2); }
.fig svg, .fig img { width: 100%; height: auto; }
.fig figcaption { font-size: .875rem; color: var(--muted); margin-top: 10px; max-width: 44em; }

/* Stages group the chapters (see js/site.js) but draw nothing: the four-part arc is felt in the order, and named in the sticky bar. */
.sr-only { letter-spacing: 0 !important; position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.chapter { padding-top: clamp(72px, 10vw, 144px); }
/* Chapter text: a large, light statement in the ink color over a small label, two narrow columns of text and, where a
   chapter has numbers worth showing (the optional `stats` list in projects.js), a quiet rail on the right. */
.chapter-text { row-gap: 8px; }
.chapter-title {
  grid-column: 1 / span 10; margin: 0 0 clamp(36px, 5vw, 64px); font-family: var(--text); font-size: clamp(2rem, 4.4vw, 3.75rem);
  color: var(--ink); text-wrap: balance; max-width: 20em;
}
.chapter-label { grid-column: 1 / span 2; margin: 0; padding-top: .35em; font-size: .75rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.chapter-main { grid-column: 3 / span 7; }
/* Without a rail the text takes one more column, so each column keeps a comfortable measure (about 45 characters) */
.chapter-text:not(.has-rail) .chapter-main { grid-column: 3 / span 8; }
.chapter-copy { line-height: 1.7; }
/* Two column blocks side by side (the paragraphs are split between them in js/site.js), so both always start on the same line */
.chapter-copy.is-multi { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gutter); align-items: start; }
.chapter-copy p { orphans: 2; widows: 2; }
.chapter-copy p strong { font-weight: 600; }
/* Paragraph spacing is padding, not margin: Safari and Firefox keep a margin that sits at a column break, which would push the top of the second column down */
.chapter-main p { margin: 0; padding-bottom: 1.1em; max-width: 36em; }
.chapter-copy:not(.is-multi) p { max-width: 28em; } /* one column reads best at about 65 characters a line */
.chapter-rail { grid-column: 11 / -1; display: grid; gap: 22px; align-content: start; }
.chapter-rail > div { border-top: 1px solid var(--rule); padding-top: 12px; }
.chapter-rail > div > strong { display: block; font-weight: 300; font-size: clamp(1.75rem, 2.6vw, 2.5rem); line-height: 1; }
.chapter-rail > div > span { display: block; margin-top: 6px; font-size: .8125rem; line-height: 1.4; color: var(--muted); }
.figures { margin-top: clamp(28px, 4vw, 48px); row-gap: clamp(28px, 4vw, 48px); }
.fig-full { grid-column: 1 / -1; }
.fig-pair { grid-column: span 6; }
.fig-inset { grid-column: 5 / -1; }

.outcomes { list-style: none; margin: 28px 0 0; padding: 0; max-width: 36em; }
.outcomes li { border-top: 1px solid var(--rule); padding: 14px 0; }
.outcomes li:last-child { border-bottom: 1px solid var(--rule); }

.quote { margin-top: clamp(48px, 7vw, 88px); }
.quote blockquote { grid-column: 5 / span 7; margin: 0; }
.quote p { margin: 0 0 16px; font-size: clamp(1.75rem, 3.5vw, 3rem); line-height: 1.12; letter-spacing: 0; font-weight: 500; }
.quote footer { padding: 0; font-size: .9375rem; }

/* Marked figures: key numbers in the chapter text are drawn with the same marker stroke as the home page headline. Written as **text** in projects.js. */
.hl { position: relative; isolation: isolate; white-space: nowrap; padding: 0 .08em; margin: 0 -.08em; }
.hl::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none; left: -3%; right: -2.5%; top: 14%; bottom: 8%; transform: rotate(-.7deg);
  mix-blend-mode: multiply; background: var(--ink-hl);
  -webkit-mask: var(--pen) 0 0 / 100% 100% no-repeat; mask: var(--pen) 0 0 / 100% 100% no-repeat;
}
@media (prefers-reduced-motion: no-preference) {
  /* The stroke waits for its words, then wipes in from the left */
  .rv .hl::before { clip-path: inset(-10% 100% -10% -10%); }
  .rv.is-in .hl::before { clip-path: inset(-10%); transition: clip-path .7s cubic-bezier(.4, .1, .3, 1) calc(var(--rv-d, 0ms) + 900ms); }
  .is-handing-off .rv.is-in .hl::before { clip-path: inset(-10% 100% -10% -10%); transition: none; }
}

/* Next case study: its title and the top of its cover, cut off by the bottom of the page.
   The title is set like the case study h1 but smaller; it grows to full size as it slides up into place. */
.next { position: relative; margin-top: clamp(80px, 12vw, 160px); padding-top: 28px; }
/* A quiet way back to the list, on the same line as the Next label; the padding makes the touch target tall enough */
.back-link { position: absolute; top: 12px; right: 0; padding: 16px 0; font-size: .9375rem; color: var(--muted); }
.next-link { display: block; text-decoration: none; }
.next-label { display: block; margin: 0 0 clamp(24px, 4vw, 48px); color: var(--muted); font-size: .9375rem; }
.next .t {
  display: block; width: fit-content;
  font-family: var(--serif); font-weight: 500; letter-spacing: -.02em; line-height: 1.02;
  font-size: clamp(2rem, 4.2vw, 3.75rem);
}
.next-peek { display: block; margin-top: clamp(20px, 3vw, 32px); }
/* About the top 30% of a 16:9 cover */
.next-peek { --lift: 14px; }
.next-peek .frame {
  display: block; overflow: hidden; background: var(--paper-2);
  /* The frame holds a little more of the cover than shows: the extra strip below is clipped
     off at rest, and cancelled out in the layout by the negative margin */
  box-sizing: content-box; aspect-ratio: 16 / 2.7; padding-bottom: var(--lift); margin-bottom: calc(-1 * var(--lift));
  clip-path: inset(0 0 var(--lift) 0 round var(--radius) var(--radius) 0 0);
  transition: transform var(--sweep-time) var(--sweep-ease), clip-path var(--sweep-time) var(--sweep-ease);
}
.next-peek svg, .next-peek img { display: block; width: 100%; height: auto; }
/* On hover the cover rises while its bottom edge stays put, so a little more of it comes into view,
   hinting at how it slides up when clicked */
.next-link:hover .next-peek .frame, .next-link:focus-visible .next-peek .frame {
  transform: translateY(calc(-1 * var(--lift)));
  clip-path: inset(0 0 0 0 round var(--radius) var(--radius) 0 0);
}

/* The handoff to the next case study (see handoff() in js/site.js) */
::view-transition-group(case-title),
::view-transition-group(case-cover) { animation-duration: .8s; animation-timing-function: cubic-bezier(.2,.7,.1,1); }
/* The cover grows downward from the peek, so clip it to its moving frame.
   The faded peek crossfades into the full cover as it grows. */
::view-transition-group(case-cover) { overflow: clip; border-radius: var(--radius); }
/* The old page fades away on top of the new one, whose text then reveals itself
   with the same line-by-line wipe as the rest of the site */
::view-transition-old(root) { z-index: 1; animation: vt-out .3s ease both; }
::view-transition-new(root) { animation: none; }
@keyframes vt-out { to { opacity: 0; } }

/* ---------- Hover: left-to-right sweep ----------
   Every text link draws a line from left to right on hover; every button fills
   from left to right. One timing curve for all of it. */
:root { --sweep-ease: cubic-bezier(.2,.7,.1,1); --sweep-time: .5s; }

.wordmark, .nav a, .hero-link a, .crumb a, .back-link, .contact-row a, footer a, .standfirst a,
.guide-toggle, .project h3 > span {
  --line: 1px;
  --base: transparent;
  --sweep: var(--ultra);
  text-decoration: none;
  background-color: transparent;
  background-image: linear-gradient(var(--sweep), var(--sweep)), linear-gradient(var(--base), var(--base));
  background-repeat: no-repeat;
  background-position: 0 100%, 0 100%;
  background-size: 0% var(--line), 100% var(--line);
  padding-bottom: .1em;
  transition: background-size var(--sweep-time) var(--sweep-ease), color .3s ease;
}
/* Links that sit in running text keep a faint resting underline so they still read as links */
.hero-link a, .crumb a, .back-link, .contact-row a, footer a, .standfirst a, .guide-toggle {
  --base: color-mix(in srgb, currentColor 35%, transparent);
}
.email { position: relative; isolation: isolate; padding-bottom: 6px; }
.guide-toggle { --sweep: var(--ink); }

.wordmark:hover, .nav a:hover, .hero-link a:hover, .crumb a:hover, .back-link:hover, .contact-row a:hover, footer a:hover, .standfirst a:hover,
.wordmark:focus-visible, .nav a:focus-visible, .hero-link a:focus-visible, .crumb a:focus-visible, .back-link:focus-visible, .contact-row a:focus-visible, footer a:focus-visible, .standfirst a:focus-visible,
.project:hover h3 > span, .project:focus-visible h3 > span {
  background-size: 100% var(--line), 100% var(--line);
  color: var(--ultra-text);
}
.guide-toggle:hover, .guide-toggle:focus-visible { background-size: 100% var(--line), 100% var(--line); color: var(--ink); }

/* Buttons keep their colors and fill from left to right */
.copy {
  background: linear-gradient(var(--ink), var(--ink)) 0 0 / 0% 100% no-repeat;
  transition: background-size var(--sweep-time) var(--sweep-ease), color .3s ease;
}
.copy:hover, .copy:focus-visible { background-size: 100% 100%; color: var(--paper); }

/* ---------- Scroll reveals ----------
   js/site.js tags elements as they're rendered: .rv for text, .rv-img for images.
   Each one reveals when it scrolls into view, staggered by --rv-d. */
@media (prefers-reduced-motion: no-preference) {
  /* Text: each line rises from the bottom, words follow left to right (--w-d from js/site.js) */
  .rv .fw {
    display: inline-block;
    opacity: 0; transform: translateY(.6em);
    transition: opacity .7s cubic-bezier(.2,.7,.1,1) calc(var(--rv-d, 0ms) + var(--w-d, 0ms)),
                transform .9s cubic-bezier(.2,.7,.1,1) calc(var(--rv-d, 0ms) + var(--w-d, 0ms));
  }
  .rv.is-in .fw { opacity: 1; transform: none; }
  /* Discipline pills: the words rise like all other text, and the outline fades in with its first word (--li-d from js/site.js) */
  .rv .tags li {
    border-color: transparent;
    transition: border-color .7s cubic-bezier(.2,.7,.1,1) calc(var(--rv-d, 0ms) + var(--li-d, 0ms));
  }
  .rv.is-in .tags li { border-color: var(--ink); }
  /* Held back while a case study's title and cover slide into place (handoff() in js/site.js) */
  .is-handing-off .rv.is-in .fw { opacity: 0; transform: translateY(.6em); }
  .is-handing-off .rv.is-in .tags li { border-color: transparent; }
  .is-handing-off .rv-img.is-in { opacity: 0; transform: translateY(48px); }
  /* The email is both revealed and swept on hover, so it keeps both transitions */
  /* Images rise into place while fading in */
  .rv-img {
    opacity: 0; transform: translateY(48px);
    transition: opacity 1.1s cubic-bezier(.4,0,.2,1) var(--rv-d, 0ms), transform 1.4s cubic-bezier(.2,.7,.1,1) var(--rv-d, 0ms);
    will-change: opacity, transform;
  }
  .rv-img.is-in { opacity: 1; transform: none; }
}

/* ---------- Embedded live demo ---------- */
.embed { border: 1.5px solid var(--rule); border-radius: var(--radius); overflow: hidden; background: var(--paper); }
.embed-bar { display: flex; align-items: center; gap: 14px; padding: 10px 14px; font-size: .8125rem; color: var(--muted); border-bottom: 1.5px solid var(--rule); }
.embed-bar .dots { width: 44px; height: 10px; flex: none; background: radial-gradient(circle, var(--rule) 4.5px, transparent 5px) 0 0 / 15px 10px repeat-x; }
.embed-hint { flex: 1; }
.embed-toggle { font: inherit; font-size: .8125rem; color: var(--ink); background: none; border: 1.5px solid var(--ink); border-radius: 999px; padding: 3px 12px; cursor: pointer; }
.embed-toggle:hover, .embed-toggle:focus-visible { background: var(--ink); color: var(--paper); }
.embed iframe.is-phone { border-radius: 22px; box-shadow: 0 0 0 8px var(--ink), 0 12px 32px rgba(18,48,58,.18); }
.embed-screen { position: relative; overflow: hidden; background: var(--paper-2); }
.embed iframe { position: absolute; left: 0; top: 0; border: 0; transform-origin: 0 0; background: #fff; }

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  .block-head h2 { grid-column: 1 / -1; }
  .p1, .p2, .p3, .p4, .p5 { grid-column: 1 / -1; margin-top: 0; }
  .portrait { grid-column: 1 / span 8; }
  .about-text { grid-column: 1 / -1; }
  .standfirst, .case-side { grid-column: 1 / -1; }
  .facts { max-width: 32em; }
  .chapter-title, .chapter-label, .chapter-main, .chapter-rail, .chapter-text:not(.has-rail) .chapter-main { grid-column: 1 / -1; }
  .chapter-copy.is-multi { grid-template-columns: minmax(0, 1fr); }
  .chapter-label { margin-bottom: 4px; }
  .chapter-rail { grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 28px; }
  .hero-link { display: none; } /* the hero is short here, so the work is already in view */
  .board { padding-bottom: clamp(96px, 14vw, 128px); } /* room between the headline and the guides toggle */
  .fig-inset { grid-column: 1 / -1; }
  .quote blockquote { grid-column: 1 / -1; }
}
@media (max-width: 600px) {
  .case-head h1 { font-size: min(10.5vw, 2.5rem); } /* keeps titles' last two words together on small phones */
  .next .t { font-size: min(8vw, 2rem); }
  .guides .cols { grid-template-columns: repeat(4, 1fr); }
  .guides .cols i:nth-child(n+5) { display: none; }
  .crop, .note.side { display: none; }
  .portrait { grid-column: 1 / -1; }
  .portrait .crop { display: block; }
  .fig-pair { grid-column: 1 / -1; }
  .spec { grid-template-columns: 1fr; gap: 0; }
  .spec dd { margin-bottom: 14px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  html { scroll-behavior: auto; }
}


/* ---------- Typeface adjustments (Anton + Inter Tight) ----------
   Anton has a single weight, so headings drop their bold and italic. Running intro text
   moves to Inter Tight. */
h1, h2, h3, .email, .next .t, .wordmark, .wordmark b { font-weight: 400 !important; letter-spacing: -.005em !important; line-height: 1 !important; }
.hero h1 { font-size: clamp(3rem, 8.4vw, 8rem); }
.project h3 { font-size: 1.6rem; }
.wordmark, .wordmark b { font-family: var(--display); font-size: 1.3rem; }
.about-text .lede, .lede, .standfirst, .quote p, .hero-link a {
  font-family: var(--text); font-style: normal; font-weight: 400; letter-spacing: 0;
}



/* ---------- Work index ----------
   The case studies are an editorial list. Each row is a large title; the thumbnail
   pops out beside it on hover or keyboard focus. On touch and small screens the
   thumbnail sits inline under the title instead. */
.projects { display: block; border-top: 1px solid var(--ink); }
.project {
  position: relative; display: grid; align-items: center;
  grid-template-columns: 56px minmax(0, 1fr) minmax(0, 260px); column-gap: clamp(12px, 2vw, 28px);
  padding: clamp(18px, 2.2vw, 28px) 0; border-bottom: 1px solid var(--rule);
  transition: background-color .25s ease, padding .25s ease;
}
.project:hover, .project:focus-visible {
  background: color-mix(in srgb, var(--hl) 12%, transparent);
  padding-left: 12px; padding-right: 12px;
}
.project .n { font-family: var(--display); font-size: 1.125rem; color: var(--ultra-text); }
.project h3 { font-size: clamp(2.25rem, 6.2vw, 5rem); text-transform: uppercase; }
.project h3 > span { --line: 4px; }
.project .what { text-align: left; }
.project .art {
  position: absolute; right: 20%; top: 50%; z-index: 3; width: clamp(240px, 24vw, 340px); aspect-ratio: 3 / 2;
  overflow: visible; pointer-events: none; opacity: 0; transform: translateY(-58%) rotate(-3deg) scale(.96);
  box-shadow: 0 16px 40px rgba(18, 48, 58, .26);
  transition: opacity .25s ease, transform .45s cubic-bezier(.2, .7, .1, 1);
}
.project:hover .art, .project:focus-visible .art { opacity: 1; transform: translateY(-62%) rotate(-3deg); }
.project .art img, .project .art svg { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.project:hover .art svg, .project:hover .art img { transform: none; }
/* The hover highlight behind each title is drawn by the marker styles at the end of this file. */
.project .art img, .project .art svg { border-radius: var(--radius); box-shadow: 0 16px 40px rgba(18, 48, 58, .26); }
.project .art { box-shadow: none; }
.project:hover, .project:focus-visible { background: none; padding-left: 0; padding-right: 0; }
.project h3 > span, .project:hover h3 > span, .project:focus-visible h3 > span {
  position: relative; isolation: isolate; background-image: none; color: var(--ink); padding: 0 .08em .04em;
}

/* Phones: the headline stacks into four larger lines and the artboard gets taller, so the hero fills the first screen */
.hero h1 br.m { display: none; }
@media (max-width: 599px) {
  .hero h1 br.m { display: inline; }
  .hero h1 br.d { display: none; }
  .hero h1 { font-size: min(15vw, 4.5rem); line-height: 1.04 !important; }
  .board { padding: 72px clamp(8px, 3vw, 40px) 132px; }
}

/* Partner credit under the case study intro (e.g. work made as part of an agency team) */
.credit { grid-column: 1 / -1; margin: 8px 0 0; font-size: .9375rem; color: var(--muted); }
.credit a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Highlighter pen ----------
   Every highlight is drawn like a real marker, in a single pass: a smooth stroke with softly rounded ends,
   tilted a little off the baseline, in flat translucent ink. The stroke shape is a mask,
   so the color still comes from --hl. On hover it wipes in behind the title; in the hero it draws itself on load. */
:root {
  --pen: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 300 60%22 preserveAspectRatio=%22none%22%3E%3Cfilter id=%22f%22 x=%22-5%25%22 y=%22-20%25%22 width=%22110%25%22 height=%22140%25%22%3E%3CfeTurbulence type=%22fractalNoise%22 baseFrequency=%22.02 .08%22 numOctaves=%222%22 seed=%227%22 result=%22n%22/%3E%3CfeDisplacementMap in=%22SourceGraphic%22 in2=%22n%22 scale=%221.6%22/%3E%3C/filter%3E%3Cpath filter=%22url(%23f)%22 d=%22M20 6C70 3.5 130 8 180 5S258 7 280 5C293 4.5 298 14 297 30C298 46 292 55 279 55C240 57.5 190 52.5 130 55S44 54.5 21 56C7 56.5 2 47 3 31C2 14 7 6.5 20 6Z%22/%3E%3C/svg%3E");
  --ink-hl: color-mix(in srgb, var(--hl) 68%, transparent);
}
.marked::before, .email::before, .project h3 > span::before, .next .t::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  left: -3%; right: -2.5%; top: 20%; bottom: 16%; transform: rotate(-.7deg);
  mix-blend-mode: multiply;
  background: var(--ink-hl);
  -webkit-mask: var(--pen) 0 0 / 100% 100% no-repeat; mask: var(--pen) 0 0 / 100% 100% no-repeat;
}
/* The titles the stroke sits behind need their own positioning context */
.next .t { position: relative; isolation: isolate; padding: 0 .08em .04em; margin-left: -.08em; }
/* Hover: closed until pointed at, then the stroke wipes in; on leaving it fades, then resets */
.email::before, .project h3 > span::before, .next .t::before {
  opacity: 0; clip-path: inset(-10% 100% -10% -10%);
  transition: opacity .35s ease, clip-path 0s linear .35s;
}
@media (hover: hover) {
  .email:hover::before, .email:focus-visible::before, .next-link:hover .t::before, .next-link:focus-visible .t::before {
    opacity: 1; clip-path: inset(-10%); transition: clip-path .55s cubic-bezier(.4, .1, .3, 1), opacity 0s;
  }
}
@media (hover: hover) and (min-width: 961px) {
  .project:hover h3 > span::before, .project:focus-visible h3 > span::before {
    opacity: 1; clip-path: inset(-10%); transition: clip-path .55s cubic-bezier(.4, .1, .3, 1), opacity 0s;
  }
}
/* Hero: "good", then "story", each drawn once on load. The finished state is the resting style, so reduced motion shows it. */
.marked::before { z-index: 0; top: 24%; bottom: 10%; animation: pen-draw .8s cubic-bezier(.4, .1, .3, 1) 1.3s both; }
.marked + br + .marked::before, .marked ~ .marked::before { animation-delay: 1.9s; }
@keyframes pen-draw { from { clip-path: inset(-10% 100% -10% -10%); } to { clip-path: inset(-10%); } }

/* ---------- Work list on phones and touch ----------
   Each row is a quiet list item: number, title and discipline on the left, a small square thumbnail on the right.
   The whole row is one tap target. */
@media (max-width: 960px), (hover: none) {
  .projects { display: block; border-top: 1px solid var(--ink); }
  .project, .project:hover, .project:focus-visible {
    grid-template-columns: minmax(0, 1fr) 84px; grid-template-rows: auto auto auto; column-gap: 16px; row-gap: 0;
    align-items: center; min-height: 0; padding: 16px 0; border: 0; border-bottom: 1px solid var(--rule); border-radius: 0;
    background: none; color: inherit; overflow: visible;
  }
  .project::after { content: none; }
  .project .n { grid-column: 1; grid-row: 1; align-self: end; justify-self: start; margin: 0 0 6px; padding: 0; background: none; color: var(--ultra-text); font-size: .875rem; border-radius: 0; }
  .project h3 { grid-column: 1; grid-row: 2; font-size: clamp(1.6rem, 7.6vw, 2.25rem); line-height: 1.02; }
  .projects .project h3 > span, .projects .project:hover h3 > span, .projects .project:focus-visible h3 > span { color: var(--ink); padding-left: 0; }
  .project .what { grid-column: 1; grid-row: 3; margin: 8px 0 0; color: var(--muted); font-size: .875rem; line-height: 1.3; text-align: left; }
  .project .art, .project:hover .art, .project:focus-visible .art {
    position: static; grid-column: 2; grid-row: 1 / span 3; z-index: auto; width: 84px; height: 84px; aspect-ratio: 1; margin: 0;
    overflow: hidden; border-radius: var(--radius); background: var(--paper-2); box-shadow: none;
    opacity: 1; transform: none; transition: none; pointer-events: auto;
  }
  .project .art img, .project .art svg, .project:hover .art img, .project:hover .art svg {
    width: 100%; height: 100%; object-fit: cover; object-position: center; border-radius: 0; box-shadow: none;
    filter: none; mix-blend-mode: normal; transform: none; transition: none;
  }
  .project:active h3 > span { color: var(--ultra-text); }
}

/* ---------- Work list on desktop: the thumbnail follows the cursor ----------
   js/site.js moves the thumbnail with the pointer (a little behind it, so it glides). It always stays to the right of the cursor
   and simply stops at the window edge. Without a pointer (keyboard focus) it rests beside the title. */
@media (hover: hover) and (min-width: 961px) {
  .project .art {
    right: auto; left: 55%; top: 50%; transform: translateY(-50%);
    opacity: 0; transition: opacity .2s ease; will-change: transform;
  }
  .project:hover .art, .project:focus-visible .art { opacity: 1; transform: translateY(-50%); }
  .project .art img, .project .art svg {
    object-position: top; transform: rotate(-3deg) scale(.94);
    transition: transform .45s cubic-bezier(.2, .7, .1, 1);
  }
  .project:hover .art img, .project:hover .art svg, .project:focus-visible .art img, .project:focus-visible .art svg {
    transform: rotate(-3deg) scale(1);
  }
}

/* ---------- At a glance ----------
   Project, goal and outcome sit in three quiet outlined blocks: a hairline border, generous padding, a larger title over a
   plain paragraph. They stretch to the same height. */
.glance { margin-top: clamp(40px, 6vw, 72px); }
.glance-items { row-gap: var(--gutter); }
.glance-item {
  grid-column: span 4; padding: clamp(22px, 2.4vw, 32px);
  border: 1px solid color-mix(in srgb, var(--rule) 70%, transparent); border-radius: var(--radius);
}
.glance-item h3 { margin: 0 0 14px; font-family: var(--text); font-size: .75rem; font-weight: 600 !important; letter-spacing: .1em !important; line-height: 1.2 !important; text-transform: uppercase; color: var(--muted); }
.glance-item p { margin: 0; line-height: 1.7; color: var(--ink); }
@media (max-width: 960px) { .glance-item { grid-column: 1 / -1; } }

/* ---------- Chapter index ----------
   Fixed to the top of the window while the story is on screen. The chips scroll sideways, the current one is marked
   and kept centered, and a thin line along the bottom shows reading progress. */
.toc {
  position: fixed; inset: 0 0 auto 0; z-index: 40; background: color-mix(in srgb, var(--paper) 94%, transparent);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); border-bottom: 1px solid var(--rule);
  transform: translateY(-100%); visibility: hidden; transition: transform .35s cubic-bezier(.2, .7, .1, 1), visibility 0s linear .35s;
}
.toc.is-on { transform: none; visibility: visible; transition: transform .35s cubic-bezier(.2, .7, .1, 1), visibility 0s; }
.toc-track {
  display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; padding: 6px max(var(--margin), 12px);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--margin), #000 calc(100% - var(--margin)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--margin), #000 calc(100% - var(--margin)), transparent 100%);
}
.toc-track::-webkit-scrollbar { display: none; }
.toc a {
  position: relative; isolation: isolate;
  flex: none; display: inline-flex; gap: 8px; align-items: baseline; padding: 10px 12px 9px; border-radius: 4px;
  font-size: .875rem; color: var(--muted); text-decoration: none; white-space: nowrap; transition: color .2s ease;
}
/* The same marker stroke as the work titles: wipes in on hover, and stays drawn on the current section */
.toc a::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  left: 0; right: 0; top: 14%; bottom: 10%; transform: rotate(-.7deg);
  mix-blend-mode: multiply; background: var(--ink-hl);
  -webkit-mask: var(--pen) 0 0 / 100% 100% no-repeat; mask: var(--pen) 0 0 / 100% 100% no-repeat;
  opacity: 0; clip-path: inset(-10% 100% -10% -10%);
  transition: opacity .35s ease, clip-path 0s linear .35s;
}
.toc a[aria-current="location"]::before {
  opacity: 1; clip-path: inset(-10%); transition: clip-path .55s cubic-bezier(.4, .1, .3, 1), opacity 0s;
}
@media (hover: hover) {
  .toc a:hover::before, .toc a:focus-visible::before {
    opacity: 1; clip-path: inset(-10%); transition: clip-path .55s cubic-bezier(.4, .1, .3, 1), opacity 0s;
  }
}
.toc .toc-n { font-family: var(--display); font-size: .8125rem; color: var(--ultra-text); }
.toc a:hover { color: var(--ink); }
.toc a[aria-current="location"] { color: var(--ink); font-weight: 600; }
.toc-bar { position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--ultra); transform: scaleX(0); transform-origin: left; }
.chapter-title, .stage, .glance { scroll-margin-top: 56px; }
@media (prefers-reduced-motion: reduce) { .toc, .toc.is-on { transition: none; } }

/* ---------- Work: card grid ----------
   Cards sit two to a row in a 2 x 2 pattern: the left card is wider in one row and the right card is wider in the next.
   Wide and narrow cards get proportional image shapes so the two in a row are the same height. A lone last card spans the row.
   (The previous typographic list is kept: set HOME_LAYOUT = 'list' in js/site.js.) */
.cards { row-gap: clamp(40px, 5vw, 72px); }
.card { display: block; color: inherit; text-decoration: none; }
.c-lw { grid-column: 1 / span 7; }
.c-rn { grid-column: 8 / span 5; }
.c-ln { grid-column: 1 / span 5; }
.c-rw { grid-column: 6 / span 7; }
.c-solo { grid-column: 1 / -1; }
.card .art { overflow: hidden; border-radius: var(--radius); background: var(--paper-2); aspect-ratio: 5 / 4; }
.c-lw .art, .c-rw .art { aspect-ratio: 16 / 9; }
.c-solo .art { aspect-ratio: 21 / 9; }
.card .art img, .card .art svg {
  display: block; width: 100%; height: 100%; object-fit: cover; object-position: top;
  transition: transform .6s cubic-bezier(.2, .7, .1, 1);
}
.card:hover .art img, .card:hover .art svg, .card:focus-visible .art img, .card:focus-visible .art svg { transform: scale(1.03); }
.card-meta { padding-top: 16px; }
.card .n { display: none; }
.card h3 { margin: 0; font-family: var(--display); font-size: clamp(1.6rem, 2.6vw, 2.5rem); line-height: 1.02; text-transform: uppercase; }
.card h3 > span { position: relative; isolation: isolate; padding: 0 .08em .04em; margin-left: -.08em; }
.card .what { margin: 8px 0 0; color: var(--muted); font-size: .9375rem; line-height: 1.35; }

/* The marker highlight, as on the other titles */
.card h3 > span::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  left: -3%; right: -2.5%; top: 20%; bottom: 16%; transform: rotate(-.7deg); mix-blend-mode: multiply;
  background: var(--ink-hl); -webkit-mask: var(--pen) 0 0 / 100% 100% no-repeat; mask: var(--pen) 0 0 / 100% 100% no-repeat;
  opacity: 0; clip-path: inset(-10% 100% -10% -10%); transition: opacity .35s ease, clip-path 0s linear .35s;
}
@media (hover: hover) and (min-width: 961px) {
  .card:hover h3 > span::before, .card:focus-visible h3 > span::before {
    opacity: 1; clip-path: inset(-10%); transition: clip-path .55s cubic-bezier(.4, .1, .3, 1), opacity 0s;
  }
}

/* Phones and touch: one column of full-width cards, image over title and tags.
   (MOBILE_LAYOUT = 'rows' in js/site.js swaps these for compact rows: text left, small square thumbnail right.) */
@media (max-width: 960px), (hover: none) {
  .cards { grid-template-columns: minmax(0, 1fr); row-gap: 36px; }
  .cards .card.c-lw, .cards .card.c-rn, .cards .card.c-ln, .cards .card.c-rw, .cards .card.c-solo { grid-column: 1 / -1; }
  .cards .card .art, .cards .card.c-lw .art, .cards .card.c-rw .art, .cards .card.c-solo .art { aspect-ratio: 3 / 2; }
  .cards .card .art img, .cards .card .art svg { transition: none; }
  .cards .card:hover .art img, .cards .card:hover .art svg { transform: none; }
  .card-meta { padding-top: 12px; }
  .card h3 { font-size: clamp(1.6rem, 7.6vw, 2.25rem); }
  .card .what { margin-top: 6px; font-size: .875rem; }
}
@media (max-width: 960px), (hover: none) {
  .cards.rows { display: block; border-top: 1px solid var(--ink); }
  .cards.rows .card, .cards.rows .card.c-lw, .cards.rows .card.c-rn, .cards.rows .card.c-ln, .cards.rows .card.c-rw, .cards.rows .card.c-solo {
    display: grid; grid-template-columns: minmax(0, 1fr) 84px; column-gap: 16px; align-items: center;
    margin: 0; padding: 16px 0; border-bottom: 1px solid var(--rule);
  }
  .cards.rows .card .art, .cards.rows .card.c-lw .art, .cards.rows .card.c-rw .art, .cards.rows .card.c-solo .art { order: 2; width: 84px; height: 84px; aspect-ratio: 1; border-radius: 4px; }
  .cards.rows .card .art img, .cards.rows .card .art svg { object-position: center; }
  .cards.rows .card-meta { order: 1; padding: 0; }
  .cards.rows .n { display: block; margin: 0 0 6px; color: var(--ultra-text); font-family: var(--display); font-size: .875rem; }
  .cards.rows .card .what { margin-top: 8px; }
}

/* ---------- Cursor label ----------
   The pill that follows the pointer over a work card or the next-case-study link. It is the page color with ink text
   and a soft shadow, so it stays readable over any image (about 13:1, past WCAG AA). The native cursor is hidden
   over those links while it is active. */
.cursor-on .card:hover, .cursor-on .next-link:hover { cursor: none; }
.cursor-label {
  position: fixed; left: 0; top: 0; z-index: 60; pointer-events: none;
  padding: 9px 18px; border-radius: 999px; white-space: nowrap;
  background: var(--paper); color: var(--ink);
  font-size: .875rem; font-weight: 600; line-height: 1.2;
  box-shadow: 0 6px 20px rgba(18, 48, 58, .25);
  opacity: 0; transition: opacity .15s ease;
}
.cursor-label.is-on { opacity: 1; }

/* One corner radius for images, cards and frames; a touch smaller on phones */
@media (max-width: 600px) { :root { --radius: 12px; } }

/* ---------- About: aligned to the work grid above it (desktop) ----------
   The photo is a square across the first five columns, the same width as a narrow card. The text starts in column 7 and
   runs to the right edge (six columns), leaving column 6 and the gutters as open space between the two. The crop marks
   and notes hang just outside the photo, as on the hero artboard, with room to spare. */
@media (min-width: 961px) {
  .about-body { align-items: start; }
  .portrait { grid-column: 1 / span 5; padding: 0; }
  .portrait .crop.tl { left: -26px; top: -26px; }
  .portrait .crop.tr { right: -26px; top: -26px; left: auto; }
  .portrait .crop.bl { left: -26px; bottom: -26px; top: auto; }
  .portrait .crop.br { right: -26px; bottom: -26px; left: auto; top: auto; }
  .proof-note { left: 0; }
  .proof-note.top { top: -24px; }
  .proof-note.bottom { bottom: -24px; }
  .about-text { grid-column: 7 / span 6; }
  .about-text p { max-width: 36em; }
}

/* Case study headings are set in the text face, medium weight, sentence case: statements to read, not labels to scan. */
.chapter-title { font-weight: 300 !important; letter-spacing: 0 !important; line-height: 1.12 !important; }
