/* ==========================================================
   Sophia Ho portfolio
   Plain CSS, no build step. Edit the tokens below to restyle.
   ========================================================== */

@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-latin-wdth-normal.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-latin-ext-wdth-normal.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Hand";
  src: url("../fonts/nothing-you-could-do-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  color-scheme: light;

  /* colour */
  --paper:    #F4F5F1;
  --ink:      #191C1A;
  --graphite: #676C68;
  --rule:     #DADDD5;
  --accent:   #D63F7C;   /* raspberry: status dot, focus, hover */
  --white:    #FFFFFF;

  /* placeholder tints */
  --tint-sage:  #DDE4D8;
  --tint-lilac: #E3DFEC;
  --tint-sand:  #ECE5DA;
  --tint-sky:   #DAE3EA;

  /* type scale (modular, ~1.25) */
  --fs-small: 0.875rem;
  --fs-body:  1.0625rem;
  --fs-h3:    1.25rem;
  --fs-h2:    1rem;
  --fs-hero:  clamp(2.25rem, 1.2rem + 4.4vw, 4.75rem);
  --fs-email: clamp(1.75rem, 1rem + 3.6vw, 4rem);

  /* spacing */
  --gutter: clamp(1.25rem, 3.5vw, 3rem);
  --col-gap: clamp(1rem, 2vw, 2rem);
  --section: clamp(4.5rem, 10vw, 9rem);

  --ease: cubic-bezier(.2, .7, .2, 1);
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 6rem; }
body {
  margin: 0;
  background-color: var(--paper);
  /* faint dot grid, as on the previous slsho.com */
  background-image: radial-gradient(#d1d1d1 1px, transparent 1px);
  background-size: 20px 20px;
  background-position: 10px 10px;
  color: var(--ink);
  font-family: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: var(--fs-body);
  font-weight: 400;
  font-stretch: 100%;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* case studies (full page and popup) stay plain, no dot grid */
body:has(main.cs) { background-image: none; }
img { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, h3, p, dl, dd, ul, figure { margin: 0; padding: 0; }
ul { list-style: none; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip {
  position: absolute; left: var(--gutter); top: -3rem;
  background: var(--ink); color: var(--paper);
  padding: .5rem .75rem; z-index: 10; text-decoration: none;
}
.skip:focus { top: 1rem; }

.wrap {
  width: 100%;
  max-width: 1320px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Shared link treatment: underline that draws in on hover */
.hero a,
.footer__links a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size .35s var(--ease), color .2s;
}
.hero a:hover,
.footer__links a:hover { color: var(--accent); }

/* ---------- Header ---------- */
/* Top of the page: logo on the left, pill nav in the middle, Toronto time on the right.
   Once you scroll past 20px the logo and clock fade out (main.js adds .is-scrolled) and only the
   floating pill stays, fixed at top-centre. The header itself scrolls away with the page. */
.site-header {
  position: relative;
  z-index: 100;
}
.site-header__inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--col-gap);
  padding-top: clamp(1.9rem, 2.6vw, 2.5rem);     /* name and time sit lower on the page, level with the pill */
  padding-bottom: .85rem;
  font-size: var(--fs-small);
}
.site-header .wordmark, .site-header .clock {
  transition: opacity .3s var(--ease), visibility 0s linear 0s;
}
.site-header.is-scrolled .wordmark, .site-header.is-scrolled .clock {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .3s var(--ease), visibility 0s linear .3s;
}
/* name: just "sophia ho", plain and upright */
.wordmark {
  display: inline-flex;
  justify-self: start;          /* don't stretch across the grid column */
  align-items: center;
  text-decoration: none;
}
.wordmark__text { display: grid; line-height: 1.15; }
.wordmark__name {
  font-size: 1.5rem;
  font-weight: 480;
  font-style: normal;
  letter-spacing: -0.015em;
}

/* floating pill */
.site-nav {
  position: fixed;
  z-index: 100;
  top: clamp(1.1rem, 1.7vw, 1.7rem);             /* sits level with the name and the clock */
  left: 50%;
  translate: -50% 0;
  display: flex;
  align-items: center;
  gap: .25rem;
  padding: .4rem;
  max-width: calc(100vw - 1rem);
  background: #f5f4f0;
  border: 1px solid rgba(25, 28, 26, .14);
  border-radius: 9999px;
  box-shadow: 0 1px 2px rgba(25, 28, 26, .06), 0 8px 24px -10px rgba(25, 28, 26, .28);
  font-size: .9375rem;
  font-weight: 500;
  white-space: nowrap;
}
.site-nav__link {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .5rem 1rem;
  border: 0; border-radius: 9999px;
  background: none; color: #1c1c1c;
  font: inherit; line-height: 1.2; text-decoration: none; cursor: pointer;
  transition: background-color .2s, color .2s;
}
.site-nav__link:hover { background: rgba(25, 28, 26, .07); }
.site-nav__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.site-nav__link[aria-current="page"], .site-nav__link[data-current] { background: #1c1c1c; color: #fff; }
.site-nav__chev, .site-nav__arrow { flex: none; }
.site-nav__chev { transition: rotate .2s var(--ease); }
.site-nav__trigger[aria-expanded="true"] .site-nav__chev { rotate: 180deg; }
.site-nav__rule { width: 1px; height: 1.5rem; margin-inline: .25rem; background: rgba(25, 28, 26, .2); }
.site-nav__menu { position: relative; }
.site-nav__drop {
  position: absolute; top: calc(100% + .6rem); left: 0; min-width: 14rem;
  margin: 0; padding: .4rem; list-style: none;
  background: #f5f4f0; border: 1px solid rgba(25, 28, 26, .14); border-radius: 18px;
  box-shadow: 0 1px 2px rgba(25, 28, 26, .06), 0 16px 32px -12px rgba(25, 28, 26, .3);
}
.site-nav__drop[hidden] { display: none; }
.site-nav__drop a {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .55rem .8rem; border-radius: 12px; color: #1c1c1c; text-decoration: none;
}
.site-nav__drop a:hover, .site-nav__drop a:focus-visible { background: rgba(25, 28, 26, .07); outline: none; }
.site-nav__drop a[aria-current="page"] { background: #1c1c1c; color: #fff; }
.site-nav__drop span { color: var(--graphite); font-weight: 400; font-size: .8125rem; align-self: center; }
.site-nav__drop a[aria-current="page"] span { color: rgba(255, 255, 255, .7); }
.clock {
  justify-self: end;
  display: flex; align-items: center; gap: .5rem;
  color: var(--graphite);
  font-variant-numeric: tabular-nums;
}
.clock__time { color: var(--ink); }

/* pixel sun (6 AM–6 PM Toronto time) or moon (otherwise); set by main.js */
.clock__icon { width: 13px; height: 13px; flex: none; display: none; }
.clock__icon--sun  { fill: #E39A2D; }
.clock__icon--moon { fill: #5B6475; }
.clock[data-phase="day"]   .clock__icon--sun,
.clock[data-phase="night"] .clock__icon--moon { display: block; }

.status-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  display: inline-block;
}

/* ---------- Hero ---------- */
.hero {
  padding-top: clamp(4rem, 12vw, 10rem);
  padding-bottom: var(--section);
}
.hero__top {
  display: grid;
  /* no z-index/transform here: keeps the polaroid in the hero's stacking context */
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--col-gap);
}
.hero__portrait {
  --r: 3deg;
  width: clamp(11rem, 19vw, 17rem);
}
/* The polaroid and the note live in one box that is exactly as wide as the polaroid.
   The note is placed in % of THAT box, so the overlap is identical at every screen
   width (it used to hang off the bottom of the hero and drift). */
.hero__cards {
  position: relative;
  margin-right: clamp(0rem, 4vw, 4rem);
}
.hero .hero__portrait .media { aspect-ratio: 4 / 5; }
.hero__title {
  font-size: var(--fs-hero);
  font-weight: 430;
  font-stretch: 106%;
  line-height: 1.04;
  letter-spacing: -0.028em;
  max-width: 17ch;
  text-wrap: balance;
}
.hero__proof {
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  font-size: clamp(1.125rem, 1rem + .6vw, 1.5rem);
  font-stretch: 104%;
  line-height: 1.35;
  color: var(--graphite);
}
.hero__proof a { color: var(--ink); }
.hero__status {
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  display: flex; align-items: center; flex-wrap: wrap; gap: .5rem .8rem;
  /* same size as the "Currently at ..." line it replaced */
  font-size: clamp(1.125rem, 1rem + .6vw, 1.5rem);
  font-stretch: 104%;
  line-height: 1.35;
}
.hero__status .status-dot { width: .6em; height: .6em; flex: none; background: #12B84A; }
.hero__status a { margin-left: .25rem; }

/* ---------- Sticky notes (home hero) ---------- */
/* Anchored to the right of the hero, under the portrait. main.js lets people
   drag them (translate), click to bring one to the front, or nudge with the
   arrow keys. Below 1040px they just sit in the flow, no dragging. */
/* The hero is its own stacking layer (z-index 5), below the sticky header (20). The cards'
   z-index (which main.js raises on every click) now only ranks them against each other
   inside the hero; before, it was compared with the header directly and could pass it. */
.hero { position: relative; z-index: 5; }
.hero__notes {
  position: absolute;
  /* default rest position, measured from the mockup: the note's RIGHT edge sits 43% of
     the way into the polaroid (so the polaroid covers the note's top-right corner),
     and its top edge sits 86% of the way down. Anchoring the right edge keeps the
     overlap constant even though the note and polaroid scale at different rates. */
  right: 57%;
  top: 86%;
  /* deliberately NO z-index: a z-index here would make this wrapper its own
     stacking context, and the polaroid (outside it) could never rise above the
     note. With none, the note's own z-index competes with the polaroid's directly. */
  pointer-events: none;            /* only the notes themselves catch the mouse */
}
.sticky-note {
  --note-bg: #CDBBEE;
  --r: 2deg;
  position: relative;
  z-index: 1;                       /* base layer; main.js raises it above this on click/drag */
  pointer-events: auto;
  width: clamp(230px, 22vw, 290px);
  padding: 1.5rem 1.5rem 1.35rem;
  background: var(--note-bg);
  border-radius: 3px;
  box-shadow: 0 1px 2px rgba(25, 28, 26, .1), 0 12px 28px -14px rgba(25, 28, 26, .38);
  rotate: var(--r, 0deg);
  translate: var(--dx, 0px) var(--dy, 0px);
  cursor: grab;
  user-select: none; -webkit-user-select: none;
  touch-action: none;
  transition: scale .3s var(--ease), box-shadow .3s var(--ease);
}
.sticky-note:hover { scale: 1.015; box-shadow: 0 2px 4px rgba(25, 28, 26, .1), 0 20px 38px -16px rgba(25, 28, 26, .42); }
.sticky-note.is-dragging { cursor: grabbing; scale: 1.03; transition: scale .2s var(--ease), box-shadow .2s; box-shadow: 0 4px 8px rgba(25, 28, 26, .12), 0 28px 44px -16px rgba(25, 28, 26, .45); }
.sticky-note.is-popped { animation: note-pop .5s var(--ease); }
@keyframes note-pop {
  0% { rotate: var(--r, 0deg); }
  30% { rotate: calc(var(--r, 0deg) + 3deg); }
  65% { rotate: calc(var(--r, 0deg) - 2deg); }
  100% { rotate: var(--r, 0deg); }
}
.sticky-note--pink   { --note-bg: #F6B9D0; }
.sticky-note--butter { --note-bg: #F3DF86; }
.sticky-note--mint   { --note-bg: #BFE3CF; }
.sticky-note__label {
  margin-bottom: 1.1rem;
  font-size: var(--fs-small);
  font-weight: 560;
}
.sticky-note__line { font-size: var(--fs-body); font-weight: 560; line-height: 1.25; }
.sticky-note__line + .sticky-note__line { margin-top: .9rem; }
.sticky-note__line span { display: block; margin-top: .1rem; font-weight: 400; color: rgba(25, 28, 26, .62); }
.sticky-note__links { display: flex; flex-wrap: wrap; gap: .5rem 1.25rem; margin-top: 1.4rem; font-size: var(--fs-small); font-weight: 560; }
.sticky-note a {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1.5px;
}
.sticky-note a:hover { color: var(--accent); }
.sticky-note a { cursor: pointer; position: relative; z-index: 1; }   /* a pointer, not the card's grab hand */
.sticky-note__line span a { color: inherit; }
.sticky-note.load-in { translate: var(--dx, 0px) var(--dy, 0px); }

/* the portrait polaroid is draggable too. The note's drag offset goes through
   translate, so the polaroid's hover-lift (also translate) is folded into it
   instead of replacing it. A raised card also sits above its neighbours. */
.polaroid[data-sticky] {
  position: relative;
  z-index: 2;                       /* default: rests on top of the note. main.js raises either card on click/drag */
  cursor: grab;
  user-select: none; -webkit-user-select: none;
  touch-action: none;
  translate: var(--dx, 0px) var(--dy, 0px);
}
.polaroid[data-sticky]:hover { translate: var(--dx, 0px) calc(var(--dy, 0px) - 6px); }
.polaroid[data-sticky].is-dragging {
  cursor: grabbing;
  rotate: var(--r, 0deg);
  /* follow the pointer exactly, keeping the hover lift: dropping it here made the card jump 6px the moment a drag began */
  translate: var(--dx, 0px) calc(var(--dy, 0px) - 6px);
  scale: 1.03;
  transition: scale .2s var(--ease), box-shadow .2s, rotate .3s var(--ease);   /* no translate easing: it tracks the pointer 1:1. Rotate eases back from the hover's 0deg instead of snapping */
  box-shadow: 0 4px 8px rgba(25, 28, 26, .12), 0 28px 44px -16px rgba(25, 28, 26, .45);
}
.polaroid[data-sticky].is-popped { animation: note-pop .5s var(--ease); }
.polaroid[data-sticky] .polaroid__cap {
  padding: .55rem .1rem .8rem;
  font-family: "Hand", "Archivo", cursive;
  font-size: 1.35rem;
  line-height: 1.1;
}   /* keep drag offset independent of the load-in transform */
@media (max-width: 1039px) {
  .hero { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: var(--col-gap); }
  .hero__top, .hero__cards { display: contents; }
  .hero__portrait { margin-right: clamp(0rem, 4vw, 4rem); }
  .hero__status { grid-column: 1 / -1; order: 1; }
  .hero__notes { grid-column: 1 / -1; order: 2; position: static; margin-top: 2.25rem; }
  .sticky-note { translate: none; cursor: auto; touch-action: auto; user-select: auto; -webkit-user-select: auto; max-width: 20rem; }
  .sticky-note:hover { scale: 1; }
  .polaroid[data-sticky] { translate: none; cursor: auto; touch-action: auto; user-select: auto; -webkit-user-select: auto; }
  .polaroid[data-sticky]:hover { translate: 0 -6px; }
}
@media (prefers-reduced-motion: reduce) {
  .sticky-note.is-popped, .polaroid[data-sticky].is-popped { animation: none; }
}

/* ---------- Section titles ---------- */
.section-title {
  font-size: var(--fs-h2);
  font-weight: 560;
  font-stretch: 100%;
  padding-bottom: 1rem;
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
  border-bottom: 1px solid var(--rule);
}

/* ---------- Work: ID lanyard cards ---------- */
/* The section is its own stacking layer BELOW the sticky header (20): main.js keeps raising
   the dragged card's z-index, and without this the cards would eventually pass the nav. */
.work { padding-bottom: var(--section); position: relative; z-index: 4; }
.work__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 3rem);
  padding-top: 1.25rem;
  row-gap: clamp(1.5rem, 3vw, 2.5rem);
}

/* ---- Retractable badge reels ----
   Each card hangs from its own reel (a photo in images/badge/, body + ribbed neck), a thin black cord,
   and a clear vinyl strap (also a photo) that loops through the card's slot. main.js draws the cord
   from the hole in the reel's neck to the strap's eyelet, so it stretches when you pull the card and
   the card springs back on release. The reel itself ignores the mouse. */
.reel-unit {
  --disc: clamp(3.8rem, 4.8vw, 4.6rem);             /* reel width */
  --reel-h: calc(var(--disc) * 1.43);               /* reel photo height (body + neck) */
  --strap-up: 3.7rem;                               /* how far the vinyl strap rises above the card's top edge */
  --strap-w: 2.1rem;
  position: relative;
  padding-top: calc(var(--reel-h) + var(--strap-up) + .2rem);
}
.reel {
  position: absolute; z-index: 2; top: 0; left: 50%;
  width: var(--disc); height: var(--reel-h);
  margin-left: calc(var(--disc) / -2);
  pointer-events: none;
  /* a tight contact shadow and a soft one falling down the page */
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .3)) drop-shadow(0 7px 7px rgba(25, 28, 26, .3));
}
.reel__img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: top; }
.reel__anchor { position: absolute; left: 49%; top: 92%; }   /* the hole in the neck where the cord comes out (measured by main.js) */
.reel__cord {
  position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible;
  pointer-events: none;
  z-index: 9999;   /* always over every card: main.js raises a card's z-index (topZ) on each grab, so this must stay far above it */
  filter: drop-shadow(0 1px .5px rgba(0, 0, 0, .22));
}
.reel__cord path { fill: none; stroke: #2A2A2F; stroke-width: 1.9; stroke-linecap: round; }

/* clear vinyl strap (images/badge/clip.png): hangs from the cord by its eyelet, snaps shut, and runs down
   into the card's slot. The photo's plastic is see-through; behind it the page is softly blurred, like thick PVC. */
.strap { position: absolute; left: 0; top: 0; width: 0; height: 0; }
.strap__vinyl {
  position: absolute; left: calc(var(--strap-w) / -2); width: var(--strap-w);
  top: calc(var(--strap-up) * -1);
  height: calc(var(--strap-up) + var(--head-h) / 2);
  border-radius: .4rem .4rem 0 0;
  background: url("../../images/badge/clip.png") top / 100% auto no-repeat;
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .2));
}
.strap__loop {                                           /* the fold of vinyl running through the slot */
  position: absolute; left: calc(var(--strap-w) / -2); width: var(--strap-w);
  top: calc(var(--head-h) / 2 - .05rem); height: .3rem;
  border-radius: 0 0 .25rem .25rem;
  background: linear-gradient(rgba(60, 70, 85, .45), rgba(205, 214, 224, .35));
  box-shadow: 0 0 0 .5px rgba(70, 80, 95, .35), 0 1px 1px rgba(0, 0, 0, .25);
}
.strap__end { position: absolute; left: 0; top: calc(var(--strap-up) * -1 + var(--strap-w) * .605); width: 0; height: 0; }   /* the eyelet */

/* Drag layer. main.js moves this with transform: translate3d(x, y, 0) (GPU-accelerated, no
   layout) and raises its z-index when grabbed. The tilt and hover lift live on .id-card
   inside it, so the two never overwrite each other. */
.id-slot {
  position: relative;
  z-index: 1;
  cursor: grab;
  user-select: none; -webkit-user-select: none;
  -webkit-touch-callout: none;
  touch-action: pan-y;            /* a finger can still scroll the page; the top band below is the touch handle */
  will-change: transform;
  container-type: inline-size;    /* cqw inside = % of the card's width, so the holder photo keeps its shape */
}
.id-slot.is-dragging { cursor: grabbing; }
.id-slot img { -webkit-user-drag: none; }
.id-slot .id-card__head, .id-slot .lanyard-attachment { touch-action: none; }

.id-card {
  /* A clear zip-seal badge pocket: the photo images/badge/holder.png (800 x 791), drawn as a 9-slice frame so
     the flap, slot and zip keep their shape whatever the card's height. Sizes are in cqw (% of the card's
     width) so the photo is never squashed. --head-h runs from the top to the slot's centre line times two.
     --brand is the colour of the strip printed along the bottom of the card inside (set per card in index.html). */
  --brand: #1E1E24;
  --head-h: 15.1cqw;              /* the slot's centre sits at half of this (60 of the photo's 800px width) */
  --hb-top: 20.4cqw;              /* flap + zip ridges: the photo's top 163px */
  --hb-edge: 2.3cqw;              /* sealed side and bottom edges: 18px */
  --r: 0deg;
  position: relative;
  border-radius: 2.8cqw;
  /* box-shadow is never painted inside the element's own box, so it can't show through the clear plastic;
     it is offset and pulled in so it only falls below the holder. Clear plastic casts a light shadow. */
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 12px 14px -10px rgba(25, 28, 26, .22), 0 28px 30px -22px rgba(25, 28, 26, .28);
  rotate: var(--r);
  transform-origin: 50% 0;        /* hangs from the clip */
  /* individual properties, NOT transform: transform belongs to the drag layer */
  transition: rotate .45s var(--ease), translate .45s var(--ease), box-shadow .45s var(--ease);
}
/* The holder photo lies over the card like the pocket's front sheet: the flap, slot and zip on top, thin
   sealed edges down the sides and along the bottom, and a clear pocket in the middle.
   It is drawn from four plain background images (not border-image): Safari drops border-image frames while
   the card tilts and the Greenhouse tile animates on hover, which made the frame vanish. */
.id-card::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  --side-h: calc(100% - var(--hb-top) - var(--hb-edge));
  background:
    url("../../images/badge/holder-top.png")    0 0       / 100% var(--hb-top)            no-repeat,
    url("../../images/badge/holder-bottom.png") 0 100%    / 100% var(--hb-edge)           no-repeat,
    url("../../images/badge/holder-left.png")   0 var(--hb-top)    / var(--hb-edge) var(--side-h) no-repeat,
    url("../../images/badge/holder-right.png")  100% var(--hb-top) / var(--hb-edge) var(--side-h) no-repeat;
  transform: translateZ(0);            /* its own layer, so it is never repainted half-way through a hover */
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
}
.id-card:hover { rotate: calc(var(--r) * .35); translate: 0 -4px; box-shadow: 0 2px 3px rgba(0, 0, 0, .1), 0 16px 16px -10px rgba(25, 28, 26, .2), 0 38px 40px -24px rgba(25, 28, 26, .3); }
.id-slot.is-dragging .id-card { rotate: var(--r); translate: 0 0; box-shadow: 0 3px 4px rgba(0, 0, 0, .1), 0 20px 20px -12px rgba(25, 28, 26, .2), 0 46px 50px -26px rgba(25, 28, 26, .34); transition: rotate .3s var(--ease), translate .3s var(--ease), box-shadow .2s; }   /* the drag itself is on .id-slot, so easing the tilt here can't lag behind the pointer; it used to snap */
.id-card:focus-within { outline: 2px solid var(--accent); outline-offset: 4px; }
.id-card:has(:focus-visible) { outline: 2px solid var(--accent); outline-offset: 4px; }
.id-card:focus-within:not(:has(:focus-visible)) { outline: none; }

/* the top flap (painted by the holder photo); this element is just the touch handle */
.id-card__head { position: relative; height: var(--head-h); }

/* the card sits in the pocket, just below the zip */
.id-card__link { display: block; padding: calc(var(--hb-top) - var(--head-h) + 2cqw) 4.2cqw 4.2cqw; color: inherit; text-decoration: none; -webkit-user-drag: none; }
.id-card__link:focus-visible { outline: none; }
/* The card inside the pocket: printed edge to edge like a real plastic card (rounded corners, no white
   border), the company artwork on top and a strip in the company's colour along the bottom with the name
   and year. A hairline edge and a soft shadow show through the clear plastic. */
.id-card__body {
  position: relative;
  isolation: isolate;                 /* its own layer: the rounded clip and the photo repaint together */
  transform: translateZ(0);
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
  border-radius: 3.6cqw;
  overflow: hidden;
  background: var(--brand);
  box-shadow: 0 0 0 .5px rgba(0, 0, 0, .3), 0 1px 2px rgba(0, 0, 0, .14), 0 8px 12px -8px rgba(0, 0, 0, .3);
}
.id-card__window .media { aspect-ratio: 1050 / 750; }
.id-card__window .media img { -webkit-user-drag: none; user-select: none; transition: none; transform: none; }
.id-card__foot {
  display: flex; justify-content: space-between; align-items: baseline; gap: .25rem .75rem; flex-wrap: wrap;
  padding: 3.4cqw 4.6cqw 3.8cqw;
  color: #fff;
}
.id-card__title {
  font-size: clamp(.95rem, .85rem + .3vw, 1.1rem);
  font-weight: 560; font-stretch: 104%; letter-spacing: -0.01em;
}
.id-card__year { color: rgba(255, 255, 255, .78); font-size: var(--fs-small); font-variant-numeric: tabular-nums; white-space: nowrap; }
.id-card__foot .tag { border-color: rgba(255, 255, 255, .45); color: #fff; }
/* (no photo zoom on card hover: it flickered against the card's own tilt and lift) */

/* ---- lanyard attachment: black strap tab, metal ring and pin into the slot ----
   Everything here ignores the mouse, so it can never get in the way of dragging. */
.lanyard-attachment { position: absolute; left: 50%; pointer-events: none; }
.lanyard-attachment--top { top: 0; width: 0; height: 0; z-index: 2; }
/* Charms: drop an <img> or <svg> into any .charms-container.
   Top: sits to the right of the clip. Bottom: hangs below the card, centred.
   position:absolute + flex means adding charms never changes the card's layout. */
.charms-container {
  position: absolute; display: flex; align-items: flex-start; gap: .35rem;
  pointer-events: none;
}
.lanyard-attachment--top .charms-container { left: 1.9rem; top: -2.9rem; }
.lanyard-attachment--bottom { bottom: 0; width: 0; height: 0; z-index: 0; }
.lanyard-attachment--bottom .charms-container { top: 100%; left: 0; transform: translateX(-50%); padding-top: .25rem; }
.charms-container > * { max-height: 2.2rem; width: auto; flex: none; }

/* ---- Charms ----
   A charm is a child of the card's top attachment, so dragging the card carries it along; the
   container ignores the mouse so it can never intercept a drag or a click. Each charm hangs from a
   pivot (its jump ring or snap hook, set in --pivot-x / --pivot-y as a % of the charm's own box) and
   main.js swings it about that point with a spring-damper model (see CHARM_PHYSICS at the top of
   main.js). The CSS only sets size, pivot, and shadow. */
.lanyard-attachment--top .charms-container:has(.card-charm) { left: 0; top: -1.1rem; }
.card-charm {
  position: absolute;
  top: 0;
  max-height: none;
  height: auto;
  --swing: 0deg;                                /* written by main.js every frame */
  --sway-x: 0px;
  --pivot-x: 50%; --pivot-y: 5%;
  transform-origin: var(--pivot-x) var(--pivot-y);
  rotate: var(--swing);
  translate: var(--sway-x) 0;
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .18));   /* one soft shadow for the whole cluster */
  will-change: rotate, translate;
}
.card-charm svg { display: block; width: 100%; height: 100%; overflow: visible; }

/* Charm placement. Each charm starts with a silver key ring that loops around the top of the badge's
   vinyl strap just above the card's slot (left = -half the charm's width, `top` lifts the ring round the strap). Everything else (strap, chains, charm)
   hangs down from that one ring. --pivot-x / --pivot-y mark the ring, which main.js swings about. */
.ibm-bee-charm {
  width: 5.6rem; aspect-ratio: 134 / 142;
  left: -2.8rem; top: -.88rem;
  --pivot-x: 50%; --pivot-y: 15%;
}
.greenhouse-charms {
  width: 6.64rem; aspect-ratio: 158.8 / 191.8;          /* same scale as the bee (134 units = 5.6rem), so the white border is the same thickness */
  left: -3.32rem; top: -.88rem;                 /* the key ring is the SVG's centre line, on the badge's clip strap */
  --pivot-x: 50%; --pivot-y: 11.0%;
}

/* No JS / reduced motion: the charms simply hang still, with a small natural tilt */
@media (prefers-reduced-motion: reduce) { .card-charm { rotate: 2deg; } .id-card { transition: none; } }

.tag {
  margin-left: .4rem;
  padding: .1rem .5rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  color: var(--ink);
  font-size: .75rem;
}

/* Greenhouse "Peek" tile: a base image plus produce pieces positioned in % of the postcard.
   main.js nudges the pieces just outside their spots and springs them in on hover. */
.peek .peek__item {
  inset: auto;
  height: auto;
  object-fit: fill;
  transition: none;
  transform-origin: 50% 50%;
  will-change: transform;
  pointer-events: none;
}

/* ---------- Media + placeholders ---------- */
.media {
  position: relative;
  overflow: hidden;
  background: var(--tint-sage);
}
.media[data-tint="lilac"] { background: var(--tint-lilac); }
.media[data-tint="sand"]  { background: var(--tint-sand); }
.media[data-tint="sky"]   { background: var(--tint-sky); }
.media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .8s var(--ease);
}
.media__ph {
  position: absolute; left: 1rem; bottom: .85rem;
  font-size: .8125rem;
  color: rgba(25, 28, 26, .5);
}
.media.is-empty img { display: none; }
.media:not(.is-empty) .media__ph { display: none; }

/* ---------- Polaroid (shared frame) ---------- */
.polaroid {
  background: var(--white);
  padding: .7rem .7rem 0;
  box-shadow: 0 1px 2px rgba(25, 28, 26, .08), 0 8px 24px -12px rgba(25, 28, 26, .25);
  /* rotate/translate are separate from transform so the load-in animation can't flatten them */
  rotate: var(--r, 0deg);
  transition: rotate .45s var(--ease), translate .45s var(--ease), box-shadow .45s var(--ease);
}
.polaroid:hover {
  rotate: 0deg;
  translate: 0 -6px;
  box-shadow: 0 2px 4px rgba(25, 28, 26, .08), 0 18px 36px -16px rgba(25, 28, 26, .3);
}
/* Hover bridge: a card that lifts on hover moves its bottom edge away from a pointer resting there, which
   un-hovers it, so it drops back under the pointer and lifts again (a flicker). This invisible strip under the
   lifted card keeps the pointer "on" it. */
:is(.polaroid, .id-card, .cs-steps li, .cs-bigstats .cs-bigstat):hover::after {
  content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 10px;
}
.polaroid:not([data-sticky]) { position: relative; }
.polaroid .media { aspect-ratio: 1 / 1; }
.polaroid__cap {
  padding: .55rem .25rem .8rem;
  font-family: "Hand", "Archivo", cursive;   /* the same handwriting as the About polaroids */
  font-size: 1.3rem;
  color: var(--graphite);                    /* same grey as the About polaroids */
  line-height: 1.15;
  text-align: center;
}

/* ---------- About me ---------- */
.about { padding-bottom: var(--section); overflow: hidden; }
.about__title {
  font-size: clamp(1.875rem, 1.5rem + 2vw, 2.75rem);
  font-weight: 560;
  font-stretch: 104%;
  letter-spacing: -0.015em;
  line-height: 1.1;
  margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem);
}
.about__tags {
  display: flex; flex-wrap: nowrap; align-items: center;
  gap: clamp(1rem, 2.5vw, 1.5rem);
  margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem);
  list-style: none; padding: 0;
}
.about__tags li {
  display: flex; align-items: center; gap: .4rem;
  color: var(--graphite);
  font-size: clamp(.9375rem, .9rem + .2vw, 1rem);
  white-space: nowrap;
}
.about__tags svg {
  width: 1rem; height: 1rem;
  flex-shrink: 0;
  fill: var(--graphite); stroke: none;
}
@media (max-width: 560px) {
  .about__tags { flex-wrap: wrap; }
  .about__tags li { white-space: normal; }
}
/* The About text lines up with the cards above it: it starts at the middle of the RBC card and ends at the
   middle of the IBM card (the cards are three equal columns with a gap, so that is 1/6 of the row, minus a bit
   of the gap, in from each side). The lines inside stay left-aligned. */
:root { --work-gap: clamp(1.25rem, 3vw, 3rem); }
.work__grid { gap: var(--work-gap); }
.about > .wrap > * { text-align: left; }
@media (min-width: 721px) {
  .about > .wrap > * {
    margin-left: calc((100% - 2 * var(--work-gap)) / 6);
    width: calc((2 * 100% + 2 * var(--work-gap)) / 3);
    max-width: none;
  }
}
.about__bio p {
  font-size: clamp(1.0625rem, 1rem + .35vw, 1.25rem);
  line-height: 1.6;
  text-wrap: pretty;                                      /* no stranded single words at line ends */
}
.about__bio p + p { margin-top: 1.1em; }

/* Hanging polaroids: cards clipped to a sagging string. main.js moves them
   along the string in an endless loop (auto drift + drag, swipe, trackpad,
   arrow keys) and lets them sway. */
.hang {
  --cw: clamp(132px, 14vw, 208px);           /* card width */
  position: relative;
  margin-top: clamp(2rem, 4vw, 3.5rem);
  height: calc(var(--cw) * 1.45 + 5.5rem);
  cursor: grab;
  touch-action: pan-y;                       /* vertical swipes still scroll the page */
  user-select: none; -webkit-user-select: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.hang.is-dragging { cursor: grabbing; }
.hang:focus-visible { outline-offset: -4px; }
.hang__string {
  position: absolute; inset: 0;
  z-index: 0;                                /* always behind the cards, so it reads as going under them */
  width: 100%; height: 100%;
  overflow: visible;
  pointer-events: none;
}
.hang__string path { fill: none; stroke: #8A8F8A; stroke-width: 1.25; }
.hang__track { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; }
.hang__card {
  position: absolute; left: 0; top: 0;
  z-index: 1;                                 /* paint over the string, not under it */
  width: var(--cw);
  transform-origin: 50% 0;                   /* swings from the pin */
  will-change: transform;
}
.hang__frame {
  margin-top: 6px;
  background: var(--white);
  padding: calc(var(--cw) * .055) calc(var(--cw) * .055) 0;
  box-shadow: 0 2px 3px rgba(25, 28, 26, .08), 0 14px 26px -14px rgba(25, 28, 26, .35);
  text-align: center;
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.hang__card:hover .hang__frame {
  transform: translateY(3px) scale(1.03);
  box-shadow: 0 3px 5px rgba(25, 28, 26, .1), 0 22px 36px -16px rgba(25, 28, 26, .4);
}
.hang__frame .media { aspect-ratio: 1 / 1.02; }
.hang__frame img { pointer-events: none; }
/* wooden clothespin (assets/clothespin.png): clipped over the string and the polaroid's top edge.
   Height scales with the card; the width follows the image's 191:635 ratio. */
.hang__pin {
  --pin-h: calc(var(--cw) * .27);
  position: absolute; z-index: 2;
  left: 50%; top: calc(var(--pin-h) * -.4);   /* ~40% of it above the string/edge, the rest clamped over the frame */
  height: var(--pin-h);
  aspect-ratio: 191 / 635;
  transform: translateX(-50%) rotate(2deg);
  background: url("../clothespin.png") center / 100% 100% no-repeat;
  filter: drop-shadow(0 2px 2px rgba(25, 28, 26, .28)) drop-shadow(0 5px 5px rgba(25, 28, 26, .14));
  pointer-events: none;
}
.hang__hand {
  font-family: "Hand", "Archivo", cursive;
  font-size: clamp(.875rem, calc(var(--cw) * .085), 1.3rem);
  line-height: 1.1;
  padding: .6rem .25rem .85rem;
}

/* Without JS: a simple scrollable row */
.hang:not(.is-ready) { height: auto; aspect-ratio: auto; min-height: 0; cursor: auto; -webkit-mask-image: none; mask-image: none; }
.hang:not(.is-ready) .hang__string { display: none; }
.hang:not(.is-ready) .hang__track {
  position: static; display: flex; gap: 1.5rem; overflow-x: auto;
  padding: 1.5rem var(--gutter) 2rem;
}
.hang:not(.is-ready) .hang__card { position: relative; flex: none; }

/* ---------- Playground page ---------- */
.page-hero {
  padding-top: clamp(3.5rem, 8vw, 6.5rem);
  padding-bottom: clamp(2.5rem, 4.5vw, 3.75rem);
}
.page-hero .hero__proof { margin-top: clamp(.75rem, 1.5vw, 1.25rem); }
.playground { padding-bottom: var(--section); }

/* Pinterest-style masonry. Grid columns; main.js gives each piece a row span
   that matches its height, so pieces pack tightly left to right.
   (CSS "columns" was avoided because Safari lays it out differently.) */
.pins {
  --pin-gap: 1rem;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--pin-gap);
  align-items: start;
}
.pins.is-masonry { grid-auto-rows: 4px; row-gap: 0; }
.pin { position: relative; }
.pin .media {
  border-radius: 16px;
  aspect-ratio: var(--ar, 3 / 4);           /* placeholder shape until a real image loads */
  isolation: isolate;                       /* keeps rounded corners clipping in Safari */
}
.pin .media.is-loaded { aspect-ratio: auto; }
.pin .media img { position: static; height: auto; transition: transform .6s var(--ease); }
.pin .media.is-empty img { display: none; }
.pin:hover .media img { transform: scale(1.02); }

/* ---- Movable playground ----
   Every piece (and the cat) can be dragged anywhere on the page, brought to the front, and sent away with
   the x that appears on hover. main.js saves the arrangement in localStorage; "Put everything back" resets it. */
[data-play] { position: relative; }
.play-hint { margin-top: .9rem; font-size: var(--fs-small); color: var(--graphite); }
.play-reset {
  margin-left: .6rem; padding: .2rem .7rem; border: 1px solid var(--rule); border-radius: 999px;
  background: rgba(255, 255, 255, .7); color: var(--ink); font: inherit; cursor: pointer;
}
.play-reset:hover { background: #fff; border-color: var(--graphite); }
.play-reset[hidden] { display: none; }

[data-play-item] {
  cursor: grab;
  touch-action: pan-y;                      /* touch screens keep scrolling; dragging is for mouse and pen */
  -webkit-user-select: none; user-select: none;
  will-change: transform;
  transition: filter .25s;
}
@media (pointer: fine) { [data-play-item] { touch-action: none; } }
[data-play-item].is-dragging { cursor: grabbing; filter: drop-shadow(0 18px 22px rgba(25, 28, 26, .28)); }
[data-play-item].is-dragging .media img { transform: none; }
[data-play-item] img { -webkit-user-drag: none; pointer-events: none; }
/* leaving: flick away, then out of the layout */
[data-play-item].is-leaving { transition: transform .45s cubic-bezier(.5, -0.2, .8, .5), opacity .35s; opacity: 0; pointer-events: none; }
.pin[data-play-item].is-gone { display: none; }

.pin__x {
  position: absolute; z-index: 3; top: .5rem; right: .5rem;
  width: 1.7rem; height: 1.7rem; padding: 0; border: 0; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, .92); color: var(--ink); cursor: pointer;
  box-shadow: 0 2px 8px rgba(25, 28, 26, .25);
  opacity: 0; transform: scale(.8); transition: opacity .2s, transform .2s;
}
.pin__x svg { width: .7rem; height: .7rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.pin:hover .pin__x, .pin:focus-within .pin__x { opacity: 1; transform: none; }
.pin__x:hover { background: #fff; }
@media (hover: none) { .pin__x { opacity: 1; transform: none; } }

.play-cat {
  position: absolute; z-index: 6; right: clamp(1rem, 8vw, 9rem); top: clamp(2rem, 7vw, 5.5rem);
  padding: 0; border: 0; background: none; line-height: 0;
}
.play-cat img { width: 78px; height: 72px; image-rendering: pixelated; }
.play-cat:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; border-radius: 6px; }
@media (max-width: 720px) { .play-cat { right: 1rem; top: 1.25rem; } .play-cat img { width: 56px; height: 52px; } }

/* caption only appears on hover (still read by screen readers) */
.pin__cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .1rem .5rem;
  padding: 2.5rem 1rem .9rem;
  border-radius: 0 0 16px 16px;
  background: linear-gradient(transparent, rgba(25, 28, 26, .55));
  color: var(--white);
  font-size: var(--fs-small);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .25s, transform .35s var(--ease);
  pointer-events: none;
}
.pin:hover .pin__cap,
.pin:focus-within .pin__cap { opacity: 1; transform: none; }
.pin__name { font-weight: 400; }
.pin__meta { opacity: .8; }

/* ---------- Playground, tidbits-board look ----------
   The pieces sit in a soft bordered board: three wide columns, big rounded tiles, thin even gaps, no captions
   until hover. The site header and nav above are unchanged. */
.playground .pins {
  --pin-gap: clamp(.6rem, 1.2vw, 1rem);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding: clamp(.6rem, 1.2vw, 1rem);
  background: #FBFBF9;
  border: 1px solid var(--rule);
  border-radius: clamp(18px, 2.4vw, 28px);
  box-shadow: 0 1px 2px rgba(25, 28, 26, .04), 0 24px 48px -32px rgba(25, 28, 26, .18);
}
.playground .pin .media {
  border-radius: clamp(12px, 1.6vw, 18px);
  box-shadow: 0 0 0 1px rgba(25, 28, 26, .06);
}
.playground .pin .media video { display: block; width: 100%; height: auto; }
.playground .pin__video { background: #101512; }
.playground .pin__cap { border-radius: 0 0 clamp(12px, 1.6vw, 18px) clamp(12px, 1.6vw, 18px); }
.page-hero { padding-bottom: clamp(1.75rem, 3vw, 2.5rem); }

/* Playground as a fixed bento: no title block, a wide board that nearly fills the window, tiles stay put. */
.playground { max-width: 1800px; margin-inline: auto; padding: clamp(5.5rem, 8vw, 7rem) clamp(.5rem, 1.2vw, 1rem) var(--section); }
.page-hero { padding: 0; }
.playground .pin { cursor: default; }

@media (max-width: 720px) { .playground .pins { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---------- Playground lightbox ---------- */
/* the hover caption is replaced by the zoom view's caption; every tile is one big click target */
.playground .pin__cap { display: none; }
.pin__open { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; padding: 0; border: 0; border-radius: clamp(12px, 1.6vw, 18px); background: transparent; cursor: zoom-in; -webkit-tap-highlight-color: transparent; }
.pin__open[hidden] { display: none; }
.pin__open:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.lb { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; color: var(--ink);
  background: rgba(244, 245, 241, .74); -webkit-backdrop-filter: blur(22px) saturate(1.1); backdrop-filter: blur(22px) saturate(1.1);
  overflow: hidden; }
.lb::backdrop { background: transparent; }
.lb[open] { display: flex; flex-direction: column; align-items: center; justify-content: center; animation: lb-in .32s var(--ease) both; }
.lb.is-closing { animation: lb-out .38s var(--ease) both; }
@keyframes lb-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes lb-out { to { opacity: 0; } }
html.lb-open { overflow: hidden; }

.lb__fig { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 1rem; max-width: 100%; }
.lb__stage { display: grid; place-items: center; }
.lb__media { display: block; max-width: none; background: #fff; border-radius: 22px; object-fit: contain;
  box-shadow: 0 1px 2px rgba(25, 28, 26, .08), 0 40px 80px -30px rgba(25, 28, 26, .35); }
.lb__cap { max-width: min(46rem, 90vw); text-align: center; font-size: var(--fs-body); line-height: 1.4; color: var(--graphite); text-wrap: balance; }
.lb__cap[hidden] { display: none; }
.lb__name { color: var(--ink); font-weight: 400; }

.lb__bar { position: absolute; top: clamp(.75rem, 2vw, 1.25rem); right: clamp(.75rem, 2vw, 1.5rem); display: flex; gap: .5rem; z-index: 3; }
.lb__nav { position: absolute; left: 0; right: 0; bottom: clamp(.75rem, 2.5vw, 1.5rem); display: flex; justify-content: center; gap: .75rem; z-index: 3; }
.lb__nav[hidden] { display: none; }
.lb__btn { display: grid; place-items: center; width: 2.6rem; height: 2.6rem; padding: 0; border: 1px solid var(--rule); border-radius: 50%;
  background: rgba(255, 255, 255, .8); color: var(--ink); cursor: pointer; text-decoration: none; transition: background .2s, transform .2s; }
.lb__btn:hover { background: #fff; transform: scale(1.06); }
.lb__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.lb__btn svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
@media (max-width: 720px) { .lb__media { border-radius: 14px; } .lb__btn { width: 2.9rem; height: 2.9rem; } }
@media (prefers-reduced-motion: reduce) { .lb[open], .lb.is-closing { animation: none; } .lb__btn { transition: none; } }

/* ---------- Footer ---------- */
.site-footer {
  padding-top: clamp(3rem, 6vw, 5rem);
  padding-bottom: 2rem;
  /* rule inset to the content width, matching section dividers */
  background: linear-gradient(var(--rule), var(--rule)) no-repeat center top / calc(100% - 2 * var(--gutter)) 1px;
}
.footer__ask { color: var(--graphite); }
.footer__email {
  display: inline-block;
  margin-top: .5rem;
  font-size: var(--fs-email);
  font-weight: 430;
  font-stretch: 106%;
  letter-spacing: -0.028em;
  line-height: 1.1;
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: color .2s;
}
.footer__email:hover { color: var(--accent); }
.footer__row {
  margin-top: clamp(3rem, 7vw, 6rem);
  display: flex; justify-content: space-between; align-items: flex-end; gap: 1.5rem; flex-wrap: wrap;
  font-size: var(--fs-small);
}
.footer__links { display: flex; gap: 1.75rem; }
.footer__note { display: flex; align-items: center; gap: .75rem; color: var(--graphite); }

/* pixel cat: blinks when hovered */
.cat { width: 33px; height: 27px; flex: none; }
.cat rect { fill: var(--ink); }
.cat .eye { fill: var(--paper); transition: fill .08s; }
.cat .nose { fill: var(--accent); }
.cat:hover .eye { animation: blink .5s steps(1) 1; }
@keyframes blink { 0%, 60% { fill: var(--ink); } 61%, 100% { fill: var(--paper); } }

/* ==========================================================
   Case studies (work/*.html), full page and inside the popup
   ========================================================== */
.cs { --sticky-top: 6rem; padding-top: clamp(2rem, 5vw, 4rem); padding-bottom: var(--section); }
html.in-modal .cs { --sticky-top: 1.5rem; padding-top: 2.25rem; }
html.in-modal .site-header,
html.in-modal .site-footer,
html.in-modal .cs-back { display: none; }

.cs__layout {
  display: grid;
  grid-template-columns: 12rem minmax(0, 1fr);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: start;
}
.cs__main { max-width: 50rem; min-width: 0; }

.cs-back {
  display: inline-block;
  margin-bottom: 2.5rem;
  color: var(--graphite);
  font-size: var(--fs-small);
  text-decoration: none;
}
.cs-back:hover { color: var(--accent); }

/* side nav: sticky, highlights the section you're reading */
.cs-nav { position: sticky; top: var(--sticky-top); }
.cs-nav__title { font-size: var(--fs-small); font-weight: 560; margin-bottom: .75rem; }
.cs-nav ol { list-style: none; margin: 0; padding: 0; }
.cs-nav a {
  display: block;
  padding: .3rem 0 .3rem .85rem;
  border-left: 2px solid var(--rule);
  color: var(--graphite);
  font-size: var(--fs-small);
  text-decoration: none;
  transition: color .2s, border-color .2s;
}
.cs-nav a:hover { color: var(--ink); }
.cs-nav a.is-active { color: var(--ink); border-left-color: var(--accent); }

/* header block */
.cs-head__kicker { color: var(--graphite); }
/* optional polaroid beside the title (e.g. IBM: "come back later" note while the
   case study is still in progress) — same tilt/hover frame as the About me photos */
.cs-head__top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--col-gap);
}
.cs-head__polaroid {
  --r: -3deg;
  width: clamp(8rem, 14vw, 11rem);
  margin-top: .25rem;
}
.cs-head__polaroid .media { aspect-ratio: 1 / 1; }
@media (max-width: 560px) {
  .cs-head__top { grid-template-columns: minmax(0, 1fr); }
  .cs-head__polaroid { width: 7.5rem; justify-self: start; }
}
.cs-head__title {
  margin-top: .5rem;
  font-size: clamp(2rem, 1.2rem + 3vw, 3.5rem);
  font-weight: 430;
  font-stretch: 106%;
  line-height: 1.05;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.cs-head__summary {
  margin-top: 1.25rem;
  font-size: clamp(1.0625rem, 1rem + .35vw, 1.25rem);
  color: var(--graphite);
  max-width: 44rem;
}
.cs-meta {
  margin-top: 2rem;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem var(--col-gap);
  padding-block: 1.25rem;
  border-block: 1px solid var(--rule);
}
/* labels read as a code comment (same monospace treatment as the tl;dr role
   line below); values are bolder and a touch bigger so they carry the row
   (reference: rebecca-yang.com's meta row) */
.cs-meta dt {
  color: var(--graphite);
  font-family: "SF Mono", "Menlo", "Consolas", monospace;
  font-size: var(--fs-small);
  text-transform: lowercase;
}
.cs-meta dd { font-size: 1rem; font-weight: 600; margin-top: .3rem; }
.cs-outcome {
  margin-top: 1.25rem;
  display: flex; gap: .6rem; align-items: baseline;
  font-size: var(--fs-small);
}

/* sections */
.cs-section { padding-top: clamp(3.5rem, 7vw, 5.5rem); scroll-margin-top: var(--sticky-top); }
.cs-section h2 {
  font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
  font-weight: 500;
  font-stretch: 104%;
  letter-spacing: -0.015em;
  padding-bottom: 1rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--rule);
}
.cs-section h3 { font-size: var(--fs-h3); font-weight: 560; margin-top: 2.25rem; margin-bottom: .5rem; }
.cs-section p { max-width: 40rem; }
.cs-section p + p { margin-top: 1em; }
.cs-section ul.cs-list { list-style: disc; padding-left: 1.2rem; max-width: 40rem; }
.cs-section ul.cs-list li + li { margin-top: .4rem; }

.cs-fig { margin-top: 2rem; }
.cs-fig .media { aspect-ratio: 16 / 10; }
.cs-fig figcaption { margin-top: .6rem; color: var(--graphite); font-size: var(--fs-small); }
.cs-fig-pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--col-gap); }
.cs-fig-pair .media { aspect-ratio: 4 / 3; }

.cs-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem var(--col-gap);
  margin-top: 1.75rem;
}
.cs-stat { padding-left: 1rem; border-left: 2px solid var(--rule); }
.cs-stat strong {
  display: block;
  font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem);
  font-weight: 460;
  font-stretch: 106%;
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.cs-stat span { color: var(--graphite); font-size: var(--fs-small); }

.cs-quote {
  margin: 2rem 0 0;
  padding-left: 1.25rem;
  border-left: 2px solid var(--accent);
  font-size: clamp(1.125rem, 1rem + .5vw, 1.375rem);
  font-stretch: 104%;
  max-width: 40rem;
}

/* bits of copy still to be written: visible on purpose so they're easy to find */
.todo {
  background: #FBEAF1;
  box-shadow: 0 0 0 2px #FBEAF1;
  border-radius: 2px;
  color: #9A2456;
}

/* also check out */
.cs-next { padding-top: clamp(4rem, 8vw, 6.5rem); }
.cs-next__title { color: var(--graphite); font-size: var(--fs-h3); margin-bottom: 1.5rem; }
.cs-next__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--col-gap); }
.cs-next__card { display: block; text-decoration: none; }
.cs-next__card .media { aspect-ratio: 16 / 10; }
.cs-next__card:hover .media img { transform: scale(1.025); }
.cs-next__name { margin-top: .75rem; font-weight: 560; font-stretch: 104%; }
.cs-next__name span { color: var(--graphite); font-weight: 400; margin-left: .4rem; }

@media (max-width: 900px) {
  .cs__layout { grid-template-columns: minmax(0, 1fr); gap: 0; }
  /* side nav turns into a sticky, scrollable row of section chips */
  .cs-nav {
    top: 4.5rem;                /* sits right under the sticky site header */
    z-index: 5;
    margin: 0 calc(var(--gutter) * -1) 1.5rem;
    padding: .6rem var(--gutter);
    background: rgba(244, 245, 241, .92);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--rule);
  }
  html.in-modal .cs-nav { top: 0; }
  .cs-nav__title { display: none; }
  .cs-nav ol { display: flex; gap: .4rem; overflow-x: auto; scrollbar-width: none; }
  .cs-nav ol::-webkit-scrollbar { display: none; }
  .cs-nav a {
    white-space: nowrap;
    border: 1px solid var(--rule);
    border-radius: 999px;
    padding: .3rem .75rem;
  }
  .cs-nav a.is-active { border-color: var(--ink); background: var(--ink); color: var(--paper); }
  .cs-meta { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .cs-fig-pair, .cs-stats, .cs-next__grid { grid-template-columns: 1fr; }
}

/* ---------- Story layout (Greenhouse case study) ----------
   Numbered section headers in the project's accent colour, two-column
   intros (label left, text right), big rounded images with centred
   captions, and tinted feature bands. Set --cs-accent / --cs-accent-soft /
   --cs-band on <main> to theme a case study. */
.cs--story { --cs-radius: clamp(14px, 1.6vw, 22px); }
.cs--story .cs__main { max-width: 58rem; }

.cs--story .cs-sec-head {
  display: flex; align-items: baseline; gap: .9rem;
  padding-bottom: 1rem; margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
  border-bottom: 1px solid var(--rule);
}
.cs--story .cs-sec-num {
  color: var(--cs-accent-soft);
  font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
  font-variant-numeric: tabular-nums;
  font-stretch: 104%;
}
.cs--story .cs-sec-head h2 {
  margin: 0; padding: 0; border: 0;
  color: var(--cs-accent);
  font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
}

/* two-column intro: label left, text right */
.cs--story .cs-two {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--col-gap);
  align-items: start;
}
.cs--story .cs-two + .cs-two { margin-top: clamp(1.75rem, 3vw, 2.5rem); }
.cs--story .cs-two h3 {
  margin: 0;
  color: var(--graphite);
  font-size: .75rem;
  font-weight: 560;
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1.3;
}
.cs--story .cs-two__body p,
.cs--story .cs-two__body .cs-list { max-width: none; color: var(--graphite); }

/* TL;DR card: a quick-read summary band right under the meta row — role on
   top, then a couple of big headline numbers with a caption each (reference:
   rebecca-yang.com). Monospace label to read as a code comment / aside. */
.cs--story .cs-tldr {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding: clamp(1.5rem, 4vw, 2.25rem) clamp(1.5rem, 4vw, 2.5rem);
  background: var(--cs-band);
  border-radius: var(--cs-radius);
}
.cs--story .cs-tldr__role {
  font-family: "SF Mono", "Menlo", "Consolas", monospace;
  font-size: clamp(.9rem, .85rem + .2vw, 1rem);
  color: var(--graphite);
}
.cs--story .cs-tldr__role strong { color: var(--ink); font-weight: 600; }
.cs--story .cs-tldr__stats {
  margin-top: clamp(1.25rem, 3vw, 1.75rem);
  padding-top: clamp(1.25rem, 3vw, 1.75rem);
  border-top: 1px solid var(--rule);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 4vw, 2.5rem);
}
.cs--story .cs-tldr__stat {
  padding-left: clamp(1.5rem, 4vw, 2.5rem);
  border-left: 1px solid var(--rule);
}
.cs--story .cs-tldr__stat:first-child { padding-left: 0; border-left: none; }
.cs--story .cs-tldr__num {
  display: block;
  font-size: clamp(2rem, 1.4rem + 2.5vw, 2.75rem);
  font-weight: 450; font-stretch: 106%; letter-spacing: -0.02em;
  line-height: 1;
  color: var(--ink);
}
.cs--story .cs-tldr__cap {
  display: block;
  margin-top: .5rem;
  color: var(--graphite);
  font-size: clamp(.9375rem, .9rem + .2vw, 1.0625rem);
  line-height: 1.4;
}
@media (max-width: 560px) {
  .cs--story .cs-tldr__stats { grid-template-columns: 1fr; gap: 1.25rem; }
  .cs--story .cs-tldr__stat { padding-left: 0; border-left: none; }
}

/* images: rounded, captions centred */
.cs--story .cs-hero { margin-top: clamp(2rem, 4vw, 3rem); }
.cs--story .cs-hero .media { aspect-ratio: 1050 / 750; border-radius: var(--cs-radius); }
.cs--story .cs-fig { margin-top: clamp(2rem, 4vw, 3rem); }
.cs--story .cs-fig .media,
.cs--story .cs-pair .media,
.cs--story .cs-band__media .media { border-radius: var(--cs-radius); }
.cs--story figcaption {
  margin-top: .75rem;
  text-align: center;
  color: var(--graphite);
  font-size: var(--fs-small);
}
.cs--story .cs-pair {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--col-gap);
}
.cs--story .cs-pair .media { aspect-ratio: 4 / 3; }

/* tinted feature band: small image left, text right */
.cs--story .cs-band {
  margin-top: clamp(2rem, 4vw, 3rem);
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: center;
  padding: clamp(1.25rem, 3vw, 2.5rem);
  background: var(--cs-band);
  border-radius: var(--cs-radius);
}
.cs--story .cs-band__media { margin: 0; }
.cs--story .cs-band__media .media { aspect-ratio: 4 / 3; }
.cs--story .cs-eyebrow {
  color: var(--graphite);
  font-size: .75rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.cs--story .cs-band h3 {
  margin: .4rem 0 .75rem;
  font-size: clamp(1.25rem, 1.05rem + .7vw, 1.5rem);
  font-weight: 450;
  font-stretch: 104%;
  line-height: 1.25;
}
.cs--story .cs-band p, .cs--story .cs-band .cs-list { color: var(--graphite); max-width: none; }

/* stats and quote pick up the accent */
.cs--story .cs-stats { margin-top: clamp(1.75rem, 3vw, 2.5rem); }
.cs--story .cs-stat { border-left-color: var(--cs-accent-soft); }
.cs--story .cs-stat strong { color: var(--cs-accent); }
.cs--story .cs-quote { border-left-color: var(--cs-accent); margin-top: clamp(1.75rem, 3vw, 2.5rem); }

.cs--story .cs-next__card .media { border-radius: var(--cs-radius); }

/* Introduction: a row of internship photos, a welcome note, then project cards */
.cs--story .cs-photos {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(.6rem, 1.5vw, 1rem);
}
.cs--story .cs-photos figure { margin: 0; }
.cs--story .cs-photos .media { aspect-ratio: 1 / 1; border-radius: calc(var(--cs-radius) * .7); }
.cs--story .cs-intro {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  max-width: 44rem;
  font-size: clamp(1.0625rem, 1rem + .4vw, 1.3rem);
  line-height: 1.5;
}
.cs--story .cs-projects {
  margin-top: clamp(2rem, 4vw, 3rem);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--col-gap);
}
.cs--story .cs-project { display: block; text-decoration: none; }
.cs--story .cs-project .media { aspect-ratio: 4 / 3; border-radius: var(--cs-radius); }
.cs--story .cs-project:hover .media img { transform: scale(1.025); }
.cs--story .cs-project p { margin-top: .7rem; font-weight: 560; font-stretch: 104%; }
.cs--story .cs-project p span { color: var(--cs-accent-soft); margin-right: .35rem; font-variant-numeric: tabular-nums; }
.cs--story .cs-project:hover p { color: var(--cs-accent); }

/* animated hero (same Peek postcard as the home page) */
.cs--story .cs-hero .media.peek { aspect-ratio: 1050 / 750; }

/* reflections + testimonials */
.cs--story .cs-testimonials {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--col-gap);
}
.cs--story .cs-testimonial {
  margin: 0;
  padding: clamp(1.1rem, 2.4vw, 1.75rem);
  background: var(--cs-band);
  border-radius: var(--cs-radius);
}
.cs--story .cs-testimonial blockquote { margin: 0; font-size: 1.0625rem; line-height: 1.5; }
.cs--story .cs-testimonial figcaption { margin-top: .9rem; text-align: left; }

/* Design libraries section */
.cs--story .cs-two + .cs-fig,
.cs--story .cs-two + .cs-methods,
.cs--story .cs-two + .cs-trio,
.cs--story .cs-two + .cs-finals,
.cs--story .cs-two + .cs-stats,
.cs--story .cs-two + .cs-testimonies { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); }
.cs--story .cs-methods + .cs-two,
.cs--story .cs-trio + .cs-two,
.cs--story .cs-finals + .cs-two,
.cs--story .cs-stats + .cs-two,
.cs--story .cs-fig + .cs-two { margin-top: clamp(3rem, 6vw, 4.5rem); }

/* research methods: icon tile + numbered label */
.cs--story .cs-methods { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }
.cs--story .cs-method {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  border-radius: var(--cs-radius); overflow: hidden;
  background: var(--cs-band);
}
.cs--story .cs-method__icon {
  display: grid; place-items: center;
  min-height: 5.5rem;
  background: #DCE5D0;   /* fallback */
  background: color-mix(in srgb, var(--cs-accent-soft) 22%, var(--cs-band));
}
.cs--story .cs-method__icon svg {
  width: 2rem; height: 2rem;
  fill: none; stroke: var(--cs-accent); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
.cs--story .cs-method__text {
  display: flex; flex-direction: column; justify-content: center; gap: .15rem;
  padding: 1rem clamp(1rem, 2.4vw, 1.75rem);
  font-size: clamp(1.0625rem, 1rem + .35vw, 1.25rem);
  font-weight: 500; font-stretch: 104%;
}
.cs--story .cs-method__num { color: var(--cs-accent-soft); font-size: var(--fs-small); font-variant-numeric: tabular-nums; }

/* research methods, boxed variant: small-caps label above a plain image box, no icon */
.cs--story .cs-methods--boxed { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(.9rem, 2vw, 1.25rem); }
.cs--story .cs-method--boxed {
  display: flex; flex-direction: column; gap: .75rem;
  background: none; border-radius: 0;
}
.cs--story .cs-method__label {
  color: var(--graphite);
  font-size: .75rem;
  font-weight: 560;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-align: center;
}
.cs--story .cs-method--boxed .media { aspect-ratio: 4 / 5; border-radius: var(--cs-radius); }
/* research notes/screenshots: show the whole image (no cropping), fitted inside the box */
.cs--story .cs-method--boxed .media.cs-media--contain img { object-fit: contain; padding: 6%; }
/* plain variant: no box at all behind the screenshot — just the real image at
   its own natural shape, rounded, with a very soft shadow lifting it off the
   page (no background fill, no padding, so there's no white letterboxing
   showing around it) */
.cs--story .cs-method--boxed .media.cs-media--plain {
  aspect-ratio: auto;
  background: none;
  box-shadow: 0 1px 2px rgba(25, 28, 26, .05), 0 10px 24px -14px rgba(25, 28, 26, .12);
}
.cs--story .cs-method--boxed .media.cs-media--plain img {
  position: static;
  width: 100%; height: auto;
  object-fit: initial;
  padding: 0;
}
/* when there are only 2 methods (not 3), keep each box the same width it would
   be in a 3-up row, and centre the pair instead of leaving the 3rd slot's
   worth of empty space hanging off one side */
.cs--story .cs-methods--boxed-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 66%;
  margin-inline: auto;
}
@media (max-width: 720px) {
  .cs--story .cs-methods--boxed { grid-template-columns: 1fr; }
  .cs--story .cs-methods--boxed-2 { max-width: none; }
}

/* three sketches in a row, then large final designs */
.cs--story .cs-trio { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--col-gap); }
.cs--story .cs-trio figure, .cs--story .cs-finals figure { margin: 0; }
.cs--story .cs-trio .media { aspect-ratio: 4 / 3; border-radius: calc(var(--cs-radius) * .8); }
.cs--story .cs-finals { display: grid; gap: clamp(1rem, 2.5vw, 1.75rem); }
.cs--story .cs-finals .media { aspect-ratio: 16 / 10; border-radius: var(--cs-radius); }

/* testimonies: photo with name + role underneath, a large quote mark, then the quote */
.cs--story .cs-two--solo { margin-top: clamp(3rem, 6vw, 4.5rem); }
.cs--story .cs-testimonies { display: grid; gap: clamp(2rem, 5vw, 3.5rem); }
.cs--story .cs-testimony {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(7.5rem, 3fr) auto minmax(0, 7fr);
  column-gap: clamp(1.25rem, 3.5vw, 3rem);
  align-items: start;
}
.cs--story .cs-testimony__person { display: grid; justify-items: start; gap: .9rem; }
.cs--story .cs-testimony__avatar { width: clamp(6.5rem, 11vw, 9rem); }
.cs--story .cs-testimony__avatar .media { aspect-ratio: 1; border-radius: 50%; }
.cs--story .cs-testimony__avatar .media__ph { display: none; }
.cs--story .cs-testimony figcaption {
  margin: 0; padding-left: .35rem;
  text-align: left; color: var(--ink);
  font-size: clamp(1rem, .95rem + .3vw, 1.1875rem); line-height: 1.35;
}
.cs--story .cs-testimony figcaption strong { display: block; font-weight: 400; color: var(--ink); }
.cs--story .cs-testimony figcaption .cs-testimony__role {
  display: inline;
  color: inherit;
  font-size: inherit;
  font-weight: inherit;
  letter-spacing: normal;
  text-transform: none;
}
.cs--story .cs-testimony__mark {
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(7rem, 12vw, 10.5rem);
  line-height: .74;
  color: #BEB9B8;
  margin-top: -.15em;
}
.cs--story .cs-testimony blockquote {
  margin: 0;
  padding-top: clamp(1.75rem, 3.5vw, 3rem);
  font-size: clamp(1.125rem, 1rem + .55vw, 1.4375rem);
  line-height: 1.45;
  max-width: 26rem;
}
@media (max-width: 720px) {
  .cs--story .cs-testimony { grid-template-columns: auto minmax(0, 1fr); row-gap: .5rem; }
  .cs--story .cs-testimony__person { grid-column: 1 / -1; grid-template-columns: auto 1fr; align-items: center; }
  .cs--story .cs-testimony__avatar { width: 5rem; }
  .cs--story .cs-testimony__mark { font-size: 5.5rem; }
  .cs--story .cs-testimony blockquote { padding-top: 1.1rem; }
}

@media (max-width: 720px) {
  .cs--story .cs-method { grid-template-columns: 5.5rem minmax(0, 1fr); }
  .cs--story .cs-trio { grid-template-columns: 1fr; }
}

/* Plant milk packaging section */
.cs--story .media.cs-media--4x3 { aspect-ratio: 4 / 3; }
.cs--story .media.cs-media--natural { aspect-ratio: auto; }
.cs--story .media.cs-media--natural img { position: static; height: auto; }
/* product shots on white: show the whole image, no cropping */
.cs--story .cs-pair--contain .media { background: #FFFFFF; }
.cs--story .cs-pair--contain .media img { object-fit: contain; padding: 6%; }
/* band with the image on the right */
.cs--story .cs-band--flip { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.cs--story .cs-band--flip .cs-band__media { order: 2; }
/* chat screenshot + message bubbles */
.cs--story .cs-chat {
  margin-top: clamp(1rem, 2.5vw, 1.75rem);
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--col-gap); align-items: center;
}
.cs--story .cs-chat__shot { margin: 0; }
.cs--story .cs-chat__shot .media { border-radius: var(--cs-radius); }
.cs--story .cs-chat__bubbles { display: grid; gap: .75rem; justify-items: start; }
.cs--story .cs-bubble {
  max-width: 22rem;
  padding: .8rem 1.1rem;
  background: var(--cs-band);
  border-radius: 1.1rem 1.1rem 1.1rem .3rem;
  font-size: 1.0625rem;
}
/* one big outcome number */
.cs--story .cs-bigstat {
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
  display: flex; flex-direction: column; gap: clamp(1.5rem, 4vw, 2.5rem);
  padding: clamp(1.5rem, 3.5vw, 2.25rem);
  background: var(--cs-band);   /* fallback: the project's soft tint */
  background: color-mix(in srgb, var(--cs-accent-soft) 30%, #FFFFFF);
  border-radius: var(--cs-radius);
}
.cs--story .cs-bigstat strong {
  color: var(--ink);
  font-size: clamp(2.25rem, 1.6rem + 2.6vw, 3.75rem);
  font-weight: 450; font-stretch: 106%; letter-spacing: -0.02em; line-height: 1;
}
.cs--story .cs-bigstat span { color: var(--ink); font-size: clamp(1rem, .95rem + .25vw, 1.1875rem); line-height: 1.3; }
.cs--story .cs-two + .cs-pair--contain,
.cs--story .cs-two + .cs-bigstat { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); }
.cs--story .cs-pair + .cs-band,
.cs--story .cs-band + .cs-two,
.cs--story .cs-chat + .cs-two { margin-top: clamp(3rem, 6vw, 4.5rem); }

@media (max-width: 720px) {
  .cs--story .cs-band--flip { grid-template-columns: 1fr; }
  .cs--story .cs-band--flip .cs-band__media { order: 0; }
  .cs--story .cs-chat { grid-template-columns: 1fr; }
}

/* Photos show whole: once a real image loads, its box takes the photo's own shape
   (no cropping), on the full page and in the smaller popup. Placeholders keep their
   shape until an image is added. Kept as fixed boxes: avatars, internship squares,
   project cards, white product pairs, and the animated hero. */
.cs--story .cs-fig .media.is-loaded,
.cs--story .cs-finals .media.is-loaded,
.cs--story .cs-trio .media.is-loaded,
.cs--story .cs-pair:not(.cs-pair--contain) .media.is-loaded,
.cs--story .cs-band__media .media.is-loaded,
.cs--story .cs-chat__shot .media.is-loaded { aspect-ratio: auto; }
.cs--story .cs-fig .media.is-loaded img,
.cs--story .cs-finals .media.is-loaded img,
.cs--story .cs-trio .media.is-loaded img,
.cs--story .cs-pair:not(.cs-pair--contain) .media.is-loaded img,
.cs--story .cs-band__media .media.is-loaded img,
.cs--story .cs-chat__shot .media.is-loaded img { position: static; height: auto; }

/* ---------- Roomier rhythm + dividers (story layout) ----------
   Each sub-section (Mission, Research, Final designs, ...) starts with a hairline
   rule so it's clear where one ends and the next begins; sections get more air. */
.cs--story .cs-section { padding-top: clamp(5rem, 10vw, 8.5rem); }
.cs--story .cs-sec-head { margin-bottom: clamp(2.25rem, 4.5vw, 3.5rem); }
.cs--story .cs-section > .cs-two {
  margin-top: clamp(3.5rem, 7vw, 5.5rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--rule);
}
.cs--story .cs-section > .cs-sec-head + .cs-two { margin-top: 0; padding-top: 0; border-top: 0; }
.cs--story .cs-section > .cs-two + .cs-two { margin-top: clamp(2rem, 4vw, 3rem); padding-top: clamp(2rem, 4vw, 3rem); }
/* content under a sub-section label */
.cs--story .cs-two + .cs-fig,
.cs--story .cs-two + .cs-methods,
.cs--story .cs-two + .cs-trio,
.cs--story .cs-two + .cs-finals,
.cs--story .cs-two + .cs-stats,
.cs--story .cs-two + .cs-testimonies,
.cs--story .cs-two + .cs-pair--contain,
.cs--story .cs-two + .cs-bigstat,
.cs--story .cs-two + .cs-bigstats { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
/* bands sit between sub-sections with room on both sides */
.cs--story .cs-band { margin-top: clamp(3rem, 6vw, 4.5rem); }
.cs--story .cs-finals { gap: clamp(1.5rem, 3vw, 2.25rem); }
.cs--story .cs-methods { gap: 1rem; }
.cs--story .cs-testimonies { gap: clamp(2.5rem, 5vw, 3.5rem); }
.cs--story .cs-two--solo { margin-top: clamp(3.5rem, 7vw, 5.5rem); }

/* metric outcomes: side-by-side cards */
.cs--story .cs-bigstats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(.9rem, 2vw, 1.25rem); }
.cs--story .cs-bigstats .cs-bigstat { margin-top: 0; }
@media (max-width: 720px) {
  .cs--story .cs-bigstats { grid-template-columns: 1fr; }
}

/* inside the popup: wider margins and more space at the top */
html.in-modal .cs--story { padding-top: clamp(2.75rem, 5vw, 4rem); padding-bottom: clamp(5rem, 9vw, 8rem); }
html.in-modal .cs--story.wrap { padding-inline: clamp(1.5rem, 5vw, 4.5rem); }
html.in-modal .cs--story .cs__layout { gap: clamp(2.5rem, 6vw, 6.5rem); }
html.in-modal .cs--story .cs-head { margin-bottom: clamp(.5rem, 2vw, 1.5rem); }

@media (max-width: 900px) {
  .cs--story .cs-projects, .cs--story .cs-testimonials { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .cs--story .cs-photos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
  .cs--story .cs-two,
  .cs--story .cs-band { grid-template-columns: 1fr; }
  .cs--story .cs-two { gap: .6rem; }
}
@media (max-width: 560px) {
  .cs--story .cs-pair { grid-template-columns: 1fr; }
}

/* ---------- Michelle-style rhythm (story layout) ----------
   Modelled on liumichelle.com's case study popup: every block carries its own
   vertical padding, so gaps add up the same way everywhere.
     text blocks (label + paragraph)  56px above and below
     images, grids, lists             40px above and below
     section titles                   64px above, hairline, then 40px
   No divider lines between sub-sections; only under each section title.
   (.cs.cs--story prefix = higher specificity, so this wins over the older rules.) */
.cs.cs--story {
  --b-text:  clamp(2rem, 4.5vw, 3.5rem);
  --b-media: clamp(1.5rem, 3vw, 2.5rem);
  --b-title: clamp(2.5rem, 5vw, 4rem);
}
.cs.cs--story .cs-section { padding-top: 0; }
.cs.cs--story .cs-section > * { margin-top: 0; margin-bottom: 0; }
.cs.cs--story .cs-section > .cs-sec-head {
  padding-top: var(--b-title);
  padding-bottom: 1.25rem;
  margin-bottom: var(--b-media);
}
.cs.cs--story .cs-section > .cs-two {
  margin: 0;
  padding-block: var(--b-text);
  border-top: 0;
}
.cs.cs--story .cs-section > :is(.cs-fig, .cs-photos, .cs-intro, .cs-projects, .cs-methods,
  .cs-trio, .cs-duo, .cs-solo, .cs-finals, .cs-stats, .cs-bigstats, .cs-pair, .cs-chat,
  .cs-testimonies, .cs-reflections, .cs-testimonials, .cs-journey) {
  padding-block: var(--b-media);
}
/* boxed blocks keep their inner padding, so they get the space as margin instead */
.cs.cs--story .cs-section > :is(.cs-band, .cs-bigstat, .cs-thread, .cs-locked) { margin-block: var(--b-media); }
/* sub-section links in the side nav land just below the sticky bar */
.cs--story .cs-section [id] { scroll-margin-top: var(--sticky-top); }

/* a longer testimony: slightly smaller type so the quote stays easy to read */
.cs--story .cs-testimony--long blockquote {
  max-width: 30rem;
  font-size: clamp(1.0625rem, 1rem + .3vw, 1.25rem);
  line-height: 1.5;
}

/* a testimony that's shown as a short preview, with the rest tucked behind
   a "Read full testimony" toggle (height-animated open; shown already when
   JS is off or the person prefers reduced motion) */
.cs--story .cs-testimony__quote { display: block; }
.cs--story .cs-testimony__lead { margin: 0; }
.cs--story .cs-testimony__more { overflow: hidden; }
.js .cs--story .cs-testimony__more { height: 0; transition: height .35s var(--ease); }
.cs--story .cs-testimony__more-inner > p {
  margin: 1.1em 0 0;
  font-size: clamp(1.0625rem, 1rem + .3vw, 1.25rem);
  line-height: 1.5;
}
.cs--story .cs-testimony__toggle {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  margin-top: 1.1rem;
  padding: 0;
  background: none;
  border: 0;
  color: var(--cs-accent);
  font-family: inherit;
  font-size: var(--fs-small);
  font-weight: 560;
  cursor: pointer;
}
.cs--story .cs-testimony__toggle:hover { text-decoration: underline; }
.cs--story .cs-testimony__chevron { width: 11px; height: 11px; transition: transform .3s var(--ease); flex-shrink: 0; }
.cs--story .cs-testimony__toggle[aria-expanded="true"] .cs-testimony__chevron { transform: rotate(180deg); }
/* no JS: show the full testimony and drop the toggle, so nothing is hidden */
html:not(.js) .cs--story .cs-testimony__more[hidden] { display: block; height: auto; }
html:not(.js) .cs--story .cs-testimony__toggle { display: none; }
@media (prefers-reduced-motion: reduce) {
  .cs--story .cs-testimony__more { transition: none; }
}

/* RBC: centred, narrower figures (portrait artwork, notebook photo) */
.cs.cs--story .cs-section > .cs-fig--narrow { max-width: 34rem; margin-inline: auto; }
/* product screens on white: a hairline so they don't melt into the page */
.cs--story .media.cs-media--screen { outline: 1px solid var(--rule); outline-offset: -1px; }
/* wide user journey: scrolls sideways (drag, swipe or trackpad) at a readable size */
.cs--story .cs-journey { margin-inline: 0; }
.cs--story .cs-journey__scroll {
  overflow-x: auto; overscroll-behavior-x: contain;
  background: #FFFFFF;
  border: 1px solid var(--rule);
  border-radius: var(--cs-radius);
  cursor: grab;
  scrollbar-width: thin;
}
.cs--story .cs-journey__scroll.is-dragging { cursor: grabbing; user-select: none; }
.cs--story .cs-journey__scroll:focus-visible { outline: 2px solid var(--cs-accent); outline-offset: 3px; }
.cs--story .cs-journey__scroll img {
  display: block; max-width: none; width: auto;
  height: clamp(16rem, 34vw, 24rem);
  padding: 1.25rem;
  box-sizing: content-box;
  pointer-events: none;
}

/* confidential card: lock in a white circle, then a short note with an email link */
.cs--story .cs-locked {
  padding: clamp(2rem, 6vw, 4rem) clamp(1.5rem, 6vw, 4rem);
  background: #ECEDE9;
  border-radius: calc(var(--cs-radius) * 1.3);
}
.cs--story .cs-locked__icon {
  display: grid; place-items: center;
  width: clamp(3.25rem, 6vw, 3.75rem); height: clamp(3.25rem, 6vw, 3.75rem);
  margin-bottom: clamp(1.75rem, 4vw, 2.5rem);
  background: #FFFFFF;
  border-radius: 50%;
  box-shadow: 0 2px 10px rgba(25, 28, 26, .08);
  color: #74747C;
}
.cs--story .cs-locked__icon svg { width: 1.65rem; height: 1.65rem; fill: currentColor; }
.cs.cs--story .cs-locked p { max-width: none; margin: 0; }
.cs--story .cs-locked__title {
  font-size: clamp(1.25rem, 1.05rem + .8vw, 1.5rem);
  line-height: 1.3;
  color: var(--ink);
}
.cs.cs--story .cs-locked .cs-locked__note { margin-top: .6rem; color: #A3A3AA; font-size: clamp(1rem, .95rem + .25vw, 1.125rem); }
.cs--story .cs-locked__note a { color: #6E6E76; font-weight: 500; text-decoration: none; }
.cs--story .cs-locked__note a:hover { color: var(--cs-accent); text-decoration: underline; }

/* password form inside the confidential card */
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.cs--story .cs-locked__form {
  display: flex; gap: .6rem;
  margin-top: clamp(1.5rem, 3.5vw, 2rem);
  max-width: 22rem;
}
.cs--story .cs-locked__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: .7rem .9rem;
  border: 1px solid #D7D8D2;
  border-radius: calc(var(--cs-radius) * .45);
  background: #FFFFFF;
  color: var(--ink);
  font: inherit;
  font-size: 1rem;
}
.cs--story .cs-locked__input:focus-visible { outline: 2px solid var(--cs-accent); outline-offset: 1px; }
.cs--story .cs-locked__input.is-shake { animation: cs-locked-shake .32s; }
@keyframes cs-locked-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-6px); }
  75% { transform: translateX(6px); }
}
.cs--story .cs-locked__submit {
  flex: none;
  padding: .7rem 1.1rem;
  border: none;
  border-radius: calc(var(--cs-radius) * .45);
  background: var(--ink);
  color: var(--paper);
  font: inherit;
  font-weight: 500;
  cursor: pointer;
  transition: background .15s ease;
}
.cs--story .cs-locked__submit:hover { background: var(--cs-accent); }
.cs--story .cs-locked__success {
  margin-top: clamp(1.5rem, 3.5vw, 2rem);
  padding-top: clamp(1.5rem, 3.5vw, 2rem);
  border-top: 1px solid #DADBD5;
  color: var(--ink);
}
/* pop-up-blocked fallback: no divider, same spacing/colour as the .cs-locked__note above the form
   (font-size matched via the type-scale override further down) */
.cs--story .cs-locked__success--plain {
  margin-top: .6rem;
  padding-top: 0;
  border-top: none;
  color: #A3A3AA;
}
.cs--story .cs-locked__link {
  display: inline-flex; align-items: center; gap: .35rem;
  color: var(--cs-accent);
  font-weight: 500;
  text-decoration: none;
}
.cs--story .cs-locked__link:hover { text-decoration: underline; }
.cs--story .cs-locked__link svg { width: .9em; height: .9em; flex: none; }
.cs--story .cs-locked[data-unlocked] .cs-locked__form,
.cs--story .cs-locked[data-unlocked] .cs-locked__note { display: none; }

/* launch-day text thread: friend's messages on the left in white, Sophia's replies
   on the right in the project green, all on one soft band */
.cs--story .cs-thread {
  display: grid; place-items: center;
  padding: clamp(1.75rem, 5vw, 3.5rem) clamp(1rem, 4vw, 3rem);
  background: var(--cs-band);
  border-radius: var(--cs-radius);
}
.cs--story .cs-thread__chat {
  width: min(100%, 25rem);
  display: flex; flex-direction: column; gap: .3rem;
}
.cs--story .msg {
  max-width: 88%;
  margin: 0;
  padding: .6rem 1rem .65rem;
  border-radius: 1.2rem;
  font-size: 1rem;
  line-height: 1.35;
}
.cs--story .msg--in {
  align-self: flex-start;
  background: #FFFFFF;
  color: var(--ink);
  border-bottom-left-radius: .4rem;
}
.cs--story .msg--in.msg--last { border-bottom-left-radius: 1.2rem; border-top-left-radius: .4rem; }
.cs--story .msg--out {
  align-self: flex-end;
  background: var(--cs-accent);
  color: #FFFFFF;
  border-bottom-right-radius: .4rem;
}
.cs--story .msg--in + .msg--out,
.cs--story .msg--out + .msg--in { margin-top: 1rem; }
.cs--story .msg--out.msg--last { border-bottom-right-radius: 1.2rem; border-top-right-radius: .4rem; }
/* the shelf photo, sent as a picture message, with a little heart reaction */
.cs--story .msg--photo {
  position: relative;
  width: 64%;
  padding: 0;
  margin-bottom: .9rem;
  background: none;
  border-radius: 1.4rem;
}
.cs--story .msg--photo img {
  display: block; width: 100%; height: auto;
  border-radius: 1.6rem;
  box-shadow: 0 10px 28px -16px rgba(25, 28, 26, .45);
}
.cs--story .msg__react {
  position: absolute; left: .55rem; bottom: -.85rem;
  display: grid; place-items: center;
  width: 2rem; height: 2rem;
  background: #FFFFFF;
  border: 2px solid var(--cs-band);
  border-radius: 50%;
}
.cs--story .msg__react svg { width: 1rem; height: 1rem; fill: #E5484D; }

/* messages arrive one after another once the thread scrolls into view */
.js .cs--story .cs-thread .msg { opacity: 0; transform: translateY(10px) scale(.96); }
.js .cs--story .cs-thread .msg--in { transform-origin: left bottom; }
.js .cs--story .cs-thread .msg--out { transform-origin: right bottom; }
.js .cs--story .cs-thread.is-in .msg {
  opacity: 1; transform: none;
  transition: opacity .45s var(--ease), transform .55s ease-out;
  transition-delay: calc(var(--i, 0) * 420ms + 120ms);
}
@media (prefers-reduced-motion: reduce) {
  .js .cs--story .cs-thread .msg { opacity: 1; transform: none; }
}
/* a label sits closer to the thing it introduces than to the block before it */
.cs.cs--story .cs-section > .cs-two:has(+ :not(.cs-two)) { padding-bottom: var(--b-media); }
/* the welcome note fills the full width of the column, like the photo row above it */
.cs.cs--story .cs-intro { max-width: none; text-wrap: pretty; }
/* header: title, then details, then the animated postcard */
.cs.cs--story .cs-meta { margin-top: 2.5rem; }
.cs.cs--story .cs-hero { margin-top: 2rem; margin-bottom: var(--b-media); }

/* popup: more air above the title, and on wide popups the reading column sits in
   the middle (about 736px, like Michelle's) with the side nav in the left margin */
html.in-modal .cs.cs--story { padding-top: clamp(3rem, 8vw, 6rem); }
@media (min-width: 1200px) {
  html.in-modal .cs.cs--story.wrap { padding-inline: clamp(1.5rem, 3.5vw, 3rem); }
  html.in-modal .cs.cs--story .cs__layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 46rem) minmax(0, 1fr);
    gap: 2rem;
  }
  html.in-modal .cs.cs--story .cs__main { max-width: none; }
}

/* one image, centred in the content column at a comfortable size (no cropping) */
.cs--story .cs-solo { display: grid; justify-items: center; }
.cs--story .cs-solo figure { margin: 0; width: min(100%, 46rem); }
.cs--story .cs-solo .media { aspect-ratio: 3 / 2; border-radius: calc(var(--cs-radius) * .8); }
.cs--story .cs-solo .media.is-loaded { aspect-ratio: auto; }
.cs--story .cs-solo .media.is-loaded img { position: static; width: 100%; height: auto; }

/* two images side by side, each at its own shape (no cropping) */
.cs--story .cs-duo {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--col-gap); align-items: start;
}
.cs--story .cs-duo figure { margin: 0; }
.cs--story .cs-duo .media { aspect-ratio: 3 / 2; border-radius: calc(var(--cs-radius) * .8); }
.cs--story .cs-duo .media.is-loaded { aspect-ratio: auto; }
.cs--story .cs-duo .media.is-loaded img { position: static; height: auto; }
@media (max-width: 720px) { .cs--story .cs-duo { grid-template-columns: 1fr; } }

/* ---------- One type scale for every case study (story layout) ----------
   Greenhouse, RBC and IBM all use these five sizes, so the same kind of text is
   the same size everywhere:
     --t-h2    section titles ("Design libraries", "Testimonials")
     --t-h3    sub-section labels ("Mission", "Final designs") and card titles
     --t-lead  intro notes, quotes, reflections, research method names
     --t-body  paragraphs, bubbles, names under photos, stat labels
     --t-small details (Year, Role...), captions, little numbers */
.cs.cs--story {
  --t-h2:    clamp(1.5rem, 1.2rem + 1.1vw, 2rem);
  --t-h3:    clamp(1.25rem, 1.1rem + .55vw, 1.5rem);
  --t-lead:  clamp(1.125rem, 1.05rem + .3vw, 1.25rem);
  --t-body:  var(--fs-body);
  --t-small: var(--fs-small);
}
.cs.cs--story .cs-sec-head h2,
.cs.cs--story .cs-sec-num { font-size: var(--t-h2); line-height: 1.2; }
.cs.cs--story .cs-band h3,
.cs.cs--story .cs-locked .cs-locked__title,
.cs.cs--story .cs-next__title { font-size: var(--t-h3); line-height: 1.3; }
.cs.cs--story .cs-two h3 {
  font-size: .75rem;
  color: var(--graphite);
  font-weight: 560;
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1.3;
}
.cs.cs--story .cs-intro,
.cs.cs--story .cs-testimony blockquote,
.cs.cs--story .cs-method__text { font-size: var(--t-lead); line-height: 1.5; }
.cs.cs--story .cs-two__body p,
.cs.cs--story .cs-two__body .cs-list,
.cs.cs--story .cs-band p,
.cs.cs--story .msg,
.cs.cs--story .cs-bubble,
.cs.cs--story .cs-testimony figcaption,
.cs.cs--story .cs-testimonial blockquote,
.cs.cs--story .cs-locked .cs-locked__note,
.cs.cs--story .cs-locked__success--plain,
.cs.cs--story .cs-bigstat span,
.cs.cs--story .cs-project p,
.cs.cs--story .cs-next__name { font-size: var(--t-body); }
.cs.cs--story .cs-two__body p,
.cs.cs--story .cs-band p { line-height: 1.55; }
.cs.cs--story .cs-meta dt,
.cs.cs--story figcaption:not(.cs-testimony figcaption),
.cs.cs--story .cs-method__num { font-size: var(--t-small); }

/* ==========================================================
   Case study popup (home page)
   ========================================================== */
html.modal-open { overflow: hidden; }
.cs-modal {
  width: min(1240px, calc(100vw - 2 * clamp(.75rem, 3vw, 2.5rem)));
  height: calc(100dvh - 2 * clamp(.75rem, 3vw, 2.5rem));
  max-width: none; max-height: none;
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: 14px;
  background: var(--paper);
  color: var(--ink);
  overflow: hidden;
  box-shadow: 0 30px 80px -30px rgba(25, 28, 26, .45);
  display: none;
  flex-direction: column;
}
.cs-modal[open] { display: flex; animation: sheet-in .45s var(--ease); }
.cs-modal.is-closing { animation: sheet-out .25s ease-in forwards; }
.cs-modal::backdrop {
  background: rgba(25, 28, 26, .38);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
@keyframes sheet-in  { from { opacity: 0; transform: translateY(28px) scale(.985); } }
@keyframes sheet-out { to   { opacity: 0; transform: translateY(18px) scale(.99); } }

.cs-modal__bar {
  flex: none;
  display: flex; justify-content: space-between; align-items: center;
  padding: .6rem .75rem;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-small);
}
.cs-modal__btn {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .4rem .65rem;
  border: 0; border-radius: 8px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}
.cs-modal__btn:hover { background: rgba(25, 28, 26, .06); }
.cs-modal__btn svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.6; }
.cs-modal__frame { flex: 1; width: 100%; border: 0; background: var(--paper); }

@media (max-width: 720px) {
  .cs-modal { width: 100vw; height: 100dvh; border-radius: 0; }
}

/* ---------- Motion ---------- */
/* one load-in sequence for the hero */
.js .load-in {
  opacity: 0;
  transform: translateY(14px);
  animation: rise .9s var(--ease) forwards;
  animation-delay: calc(var(--d, 0) * 140ms + 80ms);
}
@keyframes rise { to { opacity: 1; transform: none; } }
/* main.js adds .is-settled when a draggable card's entrance animation ends.
   Opacity then comes from here instead of from the animation's "forwards" fill,
   so a later animation (the click wiggle) can't switch the card back to opacity 0. */
.js .load-in.is-settled { opacity: 1; transform: none; animation: none; }
.js .load-in.is-settled.is-popped { animation: note-pop .5s var(--ease); }

/* images settle in as they scroll into view */
.js .reveal {
  clip-path: inset(6% 0 0 0);
  opacity: 0;
  transition: clip-path 1s var(--ease), opacity .8s var(--ease);
}
.js .reveal.is-in { clip-path: inset(0 0 0 0); opacity: 1; }

/* smooth fade between pages in browsers that support it */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
  .js .load-in, .js .reveal { opacity: 1; transform: none; clip-path: none; }
  .cs-modal[open], .cs-modal.is-closing { animation: none; }
  .polaroid:hover { rotate: var(--r, 0deg); translate: none; }
  .id-card:hover { rotate: var(--r); translate: none; }
  .id-card, .id-card__title { transition: none; }
}

/* ---------- Responsive ---------- */
@media (max-width: 1040px) {
}

}

@media (max-width: 960px) {
  .pins { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
  .work__grid { grid-template-columns: minmax(0, 1fr); max-width: 24rem; margin-inline: auto; row-gap: 1.5rem; padding-inline: .6rem; }
  .id-card { rotate: calc(var(--r) * .6); }     /* a gentler hang on phones so the corners stay on screen */
  .site-header__inner { padding-top: 4.5rem; padding-bottom: 1rem; }   /* room for the pill above the logo */
  .site-nav { top: .6rem; font-size: .8125rem; gap: 0; padding: .3rem; }
  .site-nav__link { padding: .45rem .55rem; gap: .25rem; }
  .site-nav__rule { margin-inline: .1rem; }
  .site-nav__drop { left: auto; right: 0; }
  .clock span { display: none; }
  .hero { grid-template-columns: minmax(0, 1fr); }
  .hero__portrait { width: 9.5rem; margin: .5rem 0 0 .25rem; }
  .cs-nav { top: 4.5rem; }
  html.in-modal .cs-nav { top: 0; }
}

@media (max-width: 560px) {
  .pins { grid-template-columns: repeat(2, minmax(0, 1fr)); --pin-gap: .75rem; }
  .pin .media { border-radius: 12px; }
  .pin__cap { border-radius: 0 0 12px 12px; }
}

/* Greenhouse design-library flow (follows the low-fi wireframe) */
.cs--story .cs-steps { margin: .9rem 0 0; padding-left: 1.2rem; color: var(--graphite); }
.cs--story .cs-steps li + li { margin-top: .3rem; }
.cs--story .cs-quotes { display: grid; gap: clamp(.75rem, 1.6vw, 1rem); margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
.cs--story .cs-pull {
  margin: 0; padding: clamp(1rem, 2.5vw, 1.5rem) clamp(1.1rem, 3vw, 1.75rem);
  background: #F9F9F9; border: 1px solid var(--rule); border-radius: var(--cs-radius);
  font-size: clamp(1.0625rem, 1rem + .3vw, 1.25rem); line-height: 1.35; font-stretch: 104%;
}
.cs--story .cs-pills { display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem; margin-top: 1.25rem; }
.cs--story .cs-pills p { margin: 0; padding: .6rem 1.4rem; background: #F9F9F9; border: 1px solid var(--rule); border-radius: 999px; max-width: none; }
.cs--story .cs-fb { margin-top: clamp(2rem, 4vw, 3rem); }
.cs--story .cs-fb h4 { margin: 0 0 .5rem; font-size: var(--fs-h3); font-weight: 560; }
.cs--story .cs-fb p { max-width: 40rem; color: var(--graphite); }

/* Wireframe layout: centred narrow column, left-aligned labels, centred captions */
.cs--center .cs-sec-head {
  display: flex; align-items: center; justify-content: center; gap: clamp(1rem, 3vw, 2rem);
  border-bottom: 0; padding-bottom: 0; text-align: center;
}
.cs--center .cs-sec-head::before, .cs--center .cs-sec-head::after { content: ""; flex: 1; height: 1px; background: var(--ink); opacity: .55; }
.cs--center .cs-sec-head h2, .cs--center .cs-sec-head .cs-sec-num {
  margin: 0; color: var(--ink); font-size: 1rem; font-weight: 400; font-stretch: 100%; white-space: nowrap;
}
.cs--center .cs-sec-head .cs-sec-num { margin-right: -.55rem; }

/* header + tl;dr */
.cs--center .cs-head { padding: clamp(1.5rem, 3vw, 2rem); background: var(--cs-band); }
.cs--center .cs-tldr__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cs--center .cs-tldr__stat { display: flex; align-items: center; gap: clamp(.9rem, 2.5vw, 1.75rem); border-left: 0; padding-left: 0; }
.cs--center .cs-tldr__num { font-size: clamp(2.75rem, 2rem + 3vw, 4.5rem); font-weight: 300; }
.cs--center .cs-tldr__cap { margin: 0; color: var(--ink); }

/* introduction */
.cs--center .cs-photos { grid-template-columns: repeat(3, minmax(0, 1fr)); max-width: 85%; margin-inline: auto; }
.cs--center .cs-intro { text-align: center; max-width: 30rem; margin-inline: auto; }
.cs--center .cs-projects { max-width: 58%; margin-inline: auto; }
.cs--center .cs-project .media { aspect-ratio: 1 / 1; }
.cs--center .cs-project p { margin-top: .9rem; text-align: center; text-transform: uppercase; font-weight: 400; font-stretch: 100%; font-size: var(--fs-small); }

/* body: narrow column, label above, left-aligned */
.cs--center .cs-section > :is(.cs-two, .cs-fig, .cs-quotes, .cs-fb, .cs-pills, .cs-solo, .cs-finals, .cs-bigstats, .cs-testimonies, .cs-reflections, .cs-methods, .cs-pair, .cs-band, .cs-thread, .cs-chat) {
  width: 100%; max-width: 34rem; margin-inline: auto;
}
.cs--center .cs-section > :is(.cs-finals, .cs-bigstats, .cs-testimonies, .cs-pair, .cs-band) { max-width: 48rem; }
.cs--center.cs--story .cs-section > .cs-two,
.cs--center.cs--story .cs-two--solo { grid-template-columns: minmax(0, 1fr); gap: .75rem; justify-items: start; text-align: left; border-top: 0; }
.cs--center .cs-two h3 { margin: 0; color: var(--ink); font-size: .8125rem; font-weight: 400; letter-spacing: .02em; text-transform: uppercase; }
.cs--center .cs-two__body { width: 100%; }
.cs--center .cs-two__body p, .cs--center .cs-fb p { max-width: none; color: var(--ink); }
.cs--center .cs-steps { padding-left: 1.2rem; color: var(--ink); list-style-position: outside; }
.cs--center .cs-fig figcaption, .cs--center .cs-pair figcaption { text-align: center; color: var(--ink); max-width: 28rem; margin-inline: auto; }
.cs--center .cs-quotes, .cs--center .cs-pull { text-align: center; }
.cs--center .cs-fb h4 { font-size: 1rem; font-weight: 400; }

/* beat the .cs.cs--story rhythm rules so the narrow column really centres */
.cs.cs--center.cs--story .cs-section > :is(.cs-two, .cs-fig, .cs-quotes, .cs-fb, .cs-pills, .cs-solo, .cs-methods, .cs-thread) { width: 100%; max-width: 34rem; margin-inline: auto; }
.cs.cs--center.cs--story .cs-section > :is(.cs-finals, .cs-bigstats, .cs-testimonies, .cs-pair, .cs-band) { max-width: 48rem; margin-inline: auto; }
.cs.cs--center.cs--story .cs-sec-head h2, .cs.cs--center.cs--story .cs-sec-head .cs-sec-num { font-size: 1rem; font-weight: 400; font-stretch: 100%; color: var(--ink); }
.cs.cs--center.cs--story .cs-section > .cs-two { padding-bottom: .5rem; }

/* User interviews panel: light grey card, italic questions, grey pill notes (from wireframe) */
.cs--center .cs-section > .cs-panel { max-width: 58rem; margin-inline: auto; padding: clamp(1.5rem, 4vw, 2.75rem) clamp(1rem, 4vw, 3rem); background: #F6F6F6; border-radius: var(--cs-radius); display: grid; gap: clamp(1.5rem, 3vw, 2.25rem); justify-items: center; }
.cs--center .cs-panel__text { width: 100%; max-width: 26rem; display: grid; gap: 1.25rem; }
.cs--center .cs-panel__text h3 { margin: 0; font-size: .8125rem; font-weight: 400; letter-spacing: .02em; text-transform: uppercase; }
.cs--center .cs-panel__text p { margin: 0; max-width: none; color: var(--ink); }
.cs--center .cs-q { margin: 0; max-width: 40rem; text-align: left; font-style: italic; font-size: clamp(1.125rem, 1rem + .7vw, 1.625rem); line-height: 1.3; }
.cs--center .cs-pill { margin: 0; max-width: none; padding: .85rem 2.25rem; background: #DADADA; border-radius: 999px; text-align: center; font-size: var(--fs-small); }
.cs--center .cs-panel__board { width: 100%; max-width: 40rem; height: auto; margin-top: .5rem; }

/* ---------- Greenhouse: one type scale + one spacing rhythm ----------
   Type:  label 12px/560 caps · body 17px/1.55 · caption + pill 14px · quote 24px italic · intro 20px
   Space: label → its content 33px · block → next label 83px (33 + 50) · title → first label 33px */
.cs.cs--center.cs--story {
  --t-label: .75rem;
  --t-body: var(--fs-body);
  --t-small: var(--fs-small);
  --lh-body: 1.55;
}
.cs--center .cs-two h3,
.cs--center .cs-panel__text h3,
.cs--center .cs-project p {
  font-size: var(--t-label); font-weight: 560; letter-spacing: .08em; text-transform: uppercase; line-height: 1.3; font-stretch: 100%;
}
.cs--center .cs-section p, .cs--center .cs-section li, .cs--center .cs-panel__text p { line-height: var(--lh-body); }
.cs--center .cs-fb h4, .cs--center .cs-testimony figcaption strong { font-size: var(--t-body); font-weight: 560; line-height: 1.3; }
.cs--center .cs-fig figcaption, .cs--center .cs-pair figcaption, .cs--center .cs-pill, .cs--center .cs-pills p { font-size: var(--t-small); line-height: 1.5; }

/* label sits one step above its content, wherever that content is a figure, panel, list or feedback block */
.cs.cs--center.cs--story .cs-section > .cs-two { padding-bottom: 0; }
.cs.cs--center.cs--story .cs-section > .cs-two:has(+ :not(.cs-two)) { padding-bottom: 0; }
.cs.cs--center.cs--story .cs-section > :is(.cs-panel, .cs-fb, .cs-pills) { margin-block: var(--b-media); padding-block: 0; }
.cs.cs--center.cs--story .cs-section > .cs-pills { margin-top: 0; }
.cs.cs--center.cs--story .cs-section > .cs-fb + .cs-fb { margin-top: 0; }
.cs.cs--center.cs--story .cs-section > .cs-fb:first-of-type { margin-top: var(--b-media); }
.cs--center .cs-fb { display: grid; gap: .5rem; }
.cs--center .cs-fb .cs-fig { padding: 0; margin-top: .5rem; }
.cs--center .cs-fb p { margin: 0; }
.cs--center .cs-panel { gap: var(--b-media); }
.cs.cs--center.cs--story .cs-project p {
  font-size: var(--t-label); font-weight: 560; letter-spacing: .08em; text-transform: uppercase; line-height: 1.3; font-stretch: 100%;
}
.cs.cs--center.cs--story :is(.cs-fig figcaption, .cs-pair figcaption, .cs-pill, .cs-pills p) { font-size: var(--t-small); line-height: 1.5; }

/* User interviews panel: green, with even padding top and bottom */
.cs.cs--center.cs--story .cs-section > .cs-panel {
  background: #C5D5B5;
  padding: clamp(2rem, 5vw, 3.5rem) clamp(1rem, 4vw, 3rem);
}
.cs--center .cs-panel .cs-pill { background: rgba(255, 255, 255, .6); }
.cs--center .cs-panel__board { margin: 0; display: block; }

/* User interviews panel uses the same sage tint as the header and tl;dr cards (#ECEFE6 via --cs-band) */
.cs.cs--center.cs--story .cs-section > .cs-panel { background: var(--cs-band); }
.cs--center .cs-panel .cs-pill { background: #DADDD5; }

/* ---------- Greenhouse: full-colour sheets that slide over each other (Infinify-style) ----------
   Each .cs-sheet is a full-bleed coloured band with rounded top corners. The next one overlaps the
   previous by pulling up (negative margin), and the page-scroll script adds .is-in as it arrives. */
.cs--center .cs__layout { position: relative; }
.cs--center .cs-sheet {
  --sheet-bg: #FFFFFF; --sheet-ink: var(--ink); --sheet-soft: var(--graphite);
  position: relative;
  margin-inline: calc(50% - 50vw + var(--sheet-inset, 0px));
  padding: clamp(3rem, 7vw, 6rem) calc(50vw - 50% + var(--sheet-inset, 0px));
  background: var(--sheet-bg); color: var(--sheet-ink);
  border-radius: clamp(24px, 4vw, 48px) clamp(24px, 4vw, 48px) 0 0;
  margin-top: calc(clamp(24px, 4vw, 48px) * -1);
  box-shadow: 0 -18px 40px -24px rgba(25, 28, 26, .18);
}
.cs--center .cs-sheet--white  { --sheet-bg: #FFFFFF; }
.cs--center .cs-sheet--sage   { --sheet-bg: var(--cs-band, #ECEFE6); }
.cs--center .cs-sheet :is(p, li, h3, h4, blockquote, figcaption, .cs-bigstat span, .cs-bigstat strong) { color: var(--sheet-ink); }
.cs--center .cs-sheet .cs-two__body p, .cs--center .cs-sheet .cs-fb p { color: var(--sheet-soft); }
.cs--center .cs-sheet--sage .cs-fb + .cs-fb { margin-top: 0; }
.cs--center .cs-sheet > :first-child { margin-top: 0; }
.cs--center .cs-sheet > .cs-two:first-child { padding-top: 0; }

/* slide-up + fade as each sheet arrives */
.js .cs--center .cs-sheet[data-sheet] { transform: translateY(48px); opacity: 0; transition: transform .8s var(--ease), opacity .6s var(--ease); }
.js .cs--center .cs-sheet[data-sheet].is-in { transform: none; opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .js .cs--center .cs-sheet[data-sheet] { transform: none; opacity: 1; transition: none; }
}
/* inside the popup the sheets stay within the popup width */
html.in-modal .cs--center .cs-sheet { margin-inline: 0; padding-inline: clamp(1rem, 4vw, 2.5rem); }

/* pill labels, like "Foundations" */
.cs--center .cs-sheet .cs-two h3 {
  display: inline-block; padding: .35rem .9rem; border: 1px solid currentColor; border-radius: 999px;
  color: var(--sheet-ink); opacity: .85;
}

/* research method cards: soft rounded cards with simple blue-ish shapes → forest green here */
.cs--center .cs-atoms {
  list-style: none; margin: clamp(1.75rem, 3.5vw, 2.5rem) auto 0; padding: 0; max-width: 48rem;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(.75rem, 2vw, 1.25rem);
}
.cs--center .cs-atom {
  padding: clamp(1rem, 2.5vw, 1.5rem); background: #F3F3F1; border-radius: var(--cs-radius);
  box-shadow: 0 1px 2px rgba(25,28,26,.06), 0 12px 24px -16px rgba(25,28,26,.2);
  display: grid; gap: 1rem; align-content: start;
}
.cs--center .cs-atom svg { width: 100%; height: auto; max-height: 7rem; }
.cs--center .cs-atom svg circle { fill: var(--cs-accent); }
.cs--center .cs-atom svg circle.o { fill: #FFFFFF; stroke: #E2E4DE; stroke-width: 2; filter: drop-shadow(0 2px 3px rgba(25,28,26,.12)); }
.cs--center .cs-atom svg circle.ring { fill: #FFFFFF; stroke: #E2E4DE; stroke-width: 2; filter: drop-shadow(0 2px 3px rgba(25,28,26,.12)); }
.cs--center .cs-atom h4 { margin: 0; font-size: var(--fs-body); font-weight: 560; line-height: 1.3; color: var(--ink); }
.cs--center .cs-atom h4 span { font-weight: 400; color: var(--graphite); }
@media (max-width: 720px) { .cs--center .cs-atoms { grid-template-columns: 1fr; } }
.cs--center { overflow-x: clip; }
.cs--center .cs-nav { z-index: 6; }

/* sheet background is a layer that bleeds past the column on both sides, so content stays in the column */
.cs--center .cs-sheet {
  margin-inline: 0; padding-inline: 0; background: none; box-shadow: none; border-radius: 0;
  isolation: isolate;
}
.cs--center .cs-sheet::before {
  content: ""; position: absolute; z-index: -1; inset: 0 -100vw;
  background: var(--sheet-bg);
  border-radius: clamp(24px, 4vw, 48px) clamp(24px, 4vw, 48px) 0 0;
  box-shadow: 0 -18px 40px -24px rgba(25, 28, 26, .18);
}
html.in-modal .cs--center .cs-sheet { padding-inline: 0; }
/* side nav stays readable on any colour */
.cs--center .cs-nav { padding: .85rem 1rem; margin-left: -1rem; background: rgba(244, 245, 241, .92); backdrop-filter: blur(8px); border-radius: 16px; box-shadow: 0 1px 2px rgba(25,28,26,.06), 0 10px 24px -16px rgba(25,28,26,.2); }
@media (max-width: 900px) { .cs--center .cs-nav { margin-left: 0; padding: 0; background: none; box-shadow: none; backdrop-filter: none; } }

/* rounded sheet tops: keep the page background from showing a hard edge */
.cs--center .cs-sheet::before { border-top-left-radius: clamp(28px, 5vw, 56px); border-top-right-radius: clamp(28px, 5vw, 56px); }
.cs--center .cs-sheet { margin-top: calc(clamp(28px, 5vw, 56px) * -1); padding-top: calc(clamp(3rem, 7vw, 6rem) + clamp(28px, 5vw, 56px) * .35); }

/* overlap (beats the older ".cs-section > *" margin reset) and visible rounded corners:
   the colour layer is exactly one viewport wide, positioned from the column edge by --sheet-x (set in main.js) */
.cs.cs--center.cs--story .cs-section > .cs-sheet { margin-top: calc(clamp(28px, 5vw, 56px) * -1); }
.cs.cs--center.cs--story .cs-section > .cs-sheet:first-of-type { margin-top: 0; }
.cs--center .cs-sheet::before { inset: 0 auto 0 calc(var(--sheet-x, 0px) * -1); width: 100vw; }
html.in-modal .cs--center .cs-sheet::before { inset: 0; width: auto; }

/* breathing room between text, questions and pills inside the interviews block */
.cs.cs--center.cs--story .cs-sheet .cs-panel { display: grid; gap: clamp(1.5rem, 3vw, 2.25rem); justify-items: start; }
.cs--center .cs-sheet .cs-panel .cs-pill { justify-self: stretch; }
.cs--center .cs-sheet .cs-panel .cs-q { margin: 0; }
.cs--center .cs-sheet .cs-panel__board { justify-self: stretch; width: 100%; max-width: none; }

/* the centred-column rules above targeted ".cs-section > block"; blocks now live one level deeper, inside ".cs-sheet" */
.cs.cs--center.cs--story .cs-sheet > :is(.cs-two, .cs-fig, .cs-quotes, .cs-fb, .cs-pills, .cs-solo, .cs-methods, .cs-thread, .cs-panel, .cs-atoms) { width: 100%; max-width: 34rem; margin-inline: auto; }
.cs.cs--center.cs--story .cs-sheet > :is(.cs-finals, .cs-bigstats, .cs-testimonies, .cs-pair, .cs-band) { width: 100%; max-width: 48rem; margin-inline: auto; }
.cs.cs--center.cs--story .cs-sheet > .cs-atoms { max-width: 48rem; }
.cs.cs--center.cs--story .cs-sheet > .cs-panel { max-width: 40rem; }
.cs.cs--center.cs--story .cs-sheet > .cs-two {
  grid-template-columns: minmax(0, 1fr); gap: .75rem; justify-items: start; text-align: left; border-top: 0; margin: 0 auto; padding-block: 0;
}
.cs.cs--center.cs--story .cs-sheet > .cs-two--solo { margin-top: 0; }
.cs.cs--center.cs--story .cs-sheet > * + * { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
.cs.cs--center.cs--story .cs-sheet > .cs-two + .cs-two,
.cs.cs--center.cs--story .cs-sheet > :is(.cs-fig, .cs-panel, .cs-pills, .cs-fb, .cs-atoms, .cs-bigstats, .cs-finals, .cs-testimonies) + .cs-two { margin-top: clamp(3rem, 6vw, 4.5rem); }
.cs.cs--center.cs--story .cs-sheet > .cs-two + :is(.cs-fig, .cs-panel, .cs-fb, .cs-atoms, .cs-bigstats, .cs-finals, .cs-testimonies, .cs-pair) { margin-top: 1.5rem; }
.cs.cs--center.cs--story .cs-sheet > :is(.cs-fig, .cs-finals, .cs-bigstats, .cs-testimonies) { padding-block: 0; }
.cs--center .cs-sheet .cs-two__body { max-width: none; }
.cs--center .cs-sheet .cs-two__body p { max-width: none; margin: 0; color: var(--sheet-soft); line-height: var(--lh-body); }
.cs--center .cs-sheet .cs-steps { color: var(--sheet-ink); }

/* ---------- Greenhouse hero: full-colour band with a ghost wordmark (Poliloq-style) ---------- */
.cs--center .cs-heroband {
  --hero-bg: var(--cs-accent); position: relative; isolation: isolate; overflow: visible;
  padding: clamp(2.5rem, 6vw, 4.5rem) 0 clamp(5rem, 9vw, 7.5rem); color: #F4F5F1;
}
.cs--center .cs-heroband::before {
  content: ""; position: absolute; z-index: -2; inset: 0 auto 0 calc(var(--sheet-x, 0px) * -1); width: 100vw;
  background: var(--hero-bg);
}
html.in-modal .cs--center .cs-heroband::before { inset: 0; width: auto; }
.cs--center .cs-hero__ghost {
  position: absolute; z-index: -1; left: -.04em; top: -.12em; pointer-events: none; user-select: none; white-space: nowrap;
  font-size: clamp(5rem, 17vw, 15rem); font-weight: 700; font-stretch: 106%; letter-spacing: -0.04em; line-height: 1;
  color: rgba(255, 255, 255, .09);
}
.cs--center .cs-heroband .cs-head { background: none; padding: 0; }
.cs--center .cs-heroband .cs-head__title { color: #FFFFFF; }
.cs--center .cs-heroband .cs-meta { border-color: rgba(255, 255, 255, .28); }
.cs--center .cs-heroband .cs-meta dt { color: rgba(255, 255, 255, .9); }
.cs--center .cs-heroband .cs-meta dd { color: #FFFFFF; }
.cs--center .cs-heroband .cs-tldr { background: rgba(255, 255, 255, .12); }
.cs--center .cs-heroband .cs-tldr__role { color: #FFFFFF; }
.cs--center .cs-heroband .cs-tldr__stats { border-color: rgba(255, 255, 255, .28); }
.cs--center .cs-heroband .cs-tldr__num, .cs--center .cs-heroband .cs-tldr__cap { color: #FFFFFF; }

/* RBC: the first sheet of the document-builder section slides up over the hero band, like the Greenhouse introduction */
.cs.cs--center.cs--story #document-builder { padding-top: 0; }
.cs.cs--center.cs--story #document-builder.cs-section > .cs-sheet:first-of-type { margin-top: calc(clamp(28px, 5vw, 56px) * -1); }
.cs--center #document-builder > .cs-sheet { z-index: 1; }
/* research screenshots need the wide column to stay readable side by side */
.cs.cs--center.cs--story .cs-sheet > .cs-methods--boxed { max-width: 48rem; }
/* "my role" in the tl;dr is ink by default; on a coloured hero band it must be white */
.cs--center .cs-heroband .cs-tldr__role strong { color: #FFFFFF; }

/* RBC: two research methods as sticker cards (same cards as Greenhouse, two across, with a screenshot inside) */
.cs--center .cs-atoms--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cs--center .cs-atoms--2 .cs-atom .media { width: 100%; background: #FFFFFF; border-radius: calc(var(--cs-radius) * .6); overflow: hidden; }
.cs--center .cs-atoms--2 .cs-atom .media { aspect-ratio: 1588 / 1204; }
.cs--center .cs-atoms--2 .cs-atom:nth-child(2) .media { aspect-ratio: 1566 / 1198; }
.cs--center .cs-atoms--2 .cs-atom .media img { object-fit: contain; }
@media (max-width: 720px) { .cs--center .cs-atoms--2 { grid-template-columns: 1fr; } }
/* RBC: the sketches photo as one polaroid, at the photo's own shape */
.cs.cs--center.cs--story .cs-sheet > .cs-polaroids.cs-polaroids--solo { max-width: 48rem; }
.cs.cs--story .cs-polaroids.cs-polaroids--solo .polaroid:is(:first-child, :last-child) { width: min(100%, 42rem); }
.cs.cs--story .cs-polaroids.cs-polaroids--solo .polaroid:is(:first-child, :last-child) .media { aspect-ratio: 778 / 572; }
/* confidential card takes the page's own tint so it sits on the sheet like the other blocks */
.cs--center .cs-locked { background: var(--cs-band); }
.cs--center .cs-locked__icon { color: var(--cs-accent); }
.cs.cs--center .cs-locked p.cs-locked__note { color: var(--graphite); }

/* IBM: its single sheet slides up over the hero band, like the RBC and Greenhouse first sheets */
.cs.cs--center.cs--story #design-strategy { padding-top: 0; }
.cs.cs--center.cs--story #design-strategy.cs-section > .cs-sheet:first-of-type { margin-top: calc(clamp(28px, 5vw, 56px) * -1); }
.cs--center #design-strategy > .cs-sheet { z-index: 1; }
/* IBM: the header polaroid sits on the band; its frame stays white */
.cs--center .cs-heroband .cs-head__polaroid { color: var(--ink); }

/* the introduction is the first sheet: it slides up over the hero band */
.cs.cs--center.cs--story .cs-section.cs-sheet--intro { margin-top: calc(clamp(28px, 5vw, 56px) * -1); padding-top: calc(clamp(3rem, 7vw, 6rem) + 1rem); padding-bottom: clamp(3rem, 7vw, 6rem); }
.cs.cs--center.cs--story .cs-sheet--intro > .cs-sec-head { padding-top: 0; margin-bottom: 0; }
.cs.cs--center.cs--story .cs-sheet--intro > :is(.cs-photos, .cs-intro, .cs-projects) { padding-block: 0; margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
.cs--center .cs-sheet--intro .cs-intro { color: var(--ink); }
.cs--center .cs-sheet--intro .cs-project p { color: var(--ink); }

/* numbered lists: big accent numerals, like "1 2 3 4" key insights */
.cs--center .cs-sheet .cs-steps { list-style: none; padding: 0; margin: 1.25rem 0 0; counter-reset: step; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.25rem; }
.cs--center .cs-sheet .cs-steps li { counter-increment: step; line-height: 1.4; }
.cs--center .cs-sheet .cs-steps li::before {
  content: counter(step); display: block; margin-bottom: .35rem; color: var(--cs-accent);
  font-size: clamp(2rem, 1.6rem + 1.4vw, 2.75rem); font-weight: 700; font-stretch: 106%; line-height: 1;
}
@media (max-width: 560px) { .cs--center .cs-sheet .cs-steps { grid-template-columns: 1fr; } }

.cs--center .cs-hero__ghost { top: .1em; font-size: clamp(4.5rem, 15vw, 13rem); }
.cs--center .cs-heroband { padding-top: clamp(3.5rem, 7vw, 5.5rem); }
.cs--center .cs-nav { background: rgba(244, 245, 241, .96); }
.cs--center .cs-back { position: relative; z-index: 1; }

/* whole-section sheets (plant milk, reflections, testimonials): same overlap + padding as the intro */
.cs.cs--center.cs--story .cs-section.cs-sheet:not(.cs-sheet--intro) { padding-top: calc(clamp(3rem, 7vw, 6rem) + 1rem); padding-bottom: clamp(3rem, 7vw, 6rem); }
.cs.cs--center.cs--story .cs-section.cs-sheet > .cs-sec-head { padding-top: 0; margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem); }
.cs.cs--center.cs--story .cs-section.cs-sheet > :is(.cs-fig, .cs-pair, .cs-finals, .cs-bigstats, .cs-reflections, .cs-testimonies, .cs-thread, .cs-band) { padding-block: 0; }
.cs--center .cs-next { padding-top: clamp(3rem, 6vw, 5rem); }

/* ---------- Popup: colour bands fill the whole modal, no side nav (for now) ---------- */
html.in-modal .cs--center .cs-nav { display: none; }
html.in-modal .cs.cs--center.cs--story { padding: 0; max-width: none; }
html.in-modal .cs.cs--center.cs--story.wrap { padding-inline: 0; }
html.in-modal .cs.cs--center.cs--story .cs__layout { display: block; }
html.in-modal .cs.cs--center.cs--story .cs__main { max-width: none; }
html.in-modal .cs.cs--center.cs--story .cs-heroband {
  padding: clamp(3rem, 7vw, 5rem) clamp(1.5rem, 6vw, 5rem) clamp(5rem, 9vw, 7.5rem);
}
html.in-modal .cs--center .cs-heroband > :not(.cs-hero__ghost) { max-width: 52rem; margin-inline: auto; }
html.in-modal .cs--center .cs-heroband::before,
html.in-modal .cs--center .cs-sheet::before { inset: 0; width: auto; }
html.in-modal .cs.cs--center.cs--story .cs-section.cs-sheet,
html.in-modal .cs.cs--center.cs--story .cs-sheet {
  padding-inline: clamp(1.5rem, 6vw, 5rem);
}
html.in-modal .cs--center .cs-hero__ghost { left: clamp(1rem, 4vw, 4rem); }
html.in-modal .cs--center .cs-next { padding: clamp(3rem, 6vw, 5rem) clamp(1.5rem, 6vw, 5rem); }
html.in-modal .cs.cs--center.cs--story .cs-heroband { padding-top: clamp(4.5rem, 9vw, 7rem); }
html.in-modal .cs.cs--center.cs--story .cs-sheet > .cs-sec-head,
html.in-modal .cs.cs--center.cs--story .cs-sheet.cs-section > .cs-sec-head { max-width: 52rem; margin-inline: auto; }
html.in-modal .cs.cs--center.cs--story .cs-sheet > :is(.cs-photos, .cs-intro, .cs-projects) { margin-inline: auto; }

/* popup bar now only holds the Close button: keep it on the right */
.cs-modal__bar { justify-content: flex-end; }

/* hero: Greenhouse olive green, with a barely-there ghost wordmark sitting high in the band */
.cs--center .cs-heroband { --hero-bg: var(--cs-hero, #5A6B2E); }
.cs--center .cs-hero__ghost { top: -.28em; color: rgba(255, 255, 255, .045); }

/* "01 Design libraries" title lives inside its first band, same as Introduction and Plant milk */
.cs.cs--center.cs--story .cs-sheet > .cs-sec-head { padding-top: 0; margin: 0 0 clamp(1.75rem, 3.5vw, 2.5rem); max-width: none; }
.cs.cs--center.cs--story .cs-sheet > .cs-sec-head + .cs-two { margin-top: 0; }
.cs.cs--center.cs--story #design-library { padding-top: 0; }

/* interviews band: the dot grid runs across the whole band (edge to edge in the modal), behind the sticky notes */
.cs--center .cs-sheet:has(.cs-panel)::before {
  background-image: radial-gradient(rgba(25, 28, 26, .22) 1.2px, transparent 1.4px);
  background-size: 18px 18px;
  background-position: 9px 9px;
}
.cs--center .cs-sheet .cs-panel__board { background: none; padding: 0; border-radius: 0; }
.cs--center .cs-sheet:has(.cs-panel)::before { background-image: radial-gradient(rgba(25, 28, 26, .09) 1.2px, transparent 1.4px); }
.cs--center .cs-sheet:has(.cs-panel)::before { background-image: radial-gradient(rgba(25, 28, 26, .035) 1.2px, transparent 1.4px); }
.cs--center .cs-sheet:has(.cs-panel)::before { background-image: radial-gradient(rgba(25, 28, 26, .045) 1.2px, transparent 1.4px); }

/* sage bands: give the rounded top the same clear edge the white bands have */
.cs--center .cs-sheet--sage::before {
  box-shadow: 0 -1px 0 rgba(25, 28, 26, .14), 0 -22px 44px -22px rgba(25, 28, 26, .28);
}
.cs--center .cs-sheet--white::before {
  box-shadow: 0 -1px 0 rgba(25, 28, 26, .08), 0 -22px 44px -22px rgba(25, 28, 26, .22);
}
.cs--center .cs-sheet--sage::before {
  box-shadow: 0 -1.5px 0 rgba(25, 28, 26, .2), 0 -24px 48px -22px rgba(25, 28, 26, .34);
}

/* room under each band's content for the next band's rounded top, which overlaps it */
.cs.cs--center.cs--story .cs-sheet,
.cs.cs--center.cs--story .cs-section.cs-sheet:not(.cs-sheet--intro),
.cs.cs--center.cs--story .cs-section.cs-sheet--intro {
  padding-bottom: calc(clamp(3rem, 7vw, 6rem) + clamp(28px, 5vw, 56px));
}
/* edge of each band: a slightly darker green instead of a grey line + grey shadow */
.cs--center .cs-sheet--sage::before {
  box-shadow: 0 -2px 0 #C3CEB0, 0 -22px 40px -24px rgba(63, 107, 42, .22);
}
.cs--center .cs-sheet--white::before {
  box-shadow: 0 -2px 0 #DDE4D2, 0 -22px 40px -24px rgba(63, 107, 42, .16);
}

/* clean edge: no blurred shadow (it faded out at the rounded corners and left a lighter wedge).
   A solid darker-green top border follows the curve exactly, so corners match the straight edge. */
.cs--center .cs-sheet::before { box-shadow: none; border-top: 2px solid #C3CEB0; box-sizing: border-box; }
.cs--center .cs-sheet--white::before { border-top-color: #D3DCC6; }
.cs--center .cs-sheet--sage::before { border-top-color: #BAC7A4; }
html.in-modal .cs--center .cs-sheet::before { border-left: 0; border-right: 0; }

/* corners: each band's colour layer runs on down under the next band, so the area outside the next band's
   rounded top corners shows this band's colour, not the page background */
.cs--center .cs-sheet::before { bottom: calc(clamp(28px, 5vw, 56px) * -1); }
.cs--center .cs-sheet { z-index: 0; }
.cs--center .cs-sheet + .cs-sheet { z-index: 1; }
.cs--center .cs-sheet:nth-of-type(n) { position: relative; }
html.js .cs.cs--center .cs-sheet::before,
html.in-modal .cs.cs--center .cs-sheet::before { bottom: calc(clamp(28px, 5vw, 56px) * -1); }

/* Plant milk: hotel polaroids + solution row */
.cs--story .cs-polaroids { display: flex; justify-content: center; align-items: flex-start; gap: clamp(1rem, 3vw, 2rem); margin-top: clamp(1.25rem, 2.5vw, 1.75rem); }
.cs--story .cs-polaroids .polaroid, .cs--story .cs-solution .polaroid { margin: 0; padding-bottom: .7rem; }
.cs--story .cs-polaroids .polaroid:first-child { width: min(36%, 14rem); }
.cs--story .cs-polaroids .polaroid:last-child { width: min(58%, 22rem); }
.cs--story .cs-polaroids .polaroid .media { aspect-ratio: auto; }
.cs--story .cs-polaroids .polaroid:first-child .media { aspect-ratio: 4 / 5; }
.cs--story .cs-polaroids .polaroid:last-child .media { aspect-ratio: 3 / 2; }
.cs--story .cs-polaroids .polaroid img, .cs--story .cs-solution .polaroid img { object-fit: cover; }
.cs--story .cs-solution { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 14rem); gap: clamp(1.25rem, 3vw, 2.5rem); align-items: center; margin-top: clamp(1.5rem, 3vw, 2.25rem); }
.cs--story .cs-solution .polaroid .media { aspect-ratio: 3 / 4; }
.cs--story .cs-solution__text p { color: var(--graphite); }
.cs--story .cs-solution__text p + p { margin-top: 1rem; }
@media (max-width: 640px) {
  .cs--story .cs-solution { grid-template-columns: 1fr; }
  .cs--story .cs-solution .polaroid { max-width: 14rem; }
}
.cs.cs--center.cs--story .cs-section > :is(.cs-polaroids, .cs-solution) { max-width: 34rem; margin-inline: auto; }

/* spacing fixes: testimonies label vs quote mark, and the plant milk blocks that had no gap */
.cs.cs--center.cs--story .cs-sheet > .cs-two + .cs-testimonies,
.cs.cs--center.cs--story .cs-section.cs-sheet > .cs-two + .cs-testimonies { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.cs--story .cs-testimonies .cs-testimony__mark { margin-top: 0; }
.cs.cs--center.cs--story .cs-section.cs-sheet > :is(.cs-polaroids, .cs-fig) + .cs-pills { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
.cs.cs--center.cs--story .cs-section.cs-sheet > .cs-pills { margin-bottom: 0; }
.cs.cs--center.cs--story .cs-section.cs-sheet > :is(.cs-solution, .cs-polaroids) + .cs-two { margin-top: clamp(3rem, 6vw, 4.5rem); }
.cs.cs--center.cs--story .cs-section.cs-sheet > .cs-polaroids { margin-bottom: 0; }

/* plant milk: now built from stacked sheets like the design libraries, so each part gets the curved top */
.cs.cs--center.cs--story #plant-milk { padding-top: 0; }
.cs--center #plant-milk .cs-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; margin: 1.25rem 0 clamp(1.5rem, 3vw, 2rem); }
.cs--center #plant-milk .cs-steps li, .cs--center #plant-milk .cs-steps li + li { margin-top: 0; }

/* type consistency in the case study: one body size / line height / colour, paragraph gaps, bold in ink */
.cs--center .cs-sheet .cs-two__body :is(p, li),
.cs--center .cs-section .cs-two__body :is(p, li),
.cs--center .cs-fb p,
.cs--center .cs-solution__text p { font-size: var(--t-body, 1.0625rem); line-height: var(--lh-body, 1.55); color: var(--sheet-soft, var(--graphite)); }
.cs--center .cs-two__body p + p,
.cs--center .cs-two__body p + ol,
.cs--center .cs-two__body ol + p,
.cs--center .cs-two__body ul + p { margin-top: clamp(.9rem, 1.6vw, 1.15rem); }
.cs--center .cs-two__body strong,
.cs--center .cs-solution__text strong { color: var(--ink); font-weight: 560; }
.cs--center .cs-sheet .cs-steps li { color: var(--ink); }
/* sheet with a figure caption last: don't leave a huge gap before the next band */
.cs.cs--center.cs--story .cs-sheet > .cs-fig:last-child { margin-bottom: 0; }

/* pills: outlined label pills (h3 / eyebrow) and soft chips (cs-pills p, cs-pill) share one size and padding */
.cs--center .cs-band .cs-eyebrow {
  display: inline-block; margin: 0 0 .75rem; padding: .35rem .9rem;
  font-size: .75rem; line-height: 1.3; font-weight: 560; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink); border: 1px solid var(--ink); border-radius: 999px;
}
.cs--center .cs-sheet .cs-pill,
.cs--center .cs-sheet .cs-pills p {
  padding: .6rem 1.4rem; font-size: .875rem; line-height: 1.5; font-weight: 400; border-radius: 999px;
}
.cs.cs--center.cs--story .cs-band .cs-eyebrow { font-size: .75rem; line-height: 1.3; font-weight: 560; letter-spacing: .08em; padding: .35rem .9rem; }
.cs.cs--center.cs--story .cs-sheet .cs-pill,
.cs.cs--center.cs--story .cs-sheet .cs-pills p { background: #F9F9F9; border: 1px solid var(--rule); color: var(--ink); }
.cs.cs--center.cs--story #plant-milk.cs-section > .cs-sheet:first-of-type { margin-top: calc(clamp(28px, 5vw, 56px) * -1); }
.cs--center #plant-milk > .cs-sheet { z-index: 1; }

/* introduction: photos and project cards share the wide column, the welcome text sits in the text column */
.cs.cs--center.cs--story .cs-sheet--intro > :is(.cs-photos, .cs-projects) { width: 100%; max-width: 48rem; margin-inline: auto; }
.cs.cs--center.cs--story .cs-sheet--intro > .cs-intro { width: 100%; max-width: 34rem; margin-inline: auto; text-align: center; font-size: clamp(1.125rem, 1rem + .5vw, 1.375rem); line-height: 1.5; }
.cs.cs--center.cs--story .cs-sheet--intro > .cs-projects { gap: clamp(1rem, 2.5vw, 1.75rem); }
.cs.cs--center.cs--story .cs-sheet--intro > .cs-intro + .cs-projects { margin-top: clamp(2.25rem, 4.5vw, 3.25rem); }

/* interviews panel (01 Conducting user interviews): plain uppercase title, ink text, indented italic quotes, wide outlined pills */
.cs.cs--center.cs--story .cs-sheet .cs-panel { max-width: 40rem; gap: clamp(1.75rem, 3.5vw, 2.5rem); }
.cs.cs--center.cs--story .cs-panel__text { max-width: none; gap: 1.5rem; }
.cs.cs--center.cs--story .cs-panel__text h3 { padding: 0; border: 0; border-radius: 0; font-size: .875rem; letter-spacing: .02em; text-transform: uppercase; }
.cs.cs--center.cs--story .cs-panel__text p { font-size: var(--t-body); line-height: 1.4; color: var(--ink); }
.cs.cs--center.cs--story .cs-panel .cs-q { max-width: none; margin: 0; padding-left: 1.25rem; font-size: clamp(1.0625rem, 1rem + .4vw, 1.3125rem); line-height: 1.35; color: var(--ink); }
.cs.cs--center.cs--story .cs-sheet .cs-panel .cs-pill {
  justify-self: stretch; padding: .85rem 1.5rem; background: #FDFDFB; border: 1px solid var(--ink);
  border-radius: 999px; text-align: center; font-size: var(--t-body); line-height: 1.4; color: var(--ink);
}

/* numbered lists (all case study sections): items align on one baseline, room before and after the list */
.cs--center .cs-sheet .cs-steps { align-items: start; margin: 1.25rem 0 0; row-gap: 1.25rem; }
.cs--center .cs-sheet .cs-steps li, .cs--center .cs-sheet .cs-steps li + li { margin-top: 0; }
.cs--center .cs-two__body .cs-steps + p { margin-top: clamp(1.5rem, 3vw, 2rem); }
.cs--center .cs-two__body p + .cs-steps { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); }

/* workshop recap card: show the whole screenshot at its own shape (no crop), sharp edges of the app card kept */
.cs--story .cs-fig--recap .media { aspect-ratio: 3080 / 768; background: #2a2a2a; }
.cs--story .cs-fig--recap .media img { object-fit: contain; width: 100%; height: 100%; }

/* ticket board screenshot: whole image at its own shape, no crop */
.cs--story .cs-fig--board .media { aspect-ratio: 3352 / 664; background: #F3F2F1; }
.cs--story .cs-fig--board .media img { object-fit: contain; width: 100%; height: 100%; }

/* sticker: a small die-cut illustration with a white outline and a slight tilt, instead of a photo box */
.cs--story .cs-sticker { margin: 1.25rem 0 0; display: flex; justify-content: center; }
.cs--story .cs-sticker svg {
  width: clamp(9rem, 28vw, 12.5rem); height: auto; rotate: -3deg;
  filter: drop-shadow(0 0 0 #fff) drop-shadow(3px 0 0 #fff) drop-shadow(-3px 0 0 #fff) drop-shadow(0 3px 0 #fff) drop-shadow(0 -3px 0 #fff) drop-shadow(0 8px 14px rgba(25, 28, 26, .18));
  transition: rotate .35s var(--ease), transform .35s var(--ease);
}
.cs--story .cs-sticker svg:hover { rotate: 2deg; transform: translateY(-3px); }
@media (prefers-reduced-motion: reduce) { .cs--story .cs-sticker svg { transition: none; } }

/* numbered lists as little sticky notes: pastel paper, slight alternating tilt, soft shadow */
.cs--center .cs-sheet .cs-steps { gap: clamp(.9rem, 2.2vw, 1.4rem); padding: .5rem .25rem .25rem; }
.cs--center .cs-sheet .cs-steps li {
  --note-bg: #F3DF86; --tilt: -2deg;
  position: relative; padding: 1rem 1.1rem 1.15rem;
  background: var(--note-bg); border-radius: 3px;
  box-shadow: 0 1px 2px rgba(25, 28, 26, .1), 0 12px 24px -14px rgba(25, 28, 26, .38);
  rotate: var(--tilt); color: var(--ink); line-height: 1.3;
  transition: rotate .35s var(--ease), translate .35s var(--ease), box-shadow .35s var(--ease);
}
.cs--center .cs-sheet .cs-steps li:nth-child(2) { --note-bg: #F6B9D0; --tilt: 1.5deg; }
.cs--center .cs-sheet .cs-steps li:nth-child(3) { --note-bg: #BFE3CF; --tilt: -1deg; }
.cs--center .cs-sheet .cs-steps li:nth-child(4) { --note-bg: #CDBBEE; --tilt: 2deg; }
.cs--center .cs-sheet .cs-steps li::before { color: var(--ink); margin-bottom: .45rem; font-size: clamp(1.75rem, 1.4rem + 1.2vw, 2.4rem); }
.cs--center .cs-sheet .cs-steps li:hover { rotate: 0deg; translate: 0 -4px; box-shadow: 0 2px 4px rgba(25, 28, 26, .1), 0 18px 30px -14px rgba(25, 28, 26, .4); }
@media (prefers-reduced-motion: reduce) { .cs--center .cs-sheet .cs-steps li { transition: none; } }

/* metric cards as tilted sticky notes (same soft green as before) */
.cs--story .cs-bigstats { padding: .75rem .25rem .5rem; gap: clamp(1rem, 2.4vw, 1.6rem); }
.cs--story .cs-bigstats .cs-bigstat {
  --tilt: -2deg;
  position: relative;               /* anchors the hover bridge */
  border-radius: 3px; rotate: var(--tilt);
  box-shadow: 0 1px 2px rgba(25, 28, 26, .1), 0 12px 24px -14px rgba(25, 28, 26, .38);
  transition: rotate .35s var(--ease), translate .35s var(--ease), box-shadow .35s var(--ease);
}
.cs--story .cs-bigstats .cs-bigstat:nth-child(2) { --tilt: 1.5deg; }
.cs--story .cs-bigstats .cs-bigstat:nth-child(3) { --tilt: -1deg; }
.cs--story .cs-bigstats .cs-bigstat:hover { rotate: 0deg; translate: 0 -4px; box-shadow: 0 2px 4px rgba(25, 28, 26, .1), 0 18px 30px -14px rgba(25, 28, 26, .4); }
@media (max-width: 720px) { .cs--story .cs-bigstats .cs-bigstat { rotate: calc(var(--tilt) * .6); } }
@media (prefers-reduced-motion: reduce) { .cs--story .cs-bigstats .cs-bigstat { transition: none; } }

/* ---- fixes after the plant milk sheets split ---- */
/* hotel polaroids + solution row now live inside sheets, so cap them like the other blocks */
.cs.cs--center.cs--story .cs-sheet > :is(.cs-polaroids, .cs-solution) { width: 100%; max-width: 34rem; margin-inline: auto; }
.cs.cs--center.cs--story .cs-sheet > .cs-solution { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
/* stacking: later sections sit above the plant milk sheets (so their curved tops and titles are not covered) */
.cs--center #testimonials.cs-sheet { z-index: 3; }
/* paragraph gap inside text blocks (the sheet rule was zeroing it) */
.cs.cs--center.cs--story .cs-sheet .cs-two__body p + p { margin-top: clamp(.9rem, 1.6vw, 1.15rem); }

/* quote mark as a sticker: round pastel badge, white die-cut edge, slight tilt */
.cs--story .cs-testimonies .cs-testimony__mark {
  display: grid; place-items: center; align-self: start;
  width: clamp(3.75rem, 7vw, 5rem); aspect-ratio: 1; margin: 0; padding-top: .2em;
  font-size: clamp(3.25rem, 6vw, 4.5rem); line-height: 1; color: var(--ink);
  background: #F3DF86; border: 4px solid #fff; border-radius: 50%;
  box-shadow: 0 1px 2px rgba(25, 28, 26, .12), 0 10px 20px -10px rgba(25, 28, 26, .4);
  rotate: -8deg; transition: rotate .35s var(--ease), translate .35s var(--ease);
}
.cs--story .cs-testimonies .cs-testimony:nth-child(2) .cs-testimony__mark { background: #F6B9D0; rotate: 6deg; }
.cs--story .cs-testimonies .cs-testimony:nth-child(3) .cs-testimony__mark { background: #BFE3CF; rotate: -5deg; }
.cs--story .cs-testimonies .cs-testimony:hover .cs-testimony__mark { rotate: 0deg; translate: 0 -3px; }
@media (prefers-reduced-motion: reduce) { .cs--story .cs-testimonies .cs-testimony__mark { transition: none; } }
.cs--center .cs-sheet .cs-solution__text p { color: var(--sheet-soft, var(--graphite)); }

/* research method cards: spacing */
.cs--center .cs-atom { justify-items: start; gap: 1.1rem; padding: clamp(1.1rem, 2.5vw, 1.6rem); }

/* intro photos as polaroids: white frame, handwritten caption, alternating tilt */
.cs--story .cs-photos--polaroids { align-items: start; gap: clamp(.75rem, 2vw, 1.5rem); padding-top: .5rem; }
.cs--story .cs-photos--polaroids .polaroid { margin: 0; padding: .6rem .6rem 0; }
.cs--story .cs-photos--polaroids .polaroid .media { aspect-ratio: 1 / 1; border-radius: 2px; }
.cs--story .cs-photos--polaroids .polaroid__cap { padding: .6rem .25rem .8rem; font-size: clamp(1.05rem, .9rem + .5vw, 1.35rem); }
@media (max-width: 640px) { .cs--story .cs-photos--polaroids { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .5rem; } .cs--story .cs-photos--polaroids .polaroid { padding: .35rem .35rem 0; } .cs--story .cs-photos--polaroids .polaroid__cap { font-size: .9rem; padding-bottom: .5rem; } }

/* reflections sketch: whole page visible at its own shape, no crop */
.cs--story .cs-fig--sketch .media { aspect-ratio: 3512 / 2468; background: #F4F2EE; }
.cs--story .cs-fig--sketch .media img { object-fit: contain; width: 100%; height: 100%; }

/* label pills line up with the wide block under them (cards, notes, testimonies, final images); body text stays in the text column */
.cs.cs--center.cs--story .cs-sheet > .cs-two:has(+ :is(.cs-atoms, .cs-bigstats, .cs-testimonies, .cs-finals, .cs-pair)) { max-width: 48rem; }
.cs.cs--center.cs--story .cs-sheet > .cs-two:has(+ :is(.cs-atoms, .cs-bigstats, .cs-testimonies, .cs-finals, .cs-pair)) .cs-two__body { max-width: 34rem; }
.cs.cs--center.cs--story .cs-sheet > .cs-two:has(+ :is(.cs-atoms, .cs-bigstats, .cs-testimonies, .cs-finals, .cs-pair)) + * { margin-top: clamp(1.5rem, 3vw, 2rem); }

/* "01 Conducting user interviews" is a pill like every other label */
.cs.cs--center.cs--story .cs-panel__text h3 {
  justify-self: start; width: fit-content;
  padding: .35rem .9rem; border: 1px solid var(--ink); border-radius: 999px;
  font-size: .75rem; font-weight: 560; letter-spacing: .08em; line-height: 1.3; text-transform: uppercase; color: var(--ink);
}

/* page stack: click the top page and it flicks away, the next one comes forward (like shuffling papers) */
.cs--story .cs-deck { --deck-n: 4; }
.cs--story .cs-deck__stage {
  position: relative; width: calc(100% - 2rem); aspect-ratio: 1205 / 1081; cursor: pointer;
  margin-bottom: 1.75rem; -webkit-tap-highlight-color: transparent; outline-offset: 6px; border-radius: var(--cs-radius);
}
.cs--story .cs-deck__page {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  background: #fff; border-radius: var(--cs-radius); outline: 1px solid var(--rule); outline-offset: -1px;
  box-shadow: 0 1px 2px rgba(25, 28, 26, .08), 0 14px 28px -16px rgba(25, 28, 26, .35);
  z-index: calc(var(--deck-n) - var(--i, 0));
  transform: translate(calc(var(--i, 0) * .5rem), calc(var(--i, 0) * .45rem)) rotate(calc(var(--i, 0) * 1.1deg));
  transform-origin: 20% 90%;
  transition: transform .62s cubic-bezier(.4, 0, .2, 1);
  user-select: none; -webkit-user-drag: none;
}
.cs--story .cs-deck__page.is-leaving { transform: translate(28%, 1%) rotate(2.2deg); transition: transform .2s ease-out; }
.cs--story .cs-deck__page.is-jump { transition: none; }
.cs--story .cs-deck__stage:hover .cs-deck__page[style*="--i: 0"]:not(.is-leaving) { transform: translate(-2px, -4px) rotate(-.4deg); }
.cs--story .cs-deck__stage:focus-visible { outline: 2px solid var(--ink); }
.cs.cs--center.cs--story .cs-sheet > .cs-deck { max-width: 48rem; }
@media (prefers-reduced-motion: reduce) { .cs--story .cs-deck__page { transition: none; } }
.cs.cs--center.cs--story .cs-sheet > .cs-deck { width: 100%; max-width: 34rem; margin-inline: auto; }
.cs--story .cs-deck__stage { margin-bottom: 3rem; }
.cs--story .cs-deck figcaption { margin-top: 0; }

/* interviews: the questions are outlined pills with a little question-mark sticker on the side, the explanations are plain text */
.cs.cs--center.cs--story .cs-panel .cs-qrow { position: relative; justify-self: stretch; margin: 0; padding-right: clamp(2.25rem, 5vw, 3.25rem); }
.cs.cs--center.cs--story .cs-panel .cs-qpill {
  margin: 0; padding: .9rem 1.5rem; background: #FDFDFB; border: 1px solid var(--ink); border-radius: 999px;
  font-size: var(--t-body); line-height: 1.4; font-style: italic; color: var(--ink); text-align: left;
}
.cs.cs--center.cs--story .cs-panel .cs-qsticker {
  position: absolute; aspect-ratio: 100 / 120; overflow: visible; right: 0; top: 50%; width: clamp(2.6rem, 6vw, 3.6rem); height: auto;
  translate: 0 -50%; rotate: 9deg; filter: drop-shadow(0 4px 5px rgba(25, 28, 26, .2));
  transition: rotate .35s var(--ease), translate .35s var(--ease); pointer-events: none;
}
.cs.cs--center.cs--story .cs-panel .cs-qrow--1 .cs-qsticker { rotate: -8deg; }
.cs.cs--center.cs--story .cs-panel .cs-qrow--2 .cs-qsticker { rotate: 6deg; }
.cs.cs--center.cs--story .cs-panel .cs-qrow:hover .cs-qsticker { rotate: 0deg; translate: 0 calc(-50% - 3px); }
.cs.cs--center.cs--story .cs-panel .cs-panel__line { margin: 0; color: var(--ink); font-size: var(--t-body); line-height: 1.4; text-align: left; }
@media (prefers-reduced-motion: reduce) { .cs.cs--center.cs--story .cs-panel .cs-qsticker { transition: none; } }

/* ================================================================
   Stickers built from plain HTML + CSS (no images, no SVG).
   Shared look: ink outline, white die-cut edge, soft shadow.
   ================================================================ */
.cs--story {
  --gh-ink: #191C1A;
  --gh-edge: #FFFFFF;
  --gh-shadow: drop-shadow(0 6px 8px rgba(25, 28, 26, .2));
}

/* ---- research method discs ---- */
.cs--center .cs-atom { justify-items: start; }
.gh-disc {
  --d: clamp(4.5rem, 9vw, 5.75rem);
  position: relative; display: block; width: var(--d); height: var(--d); margin: .25rem 0 .25rem .25rem;
  border-radius: 50%; background: var(--bg);
  box-shadow: 0 0 0 4px var(--gh-edge), 0 8px 12px -2px rgba(25, 28, 26, .26);
  font-size: var(--d); rotate: var(--tilt, -4deg);
  transition: rotate .35s var(--ease), translate .35s var(--ease);
}
.gh-disc * { box-sizing: border-box; }
.cs--center .cs-atom:nth-child(2) .gh-disc { --tilt: 3deg; }
.cs--center .cs-atom:nth-child(3) .gh-disc { --tilt: -2deg; }
.cs--center .cs-atom:hover .gh-disc { rotate: 0deg; translate: 0 -3px; }

/* eye (digital shadowing): an almond cut with clip-path (ink outline + white lens), an iris and a highlight */
.gh-eye { position: absolute; left: .12em; top: .29em; width: .76em; height: .42em; display: block; }
.gh-eye::before, .gh-eye::after { content: ""; position: absolute; clip-path: polygon(0.0% 50.0%, 3.6% 42.2%, 7.1% 36.1%, 10.7% 30.5%, 14.3% 25.4%, 17.9% 20.8%, 21.4% 16.5%, 25.0% 12.8%, 28.6% 9.4%, 32.1% 6.6%, 35.7% 4.2%, 39.3% 2.4%, 42.9% 1.1%, 46.4% 0.3%, 50.0% 0.0%, 53.6% 0.3%, 57.1% 1.1%, 60.7% 2.4%, 64.3% 4.2%, 67.9% 6.6%, 71.4% 9.4%, 75.0% 12.8%, 78.6% 16.5%, 82.1% 20.8%, 85.7% 25.4%, 89.3% 30.5%, 92.9% 36.1%, 96.4% 42.2%, 100.0% 50.0%, 96.4% 57.8%, 92.9% 63.9%, 89.3% 69.5%, 85.7% 74.6%, 82.1% 79.2%, 78.6% 83.5%, 75.0% 87.2%, 71.4% 90.6%, 67.9% 93.4%, 64.3% 95.8%, 60.7% 97.6%, 57.1% 98.9%, 53.6% 99.7%, 50.0% 100.0%, 46.4% 99.7%, 42.9% 98.9%, 39.3% 97.6%, 35.7% 95.8%, 32.1% 93.4%, 28.6% 90.6%, 25.0% 87.2%, 21.4% 83.5%, 17.9% 79.2%, 14.3% 74.6%, 10.7% 69.5%, 7.1% 63.9%, 3.6% 57.8%); }
.gh-eye::before { inset: 0; background: var(--gh-ink); }
.gh-eye::after { inset: .045em .06em; background: #fff; }
.gh-eye i { position: absolute; left: 50%; top: 50%; z-index: 1; width: .25em; height: .25em; margin: -.125em 0 0 -.125em; border-radius: 50%; background: var(--gh-ink); }
.gh-eye i::after { content: ""; position: absolute; left: .125em; top: .045em; width: .06em; height: .06em; border-radius: 50%; background: #fff; }

/* ---- question marks: a real "?" character, filled, with an ink outline and a white sticker edge ---- */
.cs.cs--center.cs--story .cs-panel .cs-qsticker {
  position: absolute; right: .35rem; top: 50%; width: auto; height: auto; aspect-ratio: auto; overflow: visible; translate: 0 -50%;
  font: 800 clamp(2.9rem, 6.5vw, 4rem)/1 "Archivo", system-ui, sans-serif; font-stretch: 100%;
  color: var(--c, #F3DF86); background: none; user-select: none; rotate: 9deg;
  -webkit-text-stroke: .1em var(--gh-ink); paint-order: stroke fill;
  filter: drop-shadow(0 0 0 #fff) drop-shadow(.04em 0 0 #fff) drop-shadow(-.04em 0 0 #fff) drop-shadow(0 .04em 0 #fff) drop-shadow(0 -.04em 0 #fff) drop-shadow(0 4px 5px rgba(25, 28, 26, .22));
}

/* ---- quote marks: real quote characters in a heavy serif, white sticker edge ---- */
.cs--story .cs-testimonies .cs-testimony__mark,
.cs--story .cs-testimonies .cs-testimony:nth-child(2) .cs-testimony__mark,
.cs--story .cs-testimonies .cs-testimony:nth-child(3) .cs-testimony__mark {
  display: block; width: auto; aspect-ratio: auto; height: auto; padding: 0 .06em 0 0; margin: 0; overflow: visible;
  font: 900 clamp(6.5rem, 12vw, 9rem)/.7 Georgia, "Times New Roman", serif; color: var(--gh-ink);
  background: none; border: 0; border-radius: 0; box-shadow: none; -webkit-text-stroke: .02em var(--gh-ink);
  text-shadow: .035em 0 0 var(--gh-edge), -.035em 0 0 var(--gh-edge), 0 .035em 0 var(--gh-edge), 0 -.035em 0 var(--gh-edge), .025em .025em 0 var(--gh-edge), -.025em -.025em 0 var(--gh-edge), .025em -.025em 0 var(--gh-edge), -.025em .025em 0 var(--gh-edge);
  filter: var(--gh-shadow); rotate: -6deg; user-select: none;
}

/* ---- two people at a table: chunky sticker figures made from a few rounded blocks ---- */
.cs--story .cs-sticker { margin: 1.25rem 0 0; display: flex; justify-content: center; }
.gh-meet {
  --u: clamp(9.5rem, 30vw, 13rem); --lw: .028em; position: relative; width: var(--u); aspect-ratio: 5 / 4; font-size: var(--u);
  rotate: -3deg; transition: rotate .35s var(--ease), translate .35s var(--ease);
  filter: drop-shadow(0 0 0 #fff) drop-shadow(.025em 0 0 #fff) drop-shadow(-.025em 0 0 #fff) drop-shadow(0 .025em 0 #fff) drop-shadow(0 -.025em 0 #fff) var(--gh-shadow);
}
.cs--story .cs-sticker:hover .gh-meet { rotate: 2deg; translate: 0 -3px; }

@media (prefers-reduced-motion: reduce) { .gh-disc, .gh-meet { transition: none; } }
.cs--story .cs-sticker { margin: 1.5rem 0 2.25rem; }

/* ---- stickers redrawn as inline SVG: question marks, chat, loop, and the two-people scene ---- */
.gh-disc svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; overflow: visible; }

/* question marks: a stroked hook with a separate dot, coloured fill, ink outline, then a white die-cut edge */
.cs.cs--center.cs--story .cs-panel .cs-qsticker {
  width: clamp(2.1rem, 4.6vw, 2.9rem); height: auto; aspect-ratio: 60 / 90;
  font: inherit; -webkit-text-stroke: 0; paint-order: normal;
  filter:
    drop-shadow(2px 0 0 var(--gh-ink)) drop-shadow(-2px 0 0 var(--gh-ink)) drop-shadow(0 2px 0 var(--gh-ink)) drop-shadow(0 -2px 0 var(--gh-ink))
    drop-shadow(1.5px 1.5px 0 var(--gh-ink)) drop-shadow(-1.5px -1.5px 0 var(--gh-ink)) drop-shadow(1.5px -1.5px 0 var(--gh-ink)) drop-shadow(-1.5px 1.5px 0 var(--gh-ink))
    drop-shadow(3px 0 0 #fff) drop-shadow(-3px 0 0 #fff) drop-shadow(0 3px 0 #fff) drop-shadow(0 -3px 0 #fff)
    drop-shadow(0 4px 5px rgba(25, 28, 26, .22));
}
.cs-qsticker svg { display: block; width: 100%; height: 100%; overflow: visible; }
.cs-qsticker .q-line { fill: none; stroke: var(--c, #F3DF86); stroke-width: 9; stroke-linecap: round; }
.cs-qsticker .q-dot { fill: var(--c, #F3DF86); }

/* two people at a table */
.gh-meet { aspect-ratio: 200 / 170; margin-bottom: 0; }
.gh-meet svg { display: block; width: 100%; height: 100%; overflow: visible; }
