/* ============================================================
   /work/[slug] — case study template
   Hero · overview · brief · process · outcomes · gallery · related · prev/next
   ============================================================ */

/* Hero ----------------------------------------------------- */
.cs-hero {
  position: relative;
  min-height: 88svh;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: calc(var(--nav-h) + 48px) var(--pad-x) 72px;
  overflow: hidden;
  border-bottom: 1px solid var(--border);
  isolation: isolate;
}
.cs-hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
}
.cs-hero__media img,
.cs-hero__media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: .42;
  transform: scale(1.04);
}
.cs-hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 80% at 50% 100%, rgba(17,17,17,.95), transparent 75%),
    linear-gradient(180deg, rgba(17,17,17,.55), rgba(17,17,17,.8));
}

.cs-hero__body {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-self: end;
  max-width: 1100px;
}
.cs-hero__pills {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.cs-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(0,0,0,.35);
  backdrop-filter: blur(8px);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #e7e7e7;
}
.cs-pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); }
.cs-pill.blue .dot  { background: var(--blue); }
.cs-pill.red .dot   { background: var(--red); }
.cs-pill.cream .dot { background: var(--cream); }

.cs-hero__title {
  font-family: var(--font-display);
  font-weight: var(--heading-weight);
  font-size: clamp(40px, 6.4vw, 108px);
  letter-spacing: -.035em;
  line-height: 1;
  max-width: 20ch;
}

.cs-hero__descriptor {
  font-size: clamp(17px, .6vw + 1rem, 22px);
  line-height: 1.5;
  color: #d6d6d6;
  max-width: 62ch;
}

.cs-hero__scroll {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 32px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}
.cs-hero__scroll .bar {
  width: 1px; height: 42px;
  background: linear-gradient(180deg, var(--muted), transparent);
}

/* -----------------------------------------------------------
   Content sections (overview / brief / what we did / outcomes)
   sit on a LIGHT background to aid long-form legibility.
   Gallery (below) flips back to dark so screens pop.
   ----------------------------------------------------------- */
.cs-content-light {
  background: #fafaf7;
  color: var(--ink);
  --border: #e6e0cb;
}
.cs-content-light + .cs-content-light { border-top: 0; }

/* Overview strip ---------------------------------------- */
.cs-overview {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.cs-overview__cell {
  padding: 28px var(--pad-x);
  border-right: 1px solid var(--border);
  min-width: 0;
}
.cs-overview__cell:last-child { border-right: 0; }
.cs-overview__cell .k {
  font-family: var(--font-mono);
  font-size: 10px;
  color: #7a7360;
  letter-spacing: .18em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.cs-overview__cell .v {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 15px;
  color: var(--ink);
  line-height: 1.35;
  word-break: break-word;
}
.cs-overview__cell .v a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--blue);
  transition: color .2s;
}
.cs-overview__cell .v a:hover { color: var(--ink); }
@media (max-width: 820px) {
  .cs-overview { grid-template-columns: 1fr 1fr; }
  .cs-overview__cell:nth-child(2) { border-right: 0; }
  .cs-overview__cell { border-bottom: 1px solid var(--border); }
  .cs-overview__cell:nth-last-child(-n+1) { border-bottom: 0; }
}
@media (max-width: 480px) {
  .cs-overview { grid-template-columns: 1fr; }
  .cs-overview__cell { border-right: 0; }
  .cs-overview__cell:last-child { border-bottom: 0; }
}

/* Prose sections --------------------------------------- */
.cs-section {
  padding: clamp(72px, 9vw, 140px) var(--pad-x);
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: clamp(32px, 5vw, 96px);
  border-bottom: 1px solid var(--border);
}
.cs-section__head {
  position: sticky;
  top: 90px;
  align-self: start;
}
.cs-section__eye {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #7a7360;
  margin-bottom: 14px;
}
.cs-section__title {
  font-family: var(--font-display);
  font-weight: var(--heading-weight);
  font-size: clamp(32px, 3.2vw + 1rem, 56px);
  letter-spacing: var(--heading-letter-spacing);
  line-height: var(--heading-line-height);
  color: var(--ink);
}
.cs-section__title em { color: #747062; font-style: italic; font-weight: 500; }

.cs-prose {
  font-size: clamp(17px, .4vw + 1rem, 20px);
  line-height: 1.65;
  color: #3f3a2b;
  max-width: 62ch;
}
.cs-prose p + p { margin-top: 1em; }
.cs-prose strong { color: var(--ink); font-weight: 500; }
.cs-prose .sub {
  margin-top: 28px;
  padding-top: 28px;
  border-top: 1px solid var(--border);
  color: #4c4635;
  font-size: clamp(15px, .2vw + 1rem, 17px);
  line-height: 1.6;
}
.cs-prose .sub::before {
  content: "Process";
  display: block;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #7a7360;
  margin-bottom: 8px;
}

@media (max-width: 820px) {
  .cs-section { grid-template-columns: 1fr; }
  .cs-section__head { position: static; }
}

/* Outcomes --------------------------------------------- */
.cs-outcomes {
  padding: clamp(64px, 8vw, 120px) var(--pad-x);
  border-bottom: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: clamp(24px, 3vw, 40px);
}
.cs-outcomes__head {
  display: flex;
  justify-content: space-between;
  align-items: end;
  gap: 24px;
  flex-wrap: wrap;
}
.cs-outcomes__head h2 {
  font-family: var(--font-display);
  font-weight: var(--heading-weight);
  font-size: clamp(36px, 4vw + .5rem, 64px);
  letter-spacing: var(--heading-letter-spacing);
  line-height: var(--heading-line-height);
  max-width: 16ch;
  color: var(--ink);
}
.cs-outcomes__head h2 em { color: #747062; font-style: italic; font-weight: 500; }

.cs-outcomes__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.cs-outcome {
  padding: 36px var(--pad-x);
  border-right: 1px solid var(--border);
  min-width: 0;
}
.cs-outcome:last-child { border-right: 0; }
.cs-outcome__stat {
  font-family: var(--font-display);
  font-weight: var(--heading-weight);
  /* Cap at 44px so longer compound words (Lead-qualification,
     Enterprise-grade, Hardware-paired) don't push past their column.
     Stats wrap naturally at the hyphen when they need a second line. */
  font-size: clamp(28px, 1.8vw + .5rem, 44px);
  letter-spacing: var(--heading-letter-spacing);
  line-height: 1.05;
  /* Ink type on cream keeps the impact in typography, not colour.
     The service accent still shows on hero pills + card borders. */
  color: var(--ink);
  /* Allow wrapping at hyphens (default) and as an emergency break
     for any unhyphenated word longer than the cell width. The label
     row below is line-clamped to 2; stats can also wrap to 2 if a
     compound word demands it without breaking the grid. */
  overflow-wrap: anywhere;
  word-break: normal;
  hyphens: manual;
}
.cs-outcome__label {
  margin-top: 14px;
  font-size: 13.5px;
  line-height: 1.5;
  color: #4c4635;
  max-width: 34ch;
  /* Hard clamp to 2 lines so a long label can never overrun the cell
     and bleed across the column divider into the next outcome. The
     copy is written short — this is the safety net for any future
     outcome that creeps over. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  /* Wrap inside hyphenated tokens (e.g. "g-force") so they break at
     the hyphen instead of pushing past the cell width. */
  overflow-wrap: anywhere;
  word-break: normal;
}
@media (max-width: 960px) {
  .cs-outcomes__grid { grid-template-columns: 1fr 1fr; }
  .cs-outcome:nth-child(2) { border-right: 0; }
  .cs-outcome { border-bottom: 1px solid var(--border); }
  .cs-outcome:nth-last-child(-n+2) { border-bottom: 0; }
}
@media (max-width: 560px) {
  .cs-outcomes__grid { grid-template-columns: 1fr; }
  .cs-outcome { border-right: 0; border-bottom: 1px solid var(--border); }
  .cs-outcome:last-child { border-bottom: 0; }
}

/* Gallery — DARK section so screens pop against the cream content above.
   Section padding follows the page's standard rhythm; items are packed
   tightly with a small, equal gap so the grid reads as one composition.
   ----------------------------------------------------------- */
.cs-gallery {
  --cs-gallery-gap: clamp(12px, 1.2vw, 18px);
  background: var(--bg);
  color: var(--white);
  padding: clamp(80px, 9vw, 140px) var(--pad-x);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.cs-gallery__head {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: clamp(24px, 4vw, 64px);
  margin-bottom: clamp(32px, 4vw, 56px);
  align-items: end;
}
.cs-gallery__head .eye {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}
.cs-gallery__head h2 {
  font-family: var(--font-display);
  font-weight: var(--heading-weight);
  font-size: clamp(32px, 3.2vw + .5rem, 56px);
  letter-spacing: var(--heading-letter-spacing);
  line-height: var(--heading-line-height);
  color: var(--white);
}
.cs-gallery__head h2 em { color: var(--cream); font-style: italic; font-weight: 500; }
@media (max-width: 820px) { .cs-gallery__head { grid-template-columns: 1fr; } }

.cs-gallery__grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  /* Gap is derived from the same token that drives section padding so
     vertical rhythm between items matches the horizontal air at the
     section edges. */
  gap: var(--cs-gallery-gap);
}
/* Figure is a stacked column: media on top (fixed aspect ratio) with
   an optional caption below. Caption is rendered only when the JSON
   supplies one, so figures without a caption stay the same height. */
.cs-gallery__item {
  grid-column: span 6;
  border-radius: 6px;
  overflow: hidden;
  background: #151515;
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  margin: 0;
}
.cs-gallery__item--wide {
  grid-column: span 12;
  /* Wide items used to span the full 12-col grid which on a wide
     laptop or larger meant a single 16:9 hero filled the viewport.
     Cap the visual width of wide items and centre them on the row
     so the media reads as part of an editorial flow rather than a
     window-filling poster. Aspect ratio stays intact end-to-end. */
  max-width: 1180px;
  margin-left: auto;
  margin-right: auto;
  width: 100%;
}

.cs-gallery__media {
  position: relative;
  aspect-ratio: 4/3;
  overflow: hidden;
}
.cs-gallery__item--wide .cs-gallery__media { aspect-ratio: 16/9; }

/* Images and videos share identical treatment by default — only the
   tag differs. Both cover-fit inside the box. Videos override below. */
.cs-gallery__media img,
.cs-gallery__media video {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .6s cubic-bezier(.2,.8,.2,1);
}
.cs-gallery__item:hover .cs-gallery__media img,
.cs-gallery__item:hover .cs-gallery__media video { transform: scale(1.02); }

/* Video items render at their native aspect ratio so nothing gets
   cropped — designers usually frame the demo deliberately and a 16:9
   crop loses the edges. We drop the wrapper's fixed aspect-ratio and
   let the <video> element drive height. Wide videos are width-capped
   by .cs-gallery__item--wide above; this max-height is a safety net
   for an unusually tall portrait video that would still dominate the
   viewport even at the capped width. */
.cs-gallery__item--video .cs-gallery__media {
  aspect-ratio: auto;
  background: #0a0a0a;
}
.cs-gallery__item--video .cs-gallery__media video {
  width: 100%;
  height: auto;
  max-height: 80vh;
  object-fit: contain;
}

/* Caption — optional text slot for highlighting key points.
   Two-part composition: an editorial display-font title that captures
   the point in a few words, then a UI-font sentence underneath that
   explains it. The title catches the eye at scan-speed; the sentence
   pays it off when the reader engages. */
.cs-gallery__caption {
  padding: 16px 20px 18px;
  font-family: var(--font-ui);
  font-size: 13.5px;
  font-weight: 300;
  line-height: 1.55;
  color: #b8b8b8;
  border-top: 1px solid var(--border);
  background: #0f0f0f;
  letter-spacing: var(--body-letter-spacing);
}
.cs-gallery__caption-title {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--heading-weight);
  font-size: clamp(20px, 1.4vw + .25rem, 28px);
  letter-spacing: var(--heading-letter-spacing);
  line-height: 1.1;
  color: var(--white);
  margin-bottom: 10px;
}
.cs-gallery__caption-title em {
  color: var(--cream);
  font-style: italic;
  font-weight: 500;
}
.cs-gallery__caption-body {
  display: block;
}

/* ----------------------------------------------------------
   Side-caption variant (wide items only). When a wide item carries
   a caption, the figure splits into a 2-column flex row: media on
   the left at a constrained width, caption on the right reading as
   an editorial annotation. The result is a smaller, more digestible
   media block on big screens, with the caption doing real work
   instead of sitting as a thin strip below.

   Falls back to the default stacked layout below 1024px so the
   caption gets full width on tablet/mobile.
   ---------------------------------------------------------- */
@media (min-width: 1024px) {
  .cs-gallery__item--wide.cs-gallery__item--has-caption {
    flex-direction: row;
    align-items: stretch;
  }
  .cs-gallery__item--wide.cs-gallery__item--has-caption .cs-gallery__media {
    flex: 0 0 66.66%;
    max-width: 66.66%;
  }
  .cs-gallery__item--wide.cs-gallery__item--has-caption .cs-gallery__caption {
    flex: 1 1 auto;
    border-top: 0;
    border-left: 1px solid var(--border);
    /* Caption sits beside the media — give it editorial breathing room.
       Stays vertically centred so short captions don't look orphaned
       next to a tall media block. */
    padding: clamp(20px, 2.4vw, 36px);
    display: flex;
    flex-direction: column;
    justify-content: center;
    font-size: 14.5px;
    line-height: 1.6;
  }
  /* In side-caption mode the display-font title gets a touch more room
     so it reads as the editorial annotation it is. */
  .cs-gallery__item--wide.cs-gallery__item--has-caption .cs-gallery__caption-title {
    font-size: clamp(22px, 1.6vw + .25rem, 32px);
    margin-bottom: 14px;
  }
}

@media (max-width: 640px) {
  .cs-gallery__item,
  .cs-gallery__item--wide { grid-column: span 12; }
  .cs-gallery__item--wide .cs-gallery__media { aspect-ratio: 4/3; }
  /* On phones the side-caption flips back to stacked so the caption
     gets full width below the media instead of being squeezed beside it. */
  .cs-gallery__item--wide.cs-gallery__item--has-caption { flex-direction: column; }
  .cs-gallery__item--wide.cs-gallery__item--has-caption .cs-gallery__media {
    max-width: 100%;
    flex: 0 0 auto;
  }
  .cs-gallery__item--wide.cs-gallery__item--has-caption .cs-gallery__caption {
    border-left: 0;
    border-top: 1px solid var(--border);
  }
}

/* Related + prev/next --------------------------------- */
.cs-related {
  padding: clamp(64px, 8vw, 120px) var(--pad-x);
  border-bottom: 1px solid var(--border);
}
.cs-related__head {
  display: flex;
  justify-content: space-between;
  align-items: end;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: clamp(24px, 3vw, 40px);
}
.cs-related__head h2 {
  font-family: var(--font-display);
  font-weight: var(--heading-weight);
  font-size: clamp(28px, 3vw, 48px);
  letter-spacing: -.025em;
}
/* ----------------------------------------------------------
   Pinned horizontal scroll. Section height is set by JS to
   (trackWidth − viewportWidth) + 100vh, which is exactly the
   vertical scroll needed to consume the horizontal translation.
   The inner .cs-related__sticky stays pinned during that phase,
   and the track translates left in proportion to scroll progress.
   Native horizontal scroll fallback for touch + reduced-motion.
   ---------------------------------------------------------- */
.cs-related.cs-related--pinned { padding: 0; }

.cs-related__stage {
  position: relative;
  /* height is set inline by setupPinnedRelated() */
}
.cs-related__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(72px, 9vw, 120px) 0 clamp(72px, 9vw, 120px) var(--pad-x);
  box-sizing: border-box;
  overflow: hidden;
}
.cs-related--pinned .cs-related__head {
  margin-bottom: clamp(32px, 4vw, 56px);
  padding-right: var(--pad-x);
  flex: 0 0 auto;
}
.cs-related__frame {
  flex: 0 0 auto;
  overflow: visible;
  /* No fixed height — cards size naturally, frame is what the track
     slides within. The translate is managed via transform on .track. */
}
.cs-related__track {
  display: flex;
  gap: clamp(16px, 1.6vw, 28px);
  /* Slight right padding so the last card has air on the right end */
  padding-right: var(--pad-x);
  will-change: transform;
  transition: transform .06s linear;
}

/* Bumped-up card size for the carousel */
.cs-related__track .pcard--compact {
  flex: 0 0 clamp(300px, 26vw, 400px);
}
.cs-related__track .pcard--compact .pcard__media { aspect-ratio: 4/3; }
.cs-related__track .pcard--compact .pcard__body { padding: 16px 18px 18px; }
.cs-related__track .pcard--compact .pcard__title {
  font-size: clamp(20px, .8vw + 1rem, 26px);
}
.cs-related__track .pcard--compact .pcard__desc { display: none; }

/* Native scroll fallback (touch / reduced motion / JS failure) ---- */
.cs-related--native .cs-related__stage { height: auto !important; }
.cs-related--native .cs-related__sticky {
  position: static;
  height: auto;
  padding: clamp(64px, 8vw, 120px) 0 clamp(64px, 8vw, 120px) var(--pad-x);
}
.cs-related--native .cs-related__frame {
  margin-right: calc(var(--pad-x) * -1);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.cs-related--native .cs-related__track {
  transform: none !important;
  padding-right: var(--pad-x);
}
.cs-related--native .cs-related__track .pcard--compact {
  scroll-snap-align: start;
}

@media (max-width: 720px) {
  /* Below tablet the pin feels heavy — always use native scroll */
  .cs-related.cs-related--pinned .cs-related__stage { height: auto !important; }
  .cs-related.cs-related--pinned .cs-related__sticky {
    position: static; height: auto;
    padding: clamp(56px, 8vw, 96px) 0 clamp(56px, 8vw, 96px) var(--pad-x);
  }
  .cs-related.cs-related--pinned .cs-related__frame {
    margin-right: calc(var(--pad-x) * -1);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
  }
  .cs-related.cs-related--pinned .cs-related__track {
    transform: none !important;
    padding-right: var(--pad-x);
  }
  .cs-related.cs-related--pinned .cs-related__track .pcard--compact {
    scroll-snap-align: start;
    flex-basis: 280px;
  }
}

.cs-nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-top: 1px solid var(--border);
}
.cs-nav__link {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 28px var(--pad-x);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  transition: background .2s, color .2s;
}
.cs-nav__link:hover { background: var(--surface); color: #fff; }
.cs-nav__link--next { justify-content: flex-end; text-align: right; border-left: 1px solid var(--border); }
.cs-nav__link .arr { font-family: var(--font-ui); font-size: 18px; color: #fff; }
.cs-nav__link .meta { display: flex; flex-direction: column; gap: 4px; }
.cs-nav__link .meta .title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 22px;
  letter-spacing: -.02em;
  text-transform: none;
  color: #fff;
  line-height: 1.1;
}
@media (max-width: 560px) {
  .cs-nav { grid-template-columns: 1fr; }
  .cs-nav__link--next { border-left: 0; border-top: 1px solid var(--border); }
}
