/* =====================================================================
   STORY CRAFT — case-study shell
   ---------------------------------------------------------------------
   The ROUTE FOUNDATION, not the final art direction. It exists so that
   /projects/<slug>/ is a real, semantic, accessible document rendered
   from the same records everything else reads, and so the blocks a
   finished case study needs already have somewhere to go.

   Every block renders ONLY when its data exists. There is no filler and
   no lorem: a project without metrics simply has no metrics section.

   Deliberately NOT a scroll-snap route. A case study is a reading
   surface — snapping a long document would fight the reader.
   ===================================================================== */

html{ scroll-snap-type:none; }
body{
  background:var(--powder-white); color:var(--serene-navy);
  font-family:var(--font-ui); font-weight:400;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
}

/* Case-study media can scroll underneath the fixed header. Keep its
   reading surface solid so the logo, language switcher and CTA never
   inherit unpredictable contrast from a bright or dark production still. */
.hdr{ background:var(--powder-white); }

.cs{
  padding-inline:max(var(--pad), env(safe-area-inset-left)) max(var(--pad), env(safe-area-inset-right));
  padding-bottom:clamp(3rem, 10vh, 7rem);
}
.cs__wrap{ max-inline-size:74rem; margin-inline:auto; }

/* -- hero -------------------------------------------------------------- */
.cs__hero{ padding-top:calc(var(--hdr) + clamp(1.5rem, 6vh, 4rem)); }
.cs__back{
  display:inline-flex; align-items:center; gap:.5rem;
  min-height:44px; color:var(--caspian-blue);
}
.cs__back svg{ transition:transform .4s var(--ease-out-quart); }
.cs__back:hover svg{ transform:translateX(-4px); }

.cs__chapter{ color:var(--navy-70); margin-top:clamp(1rem, 3vh, 2rem); }
.cs__h1{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(2rem, 5.4vw, 4.2rem);
  line-height:1.02; letter-spacing:-.022em;
  margin-top:.5rem; text-wrap:balance;
}
.cs__client{
  color:var(--navy-70);
  font-size:clamp(.95rem, 1.2vw, 1.1rem);
  margin-top:.6rem;
}
.cs__lede{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.1rem, 1.9vw, 1.55rem);
  line-height:1.32; letter-spacing:-.01em;
  color:var(--caspian-blue);
  max-inline-size:44ch;
  margin-top:clamp(1rem, 3vh, 1.8rem);
}

/* -- media ------------------------------------------------------------- */
.cs__film{
  position:relative;
  margin-top:clamp(1.6rem, 5vh, 3rem);
  border-radius:clamp(14px, 1vw, 20px);
  overflow:hidden;
  background:color-mix(in srgb, var(--serene-navy) 6%, var(--powder-white));
  aspect-ratio:var(--ar, 16/9);
}
.cs__film img,
.cs__film video{ width:100%; height:100%; object-fit:cover; display:block; }
.cs__film video{ position:absolute; inset:0; opacity:0; transition:opacity .5s var(--ease-out-quart); }
.cs__film video.is-live{ opacity:1; }

/* Full-width landscape media and 9:16 groups get their own containers so
   a finished case study has somewhere to put them. */
.cs__wide{ margin-top:clamp(1.6rem, 5vh, 3rem); border-radius:clamp(14px,1vw,20px); overflow:hidden; }
.cs__verts{
  display:grid; gap:clamp(.6rem, 1.4vw, 1rem);
  grid-template-columns:repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  margin-top:clamp(1.6rem, 5vh, 3rem);
}
.cs__verts figure{ margin:0; aspect-ratio:9/16; border-radius:clamp(10px,.8vw,14px); overflow:hidden; }
.cs__verts img{ width:100%; height:100%; object-fit:cover; }
.cs__mosaic{
  display:grid; gap:clamp(.6rem, 1.4vw, 1rem);
  grid-template-columns:repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  margin-top:clamp(1.6rem, 5vh, 3rem);
}

/* -- sections ---------------------------------------------------------- */
.cs__sec{
  margin-top:clamp(2.4rem, 8vh, 5rem);
  padding-top:clamp(1.2rem, 3vh, 2rem);
  border-top:1px solid var(--rule);
}
.cs__secH{ color:var(--navy-70); }
.cs__body{
  font-size:clamp(.98rem, 1.15vw, 1.08rem);
  line-height:1.6; max-inline-size:60ch;
  margin-top:.9rem;
}

/* Services / deliverables / credits share one two-column definition
   layout — they are all "label, then a list". */
.cs__defs{
  display:grid; gap:clamp(1.2rem, 4vw, 3rem);
  grid-template-columns:repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  margin-top:1rem;
}
.cs__defT{ color:var(--navy-70); }
.cs__defL{ list-style:none; margin:.7rem 0 0; padding:0; }
.cs__defL li{ padding-block:.42rem; border-bottom:1px solid var(--rule); }

.cs__metrics{
  display:grid; gap:clamp(1rem, 3vw, 2.4rem);
  grid-template-columns:repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  margin-top:1rem;
}
.cs__mN{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.8rem, 4vw, 3rem); line-height:1;
  letter-spacing:-.02em;
}
.cs__mL{ color:var(--navy-70); margin-top:.4rem; }

.cs__quote{ margin:0; }
.cs__quoteT{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.25rem, 2.6vw, 2rem);
  line-height:1.24; letter-spacing:-.015em;
  max-inline-size:34ch;
}
.cs__quoteC{ color:var(--navy-70); margin-top:.9rem; font-style:normal; }

/* -- next project ------------------------------------------------------ */
.cs__next{
  display:grid; align-items:center;
  grid-template-columns:clamp(96px, 16vw, 190px) minmax(0,1fr) auto;
  column-gap:clamp(.9rem, 2vw, 1.6rem);
  padding-block:clamp(.9rem, 2.4vh, 1.4rem);
  min-height:44px;
}
.cs__nextT{ aspect-ratio:16/10; border-radius:8px; overflow:hidden; }
.cs__nextT img{ width:100%; height:100%; object-fit:cover; }
.cs__nextN{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.15rem, 2.4vw, 1.9rem); line-height:1.1;
  letter-spacing:-.015em;
  transition:transform .5s var(--ease-out-expo); transform-origin:left;
}
.cs__next:hover .cs__nextN{ transform:translateX(6px); }
.cs__nextC{ color:var(--navy-70); }
.cs__nextA{ color:var(--caspian-blue); }
@media (max-width:520px){
  .cs__next{ grid-template-columns:clamp(88px, 26vw, 120px) minmax(0,1fr); }
  .cs__nextA{ display:none; }
}

/* -- contact CTA -------------------------------------------------------- */
.cs__cta{
  margin-top:clamp(2.4rem, 8vh, 5rem);
  padding-top:clamp(1.4rem, 4vh, 2.4rem);
  border-top:1px solid var(--rule);
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:1rem;
}
.cs__ctaH{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.3rem, 2.8vw, 2.1rem); line-height:1.1; letter-spacing:-.018em;
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important; transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
}


/* =====================================================================
   FINAL-DELIVERY PLAYERS
   ---------------------------------------------------------------------
   The delivered work, and the top of the page's argument. Everything
   here is user-initiated: real buttons, real controls, sound,
   fullscreen. None of the muted-autoplay teaser rules apply.

   Each player is a poster facade over YouTube's own thumbnail. The
   iframe is created on activation and replaces only that facade, so a
   series page with three episodes ships zero third-party players until
   somebody asks for one.
   ===================================================================== */
.cs__final{ margin-top:clamp(1.4rem, 4vh, 2.4rem); }
.cs__player{
  position:relative;
  margin-top:clamp(.8rem, 2vh, 1.2rem);
}
.cs__facade,
.cs__frame{
  display:block;
  inline-size:100%;
  aspect-ratio:var(--ar, 16/9);
  border:0;
  border-radius:clamp(14px, 1vw, 20px);
  overflow:hidden;
  background:color-mix(in srgb, var(--midnight-blue) 92%, var(--powder-white));
}
.cs__facade{ position:relative; }
.cs__thumb{
  position:absolute; inset:0;
  inline-size:100%; block-size:100%;
  object-fit:cover;
}
/* The whole surface is the button — a 44px target is the floor, not the
   design. No hover-only affordance: it is visible at rest. */
.cs__play{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  inline-size:100%; block-size:100%;
  cursor:pointer;
  background:linear-gradient(to top,
    color-mix(in srgb, var(--midnight-blue) 34%, transparent),
    color-mix(in srgb, var(--midnight-blue) 6%, transparent));
  transition:background .4s var(--ease-out-quart);
}
.cs__play:hover{ background:color-mix(in srgb, var(--midnight-blue) 26%, transparent); }
.cs__playI{
  display:inline-flex; align-items:center; justify-content:center;
  inline-size:clamp(54px, 5vw, 72px); block-size:clamp(54px, 5vw, 72px);
  border-radius:999px;
  background:var(--powder-white); color:var(--serene-navy);
  padding-left:3px;                      /* optical centring of the triangle */
  transition:transform .45s var(--ease-out-expo), background-color .4s var(--ease-out-quart);
}
.cs__play:hover .cs__playI{ transform:scale(1.06); background:var(--celestial-blue); color:var(--powder-white); }
.cs__play:focus-visible{ outline:3px solid var(--powder-white); outline-offset:-6px; }

.cs__pTitle{
  display:flex; flex-wrap:wrap; gap:.5rem 1rem; align-items:baseline;
  margin-top:.7rem;
  font-size:clamp(.9rem, 1.1vw, 1.02rem);
  line-height:1.35;
}
.cs__pOut{
  position:relative;
  display:inline-flex; align-items:center;
  color:var(--caspian-blue);
  font-family:var(--font-ui); font-weight:500;
  font-size:.7rem; letter-spacing:.14em; text-transform:uppercase;
  white-space:nowrap;
  border-bottom:1px solid color-mix(in srgb, var(--caspian-blue) 40%, transparent);
}
/* Keep the editorial label visually small while making the actual tap
   area comfortable. The overlay is part of the anchor hit target. */
.cs__pOut::before{
  content:''; position:absolute;
  top:50%; left:50%; transform:translate(-50%,-50%);
  min-inline-size:44px; inline-size:100%; block-size:44px;
}
.cs__pOut:hover{ border-bottom-color:var(--caspian-blue); }

/* -- more deliverables ------------------------------------------------
   A real list of real episodes. Single column on mobile, never a
   horizontal swipe to discover the rest of a series. */
.cs__moreH{ color:var(--navy-70); margin-top:clamp(1.6rem, 4vh, 2.6rem); }
.cs__more{
  display:grid; gap:clamp(1rem, 2.4vw, 1.8rem);
  grid-template-columns:repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  margin-top:.4rem;
}
/* Portrait deliverables stay portrait. They were made 1080x1920 for a
   feed; cropping them to 16:9 to tidy the page would destroy the exact
   thing this page is arguing for. */
/* auto-FILL with a hard track maximum, not auto-fit with 1fr: a group
   holding a single portrait film would otherwise stretch that one item
   across the whole measure and render a ~830x1470 player. */
.cs__more.is-portrait{
  grid-template-columns:repeat(auto-fill, minmax(170px, 220px));
  justify-content:start;
  max-inline-size:none;
}
.cs__more.is-portrait .cs__playI{ inline-size:46px; block-size:46px; }
.cs__more .cs__pTitle{ font-size:.86rem; }

/* -- the cover reel, explicitly secondary ------------------------------ */
.cs__teaser .cs__film{ margin-top:clamp(.8rem, 2vh, 1.2rem); }
.cs__teaserNote{ color:var(--navy-70); margin-top:.35rem; }
.cs__teaser{ margin-top:clamp(2.4rem, 8vh, 5rem); }

@media (max-width:520px){
  .cs__more.is-portrait{ grid-template-columns:repeat(2, minmax(0,1fr)); justify-content:stretch; }
}

/* A 9:16 player at full page width becomes a ~1200x2100 block on a
   laptop — absurd, and it pushes everything else off the screen. Portrait
   deliverables are capped to a phone-like measure and sit left, where the
   reading column starts. */
.cs__player.is-featured[style*="9/16"]{ max-inline-size:min(360px, 78vw); }
@media (min-width:861px){
  .cs__player.is-featured[style*="9/16"]{ max-inline-size:400px; }
}

/* Campaign heading inside the deliverables list. A record covering three
   campaigns should read as three campaigns, not eleven loose films. */
.cs__group{
  color:var(--serene-navy);
  margin-top:clamp(1.2rem, 3vh, 1.8rem);
  padding-top:.7rem;
  border-top:1px solid var(--rule);
}
.cs__group + .cs__more{ margin-top:.8rem; }
/* A self-hosted final is a real <video controls>; it needs the same
   rounded frame and ratio the iframe gets. */
video.cs__frame{ background:var(--midnight-blue); object-fit:contain; }

/* =====================================================================
   BEHIND THE SCENES
   ---------------------------------------------------------------------
   Supporting evidence, below the finished work and below the cover reel.
   A quiet grid — this is proof of craft, not a second gallery competing
   with the delivery.
   ===================================================================== */
.cs__bts{ margin-top:clamp(2.4rem, 8vh, 5rem); }
.cs__btsGrid{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  gap:clamp(.5rem, 1.2vw, .9rem);
  margin-top:clamp(.9rem, 2.4vh, 1.4rem);
}
.cs__btsI{
  margin:0;
  aspect-ratio:3/2;
  border-radius:clamp(8px, .7vw, 12px);
  overflow:hidden;
  background:color-mix(in srgb, var(--serene-navy) 6%, var(--powder-white));
}
/* A portrait frame keeps its shape and spans one column, two rows —
   cropping a vertical photograph to landscape to tidy a grid throws away
   the composition someone chose. */
.cs__btsI.is-portrait{ aspect-ratio:2/3; grid-row:span 2; }
.cs__btsI img{
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .7s var(--ease-out-expo);
}
.cs__btsI:hover img{ transform:scale(1.03); }
@media (max-width:520px){
  .cs__btsGrid{ grid-template-columns:repeat(2, minmax(0,1fr)); }
  .cs__btsI.is-portrait{ grid-row:span 1; }
}

/* A BTS reel is supporting material, so it sits at a modest width rather
   than the full measure the delivered work gets. */
.cs__player.is-bts{ max-inline-size:min(340px, 72vw); margin-top:clamp(.9rem,2.4vh,1.4rem); }
@media (min-width:861px){ .cs__player.is-bts{ max-inline-size:380px; } }

/* =====================================================================
   PHOTOGRAPHY MOSAIC
   ---------------------------------------------------------------------
   A body of work in its own right, so it gets room. Masonry-ish flow
   without being masonry: a dense grid where wide frames take two columns,
   which keeps establishing shots readable next to details.
   ===================================================================== */
.cs__gal{ margin-top:clamp(2.4rem, 8vh, 5rem); }
.cs__galGrid{
  display:grid;
  /* `dense` matters: without it the wide every-fifth frames leave holes
     that nothing backfills, and a 36-image gallery reads as a broken
     grid rather than an edit. */
  grid-auto-flow:dense;
  grid-template-columns:repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  gap:clamp(.5rem, 1.1vw, .85rem);
  margin-top:clamp(.9rem, 2.4vh, 1.4rem);
}
.cs__galI{ margin:0; aspect-ratio:3/2; border-radius:clamp(8px,.7vw,12px); overflow:hidden;
  background:color-mix(in srgb, var(--serene-navy) 6%, var(--powder-white)); }
.cs__galI img{ width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .7s var(--ease-out-expo); }
.cs__galI:hover img{ transform:scale(1.03); }
/* Every fifth frame runs wide, so the grid reads as an edit rather than
   a contact sheet. */
@media (min-width:861px){ .cs__galI:nth-child(5n+1){ grid-column:span 2; aspect-ratio:2/1; } }
@media (max-width:520px){ .cs__galGrid{ grid-template-columns:repeat(2, minmax(0,1fr)); } }

/* =====================================================================
   CHAPTERS
   ---------------------------------------------------------------------
   A case that spans two events renders each year as a real section with
   a stable id. `scroll-margin-top` is not decoration: the header is
   position:fixed, so without it a jump to #2026 puts the heading behind
   the header and the visitor thinks the link is broken.
   ===================================================================== */
/* `cs__chapter` is the hero's category eyebrow — do not reuse it. */
.cs__chSec{ scroll-margin-top:calc(var(--hdr) + 1.25rem); }
.cs__chYear{
  color:var(--navy-45);
  font-variant-numeric:tabular-nums;
}
.cs__chH{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.5rem, 3.4vw, 2.6rem);
  line-height:1.06; letter-spacing:-.018em;
  margin:.35rem 0 0;
  text-wrap:balance;
}
.cs__chLede{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1rem, 1.7vw, 1.3rem);
  line-height:1.36; color:var(--caspian-blue);
  max-inline-size:46ch; margin:.7rem 0 clamp(1.2rem, 3vh, 1.8rem);
}
.cs__chMeta{ margin-top:clamp(1.2rem, 3vh, 1.8rem); }
