/* ============================================================================
   SIEMENS — SUSTAINABILITY FILM CASE STUDY
   Four sections, film-led, minimal.

   Written mobile-first for real: every rule outside a media query targets a
   ~390px canvas, and larger screens only ever ADD to it through min-width
   blocks. Nothing here is a desktop layout being folded back down.

   Layered on top of style.css, which already supplies the design tokens, the
   topbar/footer chrome, the optional-image loader, the reveal system, the
   .btn set and the #projLightbox video modal.

   SECTION 3 (editorial furniture) intentionally repeats the primitives from
   casestudy-delhivery.css at IDENTICAL values, so the two case studies read
   as one system. They are duplicated rather than shared because that file
   also carries Delhivery's own hero/challenge/solution layout, which has no
   business loading here. If a third case study lands, lift sections 3-4 of
   both files into a shared casestudy.css and delete them from each page.

   COLOUR — one accent, no client note. #b162fe (--primary-red, aliased here
   as --cs-red) carries every eyebrow, rule, pull-quote and control on this
   page, exactly as it does on the Delhivery, Warner Bros. and AIFF studies.
   This page previously carried a muted petrol as a nod to the Siemens teal;
   it was removed because four case studies each borrowing their client's
   colour left the set reading as four different sites rather than one
   portfolio. The client is named in type, not in hue. Do not reintroduce a
   per-client accent here.

     1  Page tokens & gutter
     2  Chrome adjustments
     3  Primitives — ghost, plate
     4  Editorial furniture — eyebrow, headings, lede, meta
     5  Hero
     6  Film plate (poster + play)
     7  Challenge
     8  The making — lead frame & filmstrip
     9  Outcome & CTA
    10  TABLET         min-width: 768px
    11  DESKTOP        min-width: 1024px
    12  LARGE DESKTOP  min-width: 1440px
    13  Reduced motion
   ========================================================================= */

/* --------------------------------------------------------- 1 tokens & gutter */
:root {
  /* Carried straight from the Delhivery case study so the two pages share one
     type colour and one hairline weight. --cs-red IS --primary-red. */
  --cs-red:    #b162fe;
  --cs-white:  #f7f5f2;   /* warm white */
  --cs-grey:   #a8a5a0;   /* warm light grey */
  --cs-dim:    #6e6b66;
  --cs-line:   rgba(247, 245, 242, .1);
  --cs-line-2: rgba(247, 245, 242, .18);
  --cs-panel:  #101011;

  /* The same red at 42% for hairlines, plate borders and the filmstrip
     marker — anywhere the accent has to sit UNDER type rather than beside it.
     Same name and same job as --cs-red-lo on the Delhivery study. */
  --cs-red-lo: rgba(177, 98, 254, .42);

  --cs-space: 5.5rem;     /* 88px — mobile section rhythm */
  --cs-gap:   3.5rem;
  --cs-h1:    2.6rem;     /* 41.6px */
  --cs-h2:    1.95rem;
  --cs-h3:    1.45rem;

  /* filmstrip row height — the strip sizes every frame off this, so the
     sequence keeps one baseline while the frames keep their own ratios */
  --strip-h: 64vw;

  /* 22px of horizontal breathing room on mobile — style.css drops the global
     gutter to 18.4px under 640px, which is tighter than this page wants. */
  --gutter: 1.375rem;
}

/* ------------------------------------------------------- 2 chrome adjustments */
/* style.css makes the topbar transparent under 640px because the homepage hero
   sits behind it. Here it is a plain bar over a plain canvas, so it needs its
   background back. */
@media (max-width: 640px) {
  .topbar { background: var(--background); }
}

.cs-brand { display: flex; align-items: center; gap: .6rem; min-height: 44px; }
.cs-brand__arrow {
  width: 1.3rem; height: .6rem; color: var(--cs-grey);
  transition: transform .3s var(--ease), color .3s var(--ease);
}
.cs-brand:hover .cs-brand__arrow,
.cs-brand:focus-visible .cs-brand__arrow { transform: translateX(-5px); color: var(--cs-red); }

.cs-body { background: var(--background); }

/* ============================================================= 3 primitives */

/* Placeholder that shows through wherever a frame has not been supplied yet —
   script.js removes the <img> and this is what is left. Identical to the
   Delhivery ghost so a half-populated site stays visually coherent. */
.cs-ghost {
  position: absolute; inset: 0; z-index: 0;
  display: grid; place-items: center;
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.72rem, 3.1vw, .95rem);
  letter-spacing: .18em; text-transform: uppercase; line-height: 1.7;
  color: rgba(247, 245, 242, .3);
  text-align: center;
  background:
    radial-gradient(130% 110% at 74% 8%, rgba(177, 98, 254, .16), transparent 64%),
    linear-gradient(158deg, #17171a, #0b0b0c 60%, #121214);
  pointer-events: none;
}

/* plate — a bare bordered frame. Every image on this page is a film frame, so
   there is no browser chrome anywhere: the visuals are photography, not UI. */
.cs-plate {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--cs-line);
  background: var(--cs-panel);
  box-shadow: 0 30px 58px -32px rgba(0, 0, 0, .85);
}
.cs-plate picture { position: absolute; inset: 0; z-index: 1; }
.cs-plate img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, center); }

/* ================================================== 4 editorial furniture */
.cs-sec {
  padding-block: var(--cs-space);
  border-top: 1px solid var(--cs-line);
}
.cs-sec__head { margin-bottom: 2.75rem; }

.cs-eyebrow {
  display: flex; align-items: center; gap: .8rem;
  margin-bottom: 1.35rem;
  font-family: var(--font-cond); font-weight: 500;
  font-size: .68rem; letter-spacing: .22em; text-transform: uppercase;
  color: var(--cs-red);
}
.cs-eyebrow__rule { width: 1.6rem; height: 1px; background: var(--cs-red); flex: none; }

.cs-h1, .cs-h2, .cs-h3 {
  color: var(--cs-white);
  font-family: var(--font-cond); font-weight: 400;
  letter-spacing: -.012em;
  text-wrap: balance;
}
.cs-h1 { font-size: var(--cs-h1); line-height: 1.05; max-width: 15ch; }
.cs-h2 { font-size: var(--cs-h2); line-height: 1.12; max-width: 22ch; }
.cs-h3 { font-size: var(--cs-h3); line-height: 1.2;  max-width: 24ch; }

.cs-lede {
  margin-top: 1.35rem;
  font-size: 1rem; line-height: 1.7;
  color: var(--cs-grey);
  max-width: 48ch;
}

.cs-meta {
  display: grid; gap: 1.35rem;
  margin-top: 2.5rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--cs-line);
}
.cs-meta dt {
  font-family: var(--font-cond); font-weight: 500;
  font-size: .62rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--cs-dim);
  margin-bottom: .45rem;
}
.cs-meta dd {
  font-family: var(--font-cond); font-weight: 300;
  font-size: .95rem; letter-spacing: .02em; line-height: 1.5;
  color: var(--cs-white);
}

/* ================================================================== 5 hero */
/* Full-bleed film frame with the copy sitting on it. The section is the
   stacking context; the media is pinned behind and the shell rides on top. */
.cs-hero {
  position: relative;
  isolation: isolate;
  display: flex; align-items: flex-end;
  min-height: 82vh;
  padding-block: 6rem 3rem;
  overflow: hidden;
}
/* svh where supported: on mobile browsers vh includes the retracting URL bar,
   which makes the hero taller than the screen on first paint. */
@supports (height: 1svh) { .cs-hero { min-height: 82svh; } }

.cs-hero__media { position: absolute; inset: 0; z-index: -2; }
.cs-hero__media picture { position: absolute; inset: 0; }
.cs-hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: center; }

/* Two scrims, not one. The vertical pass buys legibility for the copy block;
   the horizontal pass keeps the frame's right side readable as an image
   instead of flattening the whole thing to grey. */
.cs-hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(to top,
      #070707 0%, rgba(7, 7, 7, .94) 22%, rgba(7, 7, 7, .62) 52%,
      rgba(7, 7, 7, .38) 78%, rgba(7, 7, 7, .5) 100%),
    linear-gradient(to right, rgba(7, 7, 7, .8) 0%, rgba(7, 7, 7, .25) 55%, transparent 100%);
}

/* Slow scale on load — the film-frame settle. 2.6s, once, then it rests.
   Started by CSS rather than JS because there is nothing to wait for; the
   reduced-motion block at the bottom removes it entirely. */
.cs-hero__media img { animation: cs-settle 2.6s var(--ease-out) both; }
@keyframes cs-settle { from { transform: scale(1.07); } to { transform: scale(1); } }

.cs-hero__inner { position: relative; z-index: 1; width: 100%; }

/* A hairline under the eyebrow rather than a coloured word, so the accent
   registers as a mark and the label stays plain type. */
.cs-hero__eyebrow .cs-eyebrow__rule { background: var(--cs-red); }

.cs-hero .cs-lede { max-width: 46ch; }

.cs-hero__cta { margin-top: 2.25rem; }
/* .btn is an <a> everywhere else on the site, so it inherits nothing useful
   on a <button>; the font shorthand resets that before the site's own type
   is reapplied. min-height is a page-scoped touch-target floor: the shared
   .btn lands at 40px on a phone, and raising it in style.css would move
   every button on every page. */
.film-cta {
  cursor: pointer;
  font: inherit;
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.66rem, .28vw + .58rem, .78rem);
  letter-spacing: .18em; text-transform: uppercase;
  min-height: 44px;
}
.cs-cta__actions .btn { min-height: 44px; }
.film-cta__icon { width: .95rem; height: .95rem; fill: currentColor; flex: none; }

/* ===================================================== 6 film plate (poster) */
/* The click target for the film. A 16:9 poster frame at full content width —
   deliberately NOT an iframe sitting in a card. The YouTube player is only
   built once the visitor asks for it, which also keeps YouTube's scripts and
   cookies off the page for anyone who never presses play. */
.film { margin-top: 3.5rem; }

.film__plate {
  position: relative; display: block;
  width: 100%; padding: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--cs-line);
  background: var(--cs-panel);
  box-shadow: 0 34px 64px -34px rgba(0, 0, 0, .9);
  cursor: pointer;
  transition: border-color .4s var(--ease);
}
.film__plate picture { position: absolute; inset: 0; z-index: 1; }
.film__plate img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .8s var(--ease-out);
}
.film__plate::after {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(to top, rgba(7, 7, 7, .78), rgba(7, 7, 7, .12) 55%, transparent);
}
.film__plate:hover { border-color: var(--cs-red-lo); }
.film__plate:hover img { transform: scale(1.035); }

.film__play {
  position: absolute; z-index: 3;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: grid; place-items: center;
  width: clamp(3.6rem, 11vw, 5.4rem); aspect-ratio: 1;
  border: 1px solid rgba(247, 245, 242, .55);
  border-radius: 50%;
  background: rgba(7, 7, 7, .34);
  color: var(--cs-white);
  backdrop-filter: blur(2px);
  transition: background-color .4s var(--ease), border-color .4s var(--ease),
              transform .5s var(--ease-out);
}
.film__play svg { width: 34%; height: 34%; fill: currentColor; margin-left: 8%; }
.film__plate:hover .film__play,
.film__plate:focus-visible .film__play {
  background: rgba(177, 98, 254, .9);
  border-color: var(--cs-red);
  transform: translate(-50%, -50%) scale(1.06);
}

.film__meta {
  position: absolute; z-index: 3;
  left: 0; bottom: 0;
  display: grid; gap: .4rem;
  padding: 1.15rem;
  text-align: left;
}
.film__tag {
  font-family: var(--font-cond); font-weight: 500;
  font-size: .58rem; letter-spacing: .22em; text-transform: uppercase;
  color: var(--cs-red);
}
.film__title {
  font-family: var(--font-cond); font-weight: 300;
  font-size: .92rem; letter-spacing: .04em; line-height: 1.35;
  color: var(--cs-white);
}

/* What the plate is replaced by once the visitor presses play. Same width,
   same 16:9 box, same border and shadow, so the film starts where the poster
   was and nothing below it moves. */
.film__player {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--cs-line);
  background: #000;
  box-shadow: 0 34px 64px -34px rgba(0, 0, 0, .9);
}
.film__player iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
}

/* ============================================================= 7 challenge */
/* Editorial two-column head, then a staggered pair of frames with the pull
   quote set between them. No cards: the composition does the work. */
.chal__copy > p + p { margin-top: 1.1rem; }
.chal__copy p {
  font-size: 1rem; line-height: 1.7;
  color: var(--cs-grey);
  max-width: 48ch;
}

.chal { display: grid; gap: 2.5rem; margin-top: 3.25rem; }

.chal__frame .cs-plate { aspect-ratio: 4 / 3; }
.chal__frame--b .cs-plate { aspect-ratio: 3 / 2; }
.chal__frame figcaption {
  margin-top: .9rem;
  font-family: var(--font-cond); font-weight: 300;
  font-size: .66rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--cs-dim);
}

/* The pull quote. This is the page's one raised voice, so it is the one
   place the accent is allowed to carry a whole element. */
.chal__quote {
  margin: 0;
  padding-left: 1.15rem;
  border-left: 2px solid var(--cs-red);
  font-family: var(--font-cond); font-weight: 300;
  font-size: 1.35rem; line-height: 1.4; letter-spacing: -.005em;
  color: var(--cs-white);
  max-width: 26ch;
  text-wrap: balance;
}

/* =========================================== 8 the making — lead & filmstrip */
.mk__lead { margin-top: 3.25rem; }
.mk__lead .cs-plate { aspect-ratio: 16 / 10; }

/* Expertise labels sit ON the frames, over a scrim, rather than in a row of
   service cards underneath them. The scrim is a real gradient on a pseudo
   element so the label keeps its contrast whatever frame is dropped in. */
.mk__frame { position: relative; }
.mk__label {
  position: absolute; z-index: 2;
  left: 0; right: 0; bottom: 0;
  padding: 2.75rem 1.15rem 1.15rem;
  background: linear-gradient(to top, rgba(7, 7, 7, .93) 12%, rgba(7, 7, 7, .6) 52%, transparent);
  pointer-events: none;
}
.mk__label b {
  display: block;
  margin-bottom: .35rem;
  font-family: var(--font-cond); font-weight: 500;
  font-size: .62rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--cs-white);
}
.mk__label span {
  display: block;
  font-size: .84rem; line-height: 1.5;
  color: rgba(247, 245, 242, .74);
  max-width: 34ch;
}

/* The filmstrip. A real horizontal scroller, which means it is swipeable on
   touch and arrow-key scrollable on desktop for free once the container is
   focusable — no carousel library, no JS-driven transform.
   It bleeds to both screen edges so the sequence reads as a strip running
   past the viewport rather than a widget parked inside the column. */
.mk__strip {
  display: flex;
  gap: .9rem;
  margin-top: 3rem;
  margin-inline: calc(-1 * var(--gutter));
  padding-inline: var(--gutter);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter);
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;              /* the progress rule below replaces it */
}
.mk__strip::-webkit-scrollbar { display: none; }
.mk__strip:focus-visible { outline: 2px solid var(--primary-red); outline-offset: 6px; }

/* MOBILE: one frame at a time. Every frame is the same generous 84vw, which
   with scroll-snap makes the strip behave like a swipe carousel — you see one
   frame, you flick, you see the next.
   The varied widths the desktop strip uses are deliberately NOT applied here.
   Tried that first: at 375px the row is ~240px tall, so a 1.78 frame wants
   427px and gets clamped by the viewport anyway, which collapsed the wide and
   squat frames to the same width and left only the portrait one different —
   all of the cost of the varied layout and none of the effect. Worse, the
   portrait frame is one of the three carrying an expertise label, and 187px
   is not enough width to set three lines of it. A uniform 84vw reads as a
   considered mobile composition rather than a squeezed desktop one, and
   nobody perceives "equal cards" in a strip that shows one frame at a time. */
/* Scoped to .mk__strip on purpose. .mk__frame on its own means only "a frame
   that can carry an .mk__label", and the LEAD figure uses it for exactly that
   — so sizing rules must never hang off the bare class or they also apply to
   the lead and squash the largest image on the page to the strip's row
   height, overriding its own 21/9 aspect-ratio. */
.mk__strip .mk__frame {
  flex: none;
  scroll-snap-align: start;
  height: var(--strip-h);
  width: 84vw;
}
.mk__strip .mk__frame .cs-plate { width: 100%; height: 100%; }
/* consumed by the width calc in the tablet block above */
.mk__frame--tall  { --ar: .78; }
.mk__frame--wide  { --ar: 1.78; }
.mk__frame--squat { --ar: 1.34; }

/* .66rem is the site's caption floor — the Delhivery study's figcaptions sit
   at exactly this size. Anything smaller starts to read as a tooltip. */
.mk__cap {
  position: absolute; z-index: 2;
  left: 0; bottom: 0;
  padding: 2rem .95rem .95rem;
  width: 100%;
  background: linear-gradient(to top, rgba(7, 7, 7, .88), transparent);
  font-family: var(--font-cond); font-weight: 300;
  font-size: .66rem; letter-spacing: .16em; text-transform: uppercase;
  color: rgba(247, 245, 242, .8);
  pointer-events: none;
}

/* Scroll position, shown as a hairline rather than a scrollbar. JS sets
   --p; with JS off the rule simply rests at its starting width, which is
   why it is decorative and hidden from assistive tech. */
.mk__progress {
  position: relative;
  height: 1px;
  margin-top: 1.5rem;
  background: var(--cs-line);
}
.mk__progress i {
  position: absolute; inset: 0 auto 0 0;
  display: block;
  width: clamp(12%, var(--p, 12%), 100%);
  background: var(--cs-red-lo);
  transition: width .18s linear;
}

.mk__hint {
  margin-top: .9rem;
  font-family: var(--font-cond); font-weight: 300;
  font-size: .62rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--cs-dim);
}

/* ==================================================== 9 outcome & CTA */
.out__copy { margin-top: 2.5rem; }
.out__copy > p + p { margin-top: 1.1rem; }
.out__copy p {
  font-size: 1rem; line-height: 1.7;
  color: var(--cs-grey);
  max-width: 52ch;
}

/* The four statements. Type carries them — a hairline, a small red index and
   a large condensed line each. No boxes, no icons, no counters. */
.out__list {
  display: grid;
  margin-top: 3.5rem;
  border-top: 1px solid var(--cs-line);
}
.out__item {
  display: flex; align-items: baseline; gap: 1.1rem;
  padding-block: 1.35rem;
  border-bottom: 1px solid var(--cs-line);
}
/* The index marks. Small, repeated, quiet. */
.out__num {
  flex: none;
  font-family: var(--font-cond); font-weight: 400;
  font-size: .68rem; letter-spacing: .2em;
  color: var(--cs-red);
}
.out__stmt {
  font-family: var(--font-cond); font-weight: 300;
  font-size: 1.3rem; line-height: 1.3; letter-spacing: -.005em;
  color: var(--cs-white);
  text-wrap: balance;
}

/* Closing action — two links, no headline. The block carries no rule of its
   own: the outcome list above already ends on a hairline and .cs-next below
   opens with one, so a third here just crowds them. Values match the AIFF
   study so all the case studies end identically.
   There were .cs-cta__title and .cs-cta__line rules here for a "Have a complex
   story to communicate? / Start a Project" pitch. Both the markup and the
   rules were deleted: the site documents work done in full-time roles and does
   not solicit projects. */
.cs-cta { margin-top: 3rem; }
.cs-cta__actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: .7rem 1.1rem;
}

/* Small next-project link — a footer to this section, not a section of its
   own. Matches the Delhivery page so the two studies end the same way. */
.cs-next {
  margin-top: 4.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--cs-line);
}
.cs-next__label {
  font-family: var(--font-cond); font-weight: 500;
  font-size: .62rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--cs-dim);
  margin-bottom: .5rem;
}
.cs-next__link {
  display: flex; align-items: center; justify-content: space-between; gap: 1.25rem;
  min-height: 44px;   /* touch target */
  font-family: var(--font-cond); font-weight: 400;
  font-size: 1.5rem; letter-spacing: -.005em;
  color: var(--cs-white);
  transition: color .3s var(--ease);
}
.cs-next__link .arrow { width: 2.1rem; color: var(--cs-red); }
.cs-next__link:hover, .cs-next__link:focus-visible { color: var(--cs-red); }
.cs-next__link:hover .arrow { transform: translateX(6px); }

/* Reveals are entirely style.css's: `.js [data-reveal]` / `.is-in` there
   already carry the fade-and-rise, the --d delay hook and the no-JS safety of
   being scoped to .js. This page only uses the attributes. */


/* ============================================================================
   10  TABLET — min-width: 768px
   ========================================================================= */
@media (min-width: 768px) {
  :root {
    --gutter: 2.25rem;
    --cs-space: 7rem;
    --cs-gap: 5rem;
    --cs-h1: 3.6rem;
    --cs-h2: 2.6rem;
    --cs-h3: 1.85rem;
    --strip-h: 330px;
  }

  .cs-hero { min-height: 78vh; padding-block: 7rem 4rem; }
  @supports (height: 1svh) { .cs-hero { min-height: 78svh; } }

  /* Client and Project Type are short; My Role is a four-part string, so it
     takes the remaining track instead of being squeezed into a third of it. */
  .cs-meta {
    grid-template-columns: auto auto minmax(0, 1fr);
    gap: 2rem;
  }
  .cs-lede { font-size: 1.05rem; }

  .film { margin-top: 4.5rem; }
  .film__meta { padding: 1.6rem; }
  .film__title { font-size: 1.05rem; }

  /* Challenge — the two frames sit side by side with the quote beneath the
     first, which is where the stagger starts */
  .chal {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: 2rem; row-gap: 3rem;
    align-items: start;
  }
  .chal__frame--a { grid-column: 1 / span 7; grid-row: 1; }
  .chal__quote    { grid-column: 9 / span 4; grid-row: 1; align-self: end; }
  .chal__frame--b { grid-column: 5 / span 8; grid-row: 2; }
  .chal__quote { font-size: 1.5rem; padding-left: 1.4rem; }

  .mk__label { padding: 3rem 1.6rem 1.6rem; }
  .mk__label span { font-size: .88rem; }
  .mk__strip { gap: 1.25rem; }

  /* From tablet up there is room for the real filmstrip: every frame keeps
     the same row height and takes its width from its own ratio, so the
     sequence holds one baseline while the shapes stay varied. That variation
     is what stops it reading as a row of equal cards. --ar is set per frame
     by the modifier classes in the markup. */
  .mk__strip .mk__frame { width: calc(var(--strip-h) * var(--ar, 1.5)); }

  .out__stmt { font-size: 1.75rem; }
  .out__item { gap: 1.6rem; padding-block: 1.75rem; }
  .cs-next__link { font-size: 2rem; justify-content: flex-start; }
}


/* ============================================================================
   11  DESKTOP — min-width: 1024px
   ========================================================================= */
@media (min-width: 1024px) {
  :root {
    /* style.css narrows the shell to 900px under `max-width: 1024px`, which
       overlaps this block at exactly 1024 and would otherwise leave the
       desktop layout ~100px narrower than it is designed for. Reclaim the
       site's wide shell from here up — a film-led page needs the width. */
    --shell: 1480px;

    --gutter: 3rem;
    --cs-space: 9.5rem;
    --cs-gap: 8rem;
    --cs-h1: 4.6rem;
    --cs-h2: 3.2rem;
    --cs-h3: 2.2rem;
    --strip-h: 420px;
  }

  /* ---- hero ------------------------------------------------------------ */
  .cs-hero { min-height: min(90vh, 820px); padding-block: 9rem 4.5rem; }
  @supports (height: 1svh) { .cs-hero { min-height: min(90svh, 820px); } }
  /* the copy occupies the left half of the frame; the right half stays image */
  .cs-hero__copy { max-width: 60%; }
  .cs-hero .cs-lede { font-size: 1.15rem; max-width: 44ch; }
  .cs-hero__cta { margin-top: 2.75rem; }

  .film { margin-top: 6rem; }

  /* ---- section heads: heading left, paragraph right -------------------- */
  /* the eyebrow spans both columns so the heading and its copy start on the
     same line beneath it */
  .cs-sec__head--split {
    display: grid;
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    column-gap: clamp(3rem, 6vw, 7rem);
    align-items: start;
  }
  .cs-sec__head--split .cs-eyebrow { grid-column: 1 / -1; }
  .cs-sec__head--split .cs-h2 { grid-column: 1; max-width: 20ch; }
  .cs-sec__head--split .chal__copy,
  .cs-sec__head--split .cs-lede {
    grid-column: 2;
    margin-top: .55rem;   /* optically level with the heading's first line */
    max-width: 42ch;
  }

  /* ---- challenge ------------------------------------------------------- */
  .chal { margin-top: 5rem; column-gap: 3rem; row-gap: 4.5rem; }
  .chal__frame--a { grid-column: 1 / span 6; }
  .chal__quote    { grid-column: 8 / span 5; font-size: 2.1rem; padding-left: 1.75rem; }
  /* The stagger is done with COLUMNS, not a negative margin. An earlier
     version pulled this up 6rem to overlap row 1's baseline band; because the
     row gap is 4.5rem that left it 24px above row 1's bottom, where it
     covered frame A's caption and the pull quote's last line. Both of those
     heights are variable — the quote rewraps at every breakpoint and frame
     A's height follows whatever ratio the supplied file has — so the overlap
     could not be tuned away, only removed. Offsetting B three columns right
     of A and two columns left of the quote gives the same broken-grid read
     with nothing stacked on top of anything. */
  .chal__frame--b { grid-column: 4 / span 9; }

  /* ---- the making ------------------------------------------------------ */
  .mk__lead { margin-top: 4.5rem; }
  .mk__lead .cs-plate { aspect-ratio: 21 / 9; }
  .mk__label { padding: 4rem 2.25rem 2.25rem; }
  .mk__label b { font-size: .68rem; }
  .mk__label span { font-size: .95rem; max-width: 40ch; }
  .mk__strip { margin-top: 4rem; gap: 1.5rem; }
  .mk__cap { padding: 2.5rem 1.4rem 1.4rem; font-size: .66rem; }

  /* ---- outcome --------------------------------------------------------- */
  .out__copy { margin-top: 0; }
  .out__stmt { font-size: 2.4rem; }
  .out__item { padding-block: 2.1rem; gap: 2.25rem; }
  .cs-cta { margin-top: 4.5rem; }
  .cs-next { margin-top: 7rem; }
  .cs-next__link { font-size: 2.75rem; }
}


/* ============================================================================
   12  LARGE DESKTOP — min-width: 1440px
   ========================================================================= */
@media (min-width: 1440px) {
  :root {
    --gutter: 4rem;
    --cs-space: 11.5rem;
    --cs-gap: 10rem;
    --cs-h1: 5.6rem;
    --cs-h2: 3.9rem;
    --cs-h3: 2.6rem;
    --strip-h: 500px;
  }

  .cs-hero__copy { max-width: 54%; }
  .chal__quote { font-size: 2.5rem; }
  .out__stmt { font-size: 2.9rem; }
  .cs-next__link { font-size: 3.2rem; }
}


/* ============================================================================
   13  REDUCED MOTION
   The hero settles instantly, the strip stops smooth-scrolling and nothing
   scales on hover. The filmstrip itself keeps working — it is an interaction,
   not an animation, and removing it would remove content.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .cs-hero__media img { animation: none; }
  .mk__strip { scroll-behavior: auto; }
  .mk__progress i { transition: none; }
  .film__plate:hover img { transform: none; }
  .film__plate:hover .film__play,
  .film__plate:focus-visible .film__play { transform: translate(-50%, -50%); }
  .cs-next__link:hover .arrow { transform: none; }
  .cs-brand:hover .cs-brand__arrow { transform: none; }
}
