/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, h4, p, ul, li { margin: 0; padding: 0; list-style: none; }
button, input, textarea, select { font: inherit; border: none; background: none; cursor: pointer; }
img { display: block; }

/* Host Grotesk is the default on everything, including dynamic content.
   Detail/label type opts into Geist Mono via .mono or --font-mono. */
*, *::before, *::after {
  font-family: "Host Grotesk", -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif;
}

/* ── Variables ── */
:root {
  --bg:           #e8e3dc;
  --text:         #111111;
  --text-2:       #8a8078;
  --border:       transparent;
  --card-bg:      transparent;
  --warm-shadow:  rgba(148, 133, 116, 0.28);
  --font:         "Host Grotesk", -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono:    "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --ease:         cubic-bezier(0.25, 0.1, 0.25, 1);
}

/* ── Detail type ──
   Small uppercase labels, metadata, captions and numeric detail run in Geist Mono.
   Everything else stays in Host Grotesk. */
.cs-eyebrow, .cs-fact-k, .cs-label, .cs-cap, .cs-stat-l, .cs-quote-by,
.cs-scroll-url, .modal-tag, .photo-label, .paper-footer, .hint,
.wordmark, .mode-btn, .filter-btn, .toast, .mono {
  font-family: var(--font-mono);
  font-weight: 400;
}

/* ── Base ── */
html, body {
  width: 100%; height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

/* ── Chrome ── */
.chrome {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 26px 32px;
  pointer-events: none;
}

.wordmark {
  font-family: var(--font);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text);
  pointer-events: auto;
}

/* ── Mode Toggle ── */
.mode-toggle {
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 4px;
  background: rgba(232, 227, 220, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: none;
  border-radius: 100px;
  pointer-events: auto;
  box-shadow: 0 2px 20px rgba(148,133,116,0.18);
}

/* ── Work filter — glass pill ── */
.filter {
  position: absolute;
  left: 50%;
  top: 22px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border-radius: 100px;
  pointer-events: auto;

  /* Glass: a light wash over whatever the canvas is doing underneath, a bright
     top edge for the lit rim, and a soft drop to lift it off the page. */
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.55),
    rgba(255, 255, 255, 0.28)
  );
  backdrop-filter: blur(20px) saturate(1.7);
  -webkit-backdrop-filter: blur(20px) saturate(1.7);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.85) inset,
    0 0 0 1px rgba(255, 255, 255, 0.45) inset,
    0 8px 28px rgba(120, 104, 84, 0.16),
    0 2px 6px rgba(120, 104, 84, 0.10);
}

/* The travelling highlight that sits under the live option. */
.filter-thumb {
  position: absolute;
  top: 4px;
  left: 0;
  height: calc(100% - 8px);
  border-radius: 100px;
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.98),
    rgba(255, 255, 255, 0.86)
  );
  box-shadow:
    0 1px 2px rgba(120, 104, 84, 0.18),
    0 0 0 1px rgba(255, 255, 255, 0.7) inset;
  /* A touch of overshoot so it arrives with some life rather than easing flat. */
  transition:
    transform 0.52s cubic-bezier(0.34, 1.42, 0.52, 1),
    width     0.52s cubic-bezier(0.34, 1.42, 0.52, 1);
  will-change: transform, width;
}

.filter-btn {
  position: relative;
  z-index: 1;
  padding: 7px 17px;
  border-radius: 100px;
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(20, 18, 15, 0.46);
  white-space: nowrap;
  transition: color 0.34s var(--ease), transform 0.2s var(--ease);
}
.filter-btn:hover      { color: rgba(20, 18, 15, 0.78); }
.filter-btn:active     { transform: scale(0.95); }
.filter-btn.active     { color: var(--text); }

@media (prefers-reduced-motion: reduce) {
  .filter-thumb { transition: none; }
}

/* Cross-fade while the canvas is re-laid under the new filter. */
.artboard {
  transition: opacity 0.22s var(--ease);
}
.artboard.swapping {
  opacity: 0;
}

/* ── Phone: case-study controls ──
   The overlay is the scroll container, so controls sitting in the flow scroll
   away and leave no way out once you're reading. Pin them to the viewport's
   top-right instead, above the content, so the close is always reachable. */
@media (max-width: 700px) {
  .modal-overlay .modal-frame { padding: 68px 20px 64px; }

  /* NOTE: these five carry a `body ` prefix on purpose. Their base rules are
     defined further down the file, and a media query adds no specificity — so
     at equal specificity the later base rule wins and every override here was
     being silently discarded. The prefix (0,1,1 vs 0,1,0) makes them stick
     regardless of order. The .chrome/.wordmark/.filter rules below need no
     prefix: their base rules appear above this block. */
  body .modal-controls {
    position: fixed;
    top: 12px;
    right: 12px;
    margin-bottom: 0;
    z-index: 210;
  }
  body .modal-ctrl-btn {
    width: 38px;
    height: 38px;
    /* Reads against whatever scrolls under it. */
    background: rgba(240, 236, 230, 0.82);
    backdrop-filter: blur(18px) saturate(1.5);
    -webkit-backdrop-filter: blur(18px) saturate(1.5);
    box-shadow:
      0 0 0 1px rgba(255, 255, 255, 0.5) inset,
      0 4px 16px rgba(120, 104, 84, 0.20);
  }

  /* The colour behind the photo — and the box you can see. .card-aura clips a
     blurred copy of the thumbnail with overflow:hidden, so on its own it is a
     rectangle of colour with four straight sides. Blurring it does not help:
     the clip happens first, so the blur just softens a rectangle.

     Masking it to an ellipse whose radii are 50% (the gradient then reaching
     zero exactly on the edge midpoints, with the corners falling outside it
     entirely) leaves a glow with no sides at all — an orb around the photo
     rather than a panel behind it. */
  body .card-aura {
    inset: -46px;
    filter: blur(34px) saturate(1.85) opacity(0.52);
    -webkit-mask-image: radial-gradient(
      ellipse 50% 50% at 50% 50%,
      black 0%,
      rgba(0, 0, 0, 0.88) 32%,
      rgba(0, 0, 0, 0.52) 56%,
      rgba(0, 0, 0, 0.20) 76%,
      transparent 100%
    );
    mask-image: radial-gradient(
      ellipse 50% 50% at 50% 50%,
      black 0%,
      rgba(0, 0, 0, 0.88) 32%,
      rgba(0, 0, 0, 0.52) 56%,
      rgba(0, 0, 0, 0.20) 76%,
      transparent 100%
    );
  }
  body .item-card:hover .card-aura { filter: blur(30px) saturate(2) opacity(0.6); }
}

/* Phone chrome: a centred pill collides with the wordmark on a narrow screen,
   so hand it back to the flex row — name left, filter right. That keeps the
   full wordmark down to 320px instead of abbreviating it. */
@media (max-width: 700px) {
  .chrome     { padding: 14px 14px; gap: 10px; }
  /* The name yields before the filter does: if a screen is ever too narrow for
     both, it truncates rather than shoving the pill off the edge. */
  .wordmark   {
    font-size: 9.5px; letter-spacing: 0.13em;
    flex: 0 1 auto; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  /* Out of the absolutely-centred position and back into the row, so the two
     can never sit on top of each other however narrow it gets. */
  .filter     { position: static; transform: none; padding: 3px; flex: 0 0 auto; }
  .filter-btn { padding: 7px 10px; font-size: 9.5px; letter-spacing: 0.07em; }
}

/* TEMPORARY — work/personal toggle hidden for launch.
   Personal mode (photos + essays) isn't finished; the site stays in work mode
   via body[data-mode="work"] in index.html.
   To restore: delete this one rule. Markup and JS are untouched. */
.mode-toggle { display: none; }

.mode-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 100px;
  color: var(--text-2);
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}

.mode-btn.active {
  background: var(--text);
  color: var(--bg);
}

.mode-btn:not(.active):hover {
  background: rgba(0, 0, 0, 0.06);
  color: var(--text);
}

/* ── Gradient field ── */
/*
  Sand/beige/grey is the base. Blobs are near-neutral warm shifts
  — slight amber, rose, sage, and cool-grey variations of #e8e3dc.
  Nothing saturated. Each blob covers the full screen so they
  merge into one cohesive breathing gradient with no gaps.
*/
.gradient-field {
  position: fixed;
  inset: -300px;
  z-index: 0;
  pointer-events: none;
  filter: blur(120px);
  opacity: 0;
  animation: gradient-reveal 3.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes gradient-reveal {
  0%   { opacity: 0; transform: scale(1.1); }
  100% { opacity: 1; transform: scale(1); }
}

.g-blob {
  position: absolute;
  border-radius: 50%;
  animation: blob-drift var(--dur, 26s) ease-in-out var(--del, 0s) infinite alternate;
}

@keyframes blob-drift {
  from { transform: translate(0, 0) scale(1); }
  to   { transform: translate(var(--tx, 60px), var(--ty, 40px)) scale(var(--sc, 1.08)); }
}

/* warm amber — upper left */
.g-b1 {
  width: 150vmax; height: 140vmax;
  background: radial-gradient(circle, rgba(210,192,162,0.55) 0%, transparent 70%);
  top: -35%; left: -40%;
  --dur:28s; --del:0s; --tx:140px; --ty:100px; --sc:1.1;
}
/* cool grey-blue — upper right */
.g-b2 {
  width: 140vmax; height: 150vmax;
  background: radial-gradient(circle, rgba(178,182,196,0.38) 0%, transparent 70%);
  top: -25%; right: -45%;
  --dur:22s; --del:2s; --tx:-110px; --ty:130px; --sc:1.07;
}
/* base sand fill — centre, strongest blob to anchor the tone */
.g-b3 {
  width: 160vmax; height: 140vmax;
  background: radial-gradient(circle, rgba(225,215,195,0.6) 0%, transparent 70%);
  top: 10%; left: 5%;
  --dur:34s; --del:1s; --tx:90px; --ty:-70px; --sc:1.1;
}
/* dusty rose — lower right */
.g-b4 {
  width: 140vmax; height: 140vmax;
  background: radial-gradient(circle, rgba(205,178,165,0.42) 0%, transparent 70%);
  bottom: -35%; right: -35%;
  --dur:25s; --del:3s; --tx:-100px; --ty:-110px; --sc:1.09;
}
/* warm grey — lower left */
.g-b5 {
  width: 140vmax; height: 150vmax;
  background: radial-gradient(circle, rgba(188,184,176,0.4) 0%, transparent 70%);
  bottom: -40%; left: -40%;
  --dur:24s; --del:1.5s; --tx:120px; --ty:-90px; --sc:1.09;
}
/* soft sage — mid right */
.g-b6 {
  width: 130vmax; height: 130vmax;
  background: radial-gradient(circle, rgba(185,196,182,0.32) 0%, transparent 70%);
  top: 20%; right: -30%;
  --dur:20s; --del:4s; --tx:-80px; --ty:100px; --sc:1.1;
}
/* warm ochre — lower centre, ties everything together */
.g-b7 {
  width: 140vmax; height: 130vmax;
  background: radial-gradient(circle, rgba(215,198,170,0.48) 0%, transparent 70%);
  bottom: -15%; left: 10%;
  --dur:29s; --del:2s; --tx:100px; --ty:-80px; --sc:1.08;
}

/* ── Artboard ── */
.artboard-wrap {
  position: fixed;
  inset: 0;
  overflow: hidden;
  cursor: grab;
  transition: filter 0.7s ease;
}
.artboard-wrap.dragging { cursor: grabbing; }

body.modal-open .artboard-wrap {
  filter: none;
}

/* ── Cursor-lens blur overlay ── */
.blur-overlay {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  backdrop-filter: blur(80px) saturate(0.55) brightness(1.04);
  -webkit-backdrop-filter: blur(80px) saturate(0.55) brightness(1.04);
  /* Falls back to the middle of the screen, which is where touch devices keep
     it — they have no cursor to follow. */
  -webkit-mask-image: radial-gradient(
    circle at var(--cx, 50%) var(--cy, 50%),
    transparent 0px,
    transparent var(--lens-clear, 90px),
    rgba(0,0,0,0.08) var(--lens-1, 150px),
    rgba(0,0,0,0.38) var(--lens-2, 240px),
    rgba(0,0,0,0.78) var(--lens-3, 360px),
    black var(--lens-4, 480px)
  );
  mask-image: radial-gradient(
    circle at var(--cx, 50%) var(--cy, 50%),
    transparent 0px,
    transparent var(--lens-clear, 90px),
    rgba(0,0,0,0.08) var(--lens-1, 150px),
    rgba(0,0,0,0.38) var(--lens-2, 240px),
    rgba(0,0,0,0.78) var(--lens-3, 360px),
    black var(--lens-4, 480px)
  );
  transition: opacity 0.6s ease;
}

/* Phones use the same cursor lens as desktop — that lens is exactly what keeps
   desktop looking right, because it softens everything you are not looking at
   and no card edge ever has to survive on its own. A phone has no cursor, so
   the middle of the screen becomes one: centreLens() pins --cx/--cy there, the
   card you have dragged to the centre stays fully sharp, and everything around
   it falls away. Radii are scaled to a phone so a whole card fits the clear
   spot. */
@media (max-width: 700px) {
  .blur-overlay {
    /* Scaled by the card ratio (185/280 = 0.66) so the lens sits in exactly the
       same relation to a card as it does on desktop.

       This is the whole trick, and getting it wrong is what produced visible
       boxes: desktop's clear radius is 90px against a 280px card, i.e. only
       0.32 of a card, so a card is always WIDER than the sharp spot and its own
       edges necessarily fall in the blurred ring. A phone clear radius of 132px
       against a 185px card was 0.71 of a card — the whole thing fitted inside
       the sharp circle, so every edge rendered crisp. */
    --lens-clear: 59px;
    --lens-1: 99px;
    --lens-2: 159px;
    --lens-3: 238px;
    --lens-4: 317px;
    backdrop-filter: blur(53px) saturate(0.55) brightness(1.04);
    -webkit-backdrop-filter: blur(53px) saturate(0.55) brightness(1.04);
  }
}

.blur-overlay.hidden {
  opacity: 0;
}

.artboard {
  position: absolute;
  top: 0; left: 0;
  will-change: transform;
  transform-origin: 0 0;
}

/* ── Artboard Items ── */
@keyframes artboard-float {
  0%, 100% { transform: translateY(0px);    }
  50%       { transform: translateY(-13px); }
}

.artboard-item {
  position: absolute;
  animation: artboard-float var(--float-dur, 8s) ease-in-out var(--float-delay, 0s) infinite;
}

/* ── Work Cards (image only) ── */
.item-card {
  /* Set from computeGeometry() so the layout maths and the rendered card can
     never disagree about how wide a card is. */
  width: var(--card-w, 280px);
  background: transparent;
  border: none;
  border-radius: 0;
  overflow: visible;
  cursor: pointer;
  user-select: none;
  -webkit-user-drag: none;
  position: relative;
}

/* Blurred image aura — pulls the photo's own colors into a soft halo */
.card-aura {
  position: absolute;
  inset: -56px;
  z-index: 0;
  overflow: hidden;
  filter: blur(36px) saturate(1.8) opacity(0.52);
  pointer-events: none;
  transition: filter 0.4s var(--ease);
}

.card-aura img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.12);
  display: block;
}

.item-card:hover .card-aura {
  filter: blur(26px) saturate(2) opacity(0.64);
}

/* Main image — fades into the aura at all edges */
.card-img {
  position: relative;
  z-index: 1;
  width: 100%;
  /* Height tracks the card so shrinking it on a phone shrinks both axes —
     a fixed height here is what left mobile cards 190x210 and crowding. */
  height: var(--card-h, 210px);
  object-fit: cover;
  display: block;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(
    ellipse 82% 80% at 50% 50%,
    black 18%,
    rgba(0,0,0,0.82) 38%,
    rgba(0,0,0,0.42) 58%,
    rgba(0,0,0,0.08) 76%,
    transparent 100%
  );
  mask-image: radial-gradient(
    ellipse 82% 80% at 50% 50%,
    black 18%,
    rgba(0,0,0,0.82) 38%,
    rgba(0,0,0,0.42) 58%,
    rgba(0,0,0,0.08) 76%,
    transparent 100%
  );
  transition: transform 0.38s var(--ease);
}

.item-card:hover .card-img {
  transform: scale(1.04);
}

/* ── Photo Cards (personal) ── */
.item-photo {
  width: 252px;
  background: transparent;
  border: none;
  border-radius: 0;
  overflow: visible;
  cursor: pointer;
  user-select: none;
  position: relative;
}

.item-photo .card-aura { inset: -36px; }

.item-photo .card-img {
  width: 100%;
  height: 220px;
  object-fit: cover;
  display: block;
  pointer-events: none;
  position: relative;
  z-index: 1;
  -webkit-mask-image: radial-gradient(
    ellipse 82% 80% at 50% 50%,
    black 18%,
    rgba(0,0,0,0.82) 38%,
    rgba(0,0,0,0.42) 58%,
    rgba(0,0,0,0.08) 76%,
    transparent 100%
  );
  mask-image: radial-gradient(
    ellipse 82% 80% at 50% 50%,
    black 18%,
    rgba(0,0,0,0.82) 38%,
    rgba(0,0,0,0.42) 58%,
    rgba(0,0,0,0.08) 76%,
    transparent 100%
  );
  transition: transform 0.38s var(--ease);
}

.item-photo:hover .card-img { transform: scale(1.04); }
.item-photo:hover .card-aura { filter: blur(26px) saturate(2) opacity(0.64); }

.item-photo .photo-label {
  padding: 9px 12px 11px;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.45);
  font-family: var(--font);
}

.photo-placeholder {
  width: 100%;
  height: 220px;
  background: linear-gradient(135deg, #2a2926 0%, #1e1d1b 100%);
  display: flex;
  align-items: center;
  justify-content: center;
}

.photo-placeholder span {
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.18);
  font-family: var(--font);
}

/* ── Paper Cards (personal) ── */
.item-paper {
  width: 224px;
  min-height: 306px;
  background: rgba(254,253,251,0.92);
  border: none;
  border-radius: 0;
  padding: 28px 22px 22px;
  display: flex;
  flex-direction: column;
  box-shadow:
    0 8px 32px rgba(148,133,116,0.2),
    0 24px 72px rgba(148,133,116,0.16),
    0 60px 120px rgba(148,133,116,0.1);
  cursor: pointer;
  user-select: none;
  transition: box-shadow 0.32s var(--ease), transform 0.32s var(--ease);
}

.item-paper:hover {
  box-shadow:
    0 12px 44px rgba(148,133,116,0.26),
    0 36px 90px rgba(148,133,116,0.2),
    0 80px 140px rgba(148,133,116,0.14);
}

.paper-rule {
  width: 28px;
  height: 1px;
  background: var(--text);
  margin-bottom: 16px;
  opacity: 0.35;
}

.paper-title {
  font-size: 12.5px;
  font-weight: 400;
  line-height: 1.55;
  color: var(--text);
  letter-spacing: 0.005em;
  flex: 1;
  font-family: var(--font);
}

.paper-excerpt {
  font-size: 10px;
  color: var(--text-2);
  line-height: 1.7;
  margin-top: 14px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.paper-footer {
  margin-top: 20px;
  font-size: 9px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-2);
  opacity: 0.55;
  font-family: var(--font);
}

/* ── Mode Visibility ── */
body[data-mode="work"]     .mode-personal { opacity: 0; pointer-events: none; }
body[data-mode="personal"] .mode-work     { opacity: 0; pointer-events: none; }

.artboard-item { transition: opacity 0.38s var(--ease); }

/* ── Drag hint ── */
.hint {
  position: fixed;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 9.5px;
  font-family: var(--font);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-2);
  pointer-events: none;
  z-index: 50;
  transition: opacity 0.8s ease;
}
.hint.gone { opacity: 0; }

/* ── Modal Overlay ── */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  overflow-y: auto;          /* scroll happens on the overlay, not the inner box */
  -webkit-overflow-scrolling: touch;
  /* Soft veil: keeps long-form type legible while the canvas still reads through */
  background: rgba(232, 227, 220, 0.93);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.55s var(--ease);
  /* hide scrollbar but keep functionality */
  scrollbar-width: none;
}
.modal-overlay::-webkit-scrollbar { display: none; }

.modal-overlay.open {
  opacity: 1;
  pointer-events: auto;
}

/* Centre content within the scrollable overlay */
.modal-overlay .modal-frame {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 100px 60px;
}

/* ── Modal Frame ── */
.modal-frame {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

/* ── Modal Controls (float above top-right corner) ── */
.modal-controls {
  display: flex;
  gap: 6px;
  margin-bottom: 8px;
}

.modal-ctrl-btn {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: rgba(232,227,220,0.88);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.18s var(--ease), color 0.18s var(--ease), transform 0.18s var(--ease);
  box-shadow: 0 2px 14px rgba(148,133,116,0.2);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.modal-ctrl-btn:hover {
  background: var(--text);
  color: var(--bg);
  transform: scale(1.08);
}

/* ── Modal Inner — edgeless, no background box ── */
.modal-inner {
  background: transparent;
  border: none;
  border-radius: 0;
  overflow: visible;
  transform: translateY(20px) scale(0.988);
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.5s ease;
}

.modal-overlay.open .modal-inner {
  transform: translateY(0) scale(1);
}

/* ══════════════════════════════════════════════════════════
   Case Study — editorial layout.
   No panel, no card: every block floats directly on the canvas.
   ══════════════════════════════════════════════════════════ */
.cs-modal {
  width: min(1180px, calc(100vw - 72px));
  --ink:   #14120f;
  --mute:  #7d746a;
  --hair:  rgba(20,18,15,0.14);
  color: var(--ink);
}

/* ── Masthead ── */
.cs-head { padding: 4px 0 0; }

.cs-eyebrow {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mute);
  margin-bottom: 40px;
}
.cs-eyebrow span { white-space: nowrap; }
.cs-eyebrow span + span::before {
  content: '';
  display: inline-block;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: currentColor;
  vertical-align: middle;
  margin-right: 26px;
  opacity: .5;
}

.cs-title {
  font-size: clamp(54px, 7.4vw, 104px);
  font-weight: 500;
  letter-spacing: -0.042em;
  line-height: 0.92;
  margin-bottom: 44px;
  text-wrap: balance;
}

.cs-lede {
  font-size: clamp(19px, 1.6vw, 23px);
  line-height: 1.6;
  letter-spacing: -0.012em;
  color: #322d27;
  max-width: 44ch;
  margin-bottom: 20px;
}

.cs-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 44px;
  padding-top: 34px;
  margin-top: 46px;
  border-top: 1px solid var(--hair);
}
.cs-fact-k {
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mute);
  margin-bottom: 9px;
}
.cs-fact-v { font-size: 14px; line-height: 1.5; max-width: 30ch; }

/* ── Rhythm ── */
.cs-block { margin-top: 118px; }
.cs-block:first-child { margin-top: 84px; }

/* ── Text block ── */
.cs-label {
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mute);
  margin-bottom: 26px;
}
.cs-h {
  font-size: clamp(28px, 3.1vw, 40px);
  font-weight: 500;
  letter-spacing: -0.028em;
  line-height: 1.12;
  max-width: 20ch;
  margin-bottom: 26px;
  text-wrap: balance;
}
.cs-p {
  font-size: 16px;
  line-height: 1.78;
  color: #4a443d;
  max-width: 58ch;
}
.cs-p + .cs-p { margin-top: 18px; }

/* Text set beside a rule, Collins-style two-column */
.cs-split {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 9fr);
  gap: 64px;
  align-items: start;
}
@media (max-width: 860px) { .cs-split { grid-template-columns: 1fr; gap: 28px; } }

/* ── Quote ── */
.cs-quote {
  margin: 0;
  font-size: clamp(26px, 3.2vw, 42px);
  font-weight: 500;
  letter-spacing: -0.032em;
  line-height: 1.22;
  max-width: 22ch;
  text-wrap: balance;
}
.cs-quote-by {
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mute);
  margin-top: 30px;
}

/* ── Stat row ── */
.cs-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 22px 40px;
  border-top: 1px solid var(--hair);
  padding-top: 40px;
}
.cs-stat-n {
  font-size: clamp(38px, 4.4vw, 60px);
  font-weight: 500;
  letter-spacing: -0.045em;
  line-height: 1;
  margin-bottom: 12px;
}
.cs-stat-l {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mute);
  line-height: 1.5;
}

/* ── Media ── */
.cs-media { display: grid; gap: 22px; }
.cs-media.pair  { grid-template-columns: 1fr 1fr; }
.cs-media.trio  { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 760px) {
  .cs-media.pair, .cs-media.trio { grid-template-columns: 1fr; }
}
.cs-media.inset  { width: 78%; margin: 0 auto; }
.cs-media.mid    { width: 58%; margin: 0 auto; }   /* portrait / tall artwork */
.cs-media.narrow { width: 42%; margin: 0 auto; }   /* 9:16 and card formats */
.cs-media.right  { width: 82%; margin-left: auto; }
.cs-media.left   { width: 82%; }
@media (max-width: 760px) {
  .cs-media.inset, .cs-media.mid, .cs-media.narrow,
  .cs-media.right, .cs-media.left { width: 100%; margin: 0; }
}

.cs-fig { margin: 0; min-width: 0; }
.cs-fig img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 5px;
  box-shadow: 0 32px 70px rgba(52,40,26,0.17), 0 6px 18px rgba(52,40,26,0.09);
}
/* Mockups that ship their own shadow + silhouette (phones, cards, fans) */
.cs-fig.float img { border-radius: 0; box-shadow: none; }

.cs-cap {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
  margin-top: 16px;
}

/* ── Live website scroller ── */
.cs-scroll-win {
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 40px 90px rgba(52,40,26,0.20), 0 8px 22px rgba(52,40,26,0.10);
}
.cs-scroll-bar {
  height: 40px;
  background: #eceae5;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 15px;
  position: relative;
}
.cs-scroll-bar i {
  width: 10px; height: 10px;
  border-radius: 50%;
  display: block;
}
.cs-scroll-url {
  position: absolute;
  left: 50%; transform: translateX(-50%);
  font-size: 11px;
  color: #7a756c;
  background: rgba(0,0,0,0.05);
  padding: 4px 48px;
  border-radius: 6px;
}
.cs-scroll-vp { height: 540px; overflow: hidden; position: relative; }
.cs-scroll-vp img {
  width: 100%;
  display: block;
  animation: csScroll 42s cubic-bezier(.65,0,.35,1) infinite alternate;
}
@keyframes csScroll {
  0%,   6%  { transform: translateY(0); }
  94%, 100% { transform: translateY(calc(-100% + 540px)); }
}
@media (prefers-reduced-motion: reduce) {
  .cs-scroll-vp img { animation: none; }
}

/* ── Footer ── */
.cs-foot {
  margin-top: 124px;
  padding-top: 34px;
  border-top: 1px solid var(--hair);
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* ── Personal Modal ── */
.modal-personal {
  width: min(640px, calc(100vw - 60px));
  display: flex;
  flex-direction: column;
  background: transparent;
}

.modal-personal-media {
  background: #111;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 380px;
}

.modal-personal-media img {
  width: 100%;
  max-height: 65vh;
  object-fit: contain;
}

.modal-personal-caption {
  padding: 18px 26px 22px;
  font-size: 11.5px;
  color: var(--text-2);
  letter-spacing: 0.04em;
  line-height: 1.6;
  font-family: var(--font);
  background: rgba(232, 227, 220, 0.82);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

/* ── Tags ── */
.modal-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.modal-tag {
  font-size: 9px;
  font-family: var(--font);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-2);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 5px 9px;
}

/* ── Paper Modal ── */
.modal-paper-content {
  padding: 52px 60px;
  width: min(600px, calc(100vw - 60px));
}

.modal-paper-title {
  font-size: 26px;
  font-weight: 300;
  letter-spacing: -0.02em;
  line-height: 1.25;
  color: var(--text);
  margin-bottom: 22px;
  font-family: var(--font);
}

.modal-paper-body {
  font-size: 14px;
  line-height: 1.82;
  color: var(--text-2);
  font-family: var(--font);
}

/* ── Toast ── */
.toast {
  position: fixed;
  bottom: 28px;
  right: 28px;
  font-size: 11px;
  font-family: var(--font);
  letter-spacing: 0.06em;
  color: var(--bg);
  background: var(--text);
  border-radius: 100px;
  padding: 8px 16px;
  z-index: 300;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.22s ease, transform 0.22s ease;
  pointer-events: none;
}

.toast.show {
  opacity: 1;
  transform: translateY(0);
}
