/* ==========================================================================
   CASE STUDY system (every /work/ page). Loaded after components.css and
   site.css, by the case-study pages only.

   Source: Figma "V2 | Case Study | K12 Onboarding" (241:127091), designed
   from the hero through Approach 03 and extended here to the whole page.

   One visual grammar, flexible compositions. Every block sits on the site's
   12-column grid (.cs-grid), and the page gets its rhythm from WHERE blocks
   sit on it, not from different components:

     copy    starts at column 1, 2 or 3 (.cs-from-2 / .cs-from-3)
     media   runs 11 of 12 columns, flush left or flush right
             (.cs-media--left / --right), or inset (--inset)
     splits  text beside media (.cs-split), text beside text (.cs-outcome)

   A page composes these per section, so two case studies never have to look
   identical. Reuse this small family. Do not add a new trick per section.
   The grid can move; the reading order cannot: a section's complete
   narrative always comes before its media.

   Prose keeps a readable measure (about 790px, eight columns) wherever it
   sits, so the narrative has presence beside large media without long lines:
   a deliberate departure from the mock, which ran body copy 993px wide.

   Desktop (1200+) is the expressive grid. Tablet (840-1199) keeps the
   compositions with smaller shifts. Phones (below 840) are one column in
   reading order, and the system carries through labels, rules, the tonal
   band, spacing and the media treatment.

   Media boxes keep the .case-hero-media / .case-section__media classes: the
   phone image lightbox (main.js) finds them by those names.
   ========================================================================== */

/* Case-study vertical rhythm (Megan, 2026-10-07; calibrated against Figma 324:215279 and
   validated on all four case studies). One token per semantic relationship
   (1200+ / 840-1199 / below 840):
     --cs-chapter    TRUE CHAPTER BREAK, the space on EACH side of .cs-rule: the overview
                     (lead / proof tiles) -> the detailed story. 120 / 96 / 56
     --cs-module     MAJOR UNRULED MODULE CHANGE: around the Key Insights band, and the
                     ending -> the project nav rule. 120 / 96 / 64
     --cs-step       SIBLING STORY STEPS: Approach -> Approach, beat -> beat, and the story
                     side of the story -> synthesis rule. 104 / 88 / 64
     --cs-group      CONNECTED GROUP: the synthesis side of .cs-rule--synthesis, Solution ->
                     Reflection and its padding, ECE's CTA panel -> Outcome, and both sides
                     of the project nav content. 64 / 56 / 40
     --cs-band-pad   Key Insights band padding. 96 / 72 / 56
     --cs-result-gap Body -> result line. 40 / 32 / 24
     --cs-text-media TEXT -> PRIMARY MEDIA inside one module: a module's narrative (and its
                     result line) to its first supporting artifact. 64 / 56 / 40
   A rule adds no margins of its own: .cs-rule is one block holding both of its spaces with
   the 1px line between them. Everything inside a composition (label -> heading, image ->
   caption, caption -> next image, pairs, sets, Reflection -> recap) keeps its own smaller
   component step. The ending nav sits outside the <article>, so it shares the variables. */
.case-study,
.case-study + .case-next {
  --cs-chapter: 120px;
  --cs-module: 120px;
  --cs-step: 104px;
  --cs-group: 64px;
  --cs-band-pad: 96px;
  --cs-result-gap: 40px;
  --cs-text-media: 64px;
  --cs-measure: 790px;     /* readable prose measure: eight grid columns at 1200+ */
}
@media (max-width: 1199px) {
  .case-study,
  .case-study + .case-next {
    --cs-chapter: 96px; --cs-module: 96px; --cs-step: 88px; --cs-group: 56px;
    --cs-band-pad: 72px; --cs-result-gap: 32px; --cs-text-media: 56px;
  }
}
@media (max-width: 839px) {
  .case-study,
  .case-study + .case-next {
    --cs-chapter: 56px; --cs-module: 64px; --cs-step: 64px; --cs-group: 40px;
    --cs-band-pad: 56px; --cs-result-gap: 24px; --cs-text-media: 40px;
  }
}

/* ---- Grid ------------------------------------------------------------------
   The site grid's own columns and gutter (tokens.css): 12 columns at 840+,
   4 below. Children span the full width unless a rule below places them. */
.cs-grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  column-gap: var(--grid-gutter);
  align-items: start;
}
.cs-grid > * { grid-column: 1 / -1; min-width: 0; }

/* Where a block starts. Tablet halves the shift, phones drop it. */
@media (min-width: 840px) {
  .cs-grid > .cs-from-3 { grid-column-start: 2; }
}
@media (min-width: 1200px) {
  .cs-grid > .cs-from-2 { grid-column-start: 2; }
  .cs-grid > .cs-from-3 { grid-column-start: 3; }
}

/* ---- Type roles ------------------------------------------------------------- */
.cs-label {
  font-family: var(--font-detail);
  font-size: var(--text-details100-size);
  font-weight: var(--text-details100-weight);
  line-height: var(--text-details100-leading);
  text-transform: uppercase;
  color: var(--color-gray);
  margin-bottom: var(--space-sm);
}
.cs-heading {
  text-wrap: balance; /* no one-word last lines in headings */
  font-family: var(--text-h200-font);
  font-size: var(--text-h200-size);
  font-weight: var(--text-h200-weight);
  line-height: var(--text-h200-leading);
  color: var(--color-ink);
}
.cs-heading + .cs-prose { margin-top: var(--space-xl); }
.cs-prose {
  max-width: var(--cs-measure);
  font-size: var(--text-body200-size);
  font-weight: var(--text-body200-weight);
  line-height: var(--text-body200-leading);
  color: var(--color-ink);
}
.cs-prose > * + * { margin-top: var(--space-lg); }
.cs-prose ul {
  list-style: disc;
  padding-left: var(--space-xl);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
.cs-prose p + ul { margin-top: var(--space-md); }
@media (max-width: 839px) {
  .cs-heading { font-size: 24px; }
}

/* ---- Hero ------------------------------------------------------------------
   The full-bleed rule under the nav, then: kicker + H1, and below them the
   facts column beside the statement and context. One column in from the
   content edge at 1200+ (Figma). */
.cs-hero {
  border-top: var(--border-width) solid var(--color-rule);
  padding-block: var(--space-4xl) var(--cs-text-media);   /* bottom = hero text -> hero image */
}
.cs-hero .cs-grid { row-gap: 40px; }
.cs-hero__kicker {
  font-family: var(--font-detail);
  font-size: var(--text-details200-size);
  line-height: var(--text-details200-leading);
  text-transform: uppercase;
  color: var(--color-ink); /* the kicker is ink, never the accent (Megan); the H1 below is the blue */
  margin-bottom: var(--space-sm);
}
.cs-hero__title {
  font-family: var(--font-body);
  font-size: var(--text-display100-size);
  font-weight: var(--text-display100-weight);
  line-height: var(--text-display100-leading);
  color: var(--color-blue-text);
}
.cs-hero__statement {
  /* No text-wrap: balance here: it evens the lines and makes the statement
     look narrower than the context below. Both fill the same column. */
  font-family: var(--text-h200-font);
  font-size: var(--text-h200-size);
  font-weight: var(--text-h200-weight);
  line-height: var(--text-h200-leading);
  color: var(--color-ink);
}
.cs-hero__context {
  margin-top: var(--space-lg);
  font-size: var(--text-body100-size);
  font-weight: var(--text-body100-weight);
  line-height: var(--text-body100-leading);
  color: var(--color-ink);
}
/* Facts: Role (with the skills as plain text under it), Timeline, Team. */
.cs-meta { display: flex; flex-direction: column; gap: var(--space-lg); }
.cs-meta dt {
  font-family: var(--font-detail);
  font-size: var(--text-details200-size);
  line-height: var(--text-details200-leading);
  text-transform: uppercase;
  color: var(--color-gray);
  margin-bottom: 2px;
}
.cs-meta dd {
  margin: 0;
  font-size: var(--text-body300-size);
  font-weight: var(--text-body300-weight);
  line-height: var(--text-body300-leading);
  color: var(--color-ink);
}
.cs-meta__role { display: block; font-weight: var(--weight-semibold); }
@media (min-width: 840px) {
  .cs-hero .cs-grid > .cs-meta { grid-column: 1 / span 4; }
  .cs-hero .cs-grid > .cs-hero__intro { grid-column: 5 / -1; }
}
@media (min-width: 1200px) {
  .cs-hero .cs-grid > .cs-hero__head { grid-column: 2 / 12; }
  .cs-hero .cs-grid > .cs-meta { grid-column: 2 / span 3; }
  .cs-hero .cs-grid > .cs-hero__intro { grid-column: 5 / 12; }
  .cs-hero__statement,
  .cs-hero__context { max-width: 655px; }
}
/* The facts list starts level with the statement: no UA dl top margin beside it. */
@media (min-width: 840px) {
  .cs-hero .cs-grid > .cs-meta { margin-top: 0; }
}
@media (max-width: 839px) {
  .cs-hero { padding-top: var(--space-2xl); }
  /* the facts list ends the hero on phones: drop the UA dl margin so hero text -> hero
     image is exactly --cs-text-media. A hero CTA follows the facts by the grid's 24px
     row gap alone, so it adds no margin, and the image is --cs-text-media below it. */
  .cs-hero .cs-meta { margin-bottom: 0; }
  .cs-hero .cs-hero__action { margin-top: 0; }
  .cs-hero .cs-grid { row-gap: var(--space-xl); }
  .cs-hero__statement { font-size: 24px; }
  .cs-hero__context { font-size: var(--text-body200-size); line-height: var(--text-body200-leading); }
  /* Reading order: title, statement, context, then the facts. */
  .cs-hero .cs-meta {
    order: 3;
    padding-top: var(--space-xl);
    border-top: var(--border-width) solid var(--color-rule);
  }
}

/* ---- Media -----------------------------------------------------------------
   A bordered, rounded box around the artwork. Section media shows the whole
   image at its own proportions (never cropped: these are product screens).
   The hero image keeps the approved crop from components.css. */
.case-study .cs-media {
  position: relative;
  margin: 0;
  border: var(--border-width) solid var(--color-gray-3);
  border-radius: var(--radius-media-lg);
  background: var(--color-surface);
  overflow: hidden;
}
.case-study .cs-media:not(.cs-media--hero) { aspect-ratio: auto; }
.case-study .cs-media:not(.cs-media--hero) img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain;
}
.case-study .cs-media--hero { border-radius: var(--radius-media); }
.case-study .cs-media picture { display: block; }
@media (max-width: 839px) {
  .case-study .cs-media { border-radius: var(--radius-media); }
}
/* 11 of 12 columns, alternating sides. */
@media (min-width: 840px) {
  .cs-grid > .cs-media--left,
  .cs-grid > .cs-pair--left { grid-column: 1 / 12; }
  .cs-grid > .cs-media--right,
  .cs-grid > .cs-pair--right { grid-column: 2 / -1; }
  .cs-grid > .cs-media--inset { grid-column: 2 / 12; }
}

/* Wide + narrow pair: 8 + 3 columns of its 11-column span (Figma). The wide
   image sets the row's height at its own proportions; the narrow one is
   fitted inside its box, whole, on a letterbox, so it can never stretch the
   row or get cropped. Stacked on phones, each at its own proportions. */
.cs-pair { display: grid; row-gap: var(--space-xl); }
@media (min-width: 840px) {
  .cs-pair {
    grid-template-columns: minmax(0, 8fr) minmax(0, 3fr);
    column-gap: var(--grid-gutter);
  }
  @supports (grid-template-columns: subgrid) {
    .cs-pair { grid-template-columns: subgrid; }
    .cs-pair > .cs-pair__wide { grid-column: span 8; }
    .cs-pair > .cs-pair__narrow { grid-column: span 3; }
  }
  .case-study .cs-pair__narrow { background: var(--color-white); }
  .case-study .cs-pair__narrow img {
    position: absolute;
    inset: 0;
    height: 100%;
    object-fit: contain;
  }
}
/* Asset-specific: the K-12 sidebar screenshot sits whole and centred on its
   own blue (#0B4BAA, the screenshot's background in Figma), so the space
   around it disappears into the artwork. Same in both themes: it is artwork. */
.case-study .cs-media--k12-nav { background: #0B4BAA; }
.case-study .cs-media--k12-nav img { object-fit: contain; object-position: center; }

/* A set of equal states: three across, one column on phones. */
.cs-film {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--grid-gutter);
}
@media (max-width: 839px) {
  .cs-film { grid-template-columns: 1fr; row-gap: var(--space-xl); }
}

/* ---- Lead: hero image, then the stat tiles ---------------------------------- */
.cs-stats { margin-top: var(--space-2xl); row-gap: var(--space-lg); }
/* Tiles are grid cells, not cards: a pale tonal step and a hairline, sized
   to the columns. Two sit five columns each inside the hero's inset; three
   take four columns each across the full width. No shadow, no icon. */
.cs-stat {
  height: 100%;
  padding: var(--space-xl);
  border: var(--border-width) solid var(--color-tile-border);
  border-radius: var(--radius-media);
  background: var(--color-tile-bg);
  text-align: center;
}
.cs-stat__text {
  font-size: var(--text-body100-medium-size);
  font-weight: var(--text-body100-medium-weight);
  line-height: var(--text-body100-medium-leading);
  color: var(--color-ink);
}
.cs-stat__number {
  display: block;
  font-family: var(--text-h100-font);
  font-size: var(--text-h100-size);
  font-weight: var(--text-h100-weight);
  line-height: var(--text-h100-leading);
  color: var(--color-blue-text);
}
.cs-stats.cs-grid { align-items: stretch; }
@media (min-width: 840px) {
  .cs-stats--3 > .cs-stat { grid-column: span 4; }
  .cs-stats--2 > .cs-stat { grid-column: span 6; }
}
@media (min-width: 1200px) {
  .cs-stats--2 > .cs-stat { grid-column: span 5; }
  .cs-stats--2 > .cs-stat:first-child { grid-column: 2 / span 5; }
}
@media (max-width: 839px) {
  .cs-stats { margin-top: var(--space-xl); row-gap: var(--space-md); }
  .cs-stat { padding: var(--space-lg) var(--space-xl); }
}
/* The recap after the Reflection sits on the block rhythm. */
.cs-stats--recap { margin-top: var(--space-2xl); }

/* Content-width hairlines. .cs-rule is the TRUE CHAPTER BREAK between the overview
   and the story: --cs-chapter / 1px line / --cs-chapter. .cs-rule--synthesis is the
   STORY -> SYNTHESIS break before the Solution / Launch / Outcome: it closes the
   sibling steps (--cs-step), then keeps the synthesis connected (--cs-group). Rules
   never add margins of their own; the block holds both spaces. */
.cs-rule {
  display: block;
  height: calc(var(--cs-chapter) * 2 + var(--border-width));
  margin: 0;
  border: 0;
  background: linear-gradient(var(--color-rule), var(--color-rule)) 0 var(--cs-chapter) / 100% var(--border-width) no-repeat;
}
.cs-rule--synthesis {
  height: calc(var(--cs-step) + var(--border-width) + var(--cs-group));
  background-position: 0 var(--cs-step);
}

/* ---- Split: text beside media (Challenge) --------------------------------------
   Label and heading on top, then the prose with the image beside it, so the
   image's top edge lines up with the first line of body copy (Figma). The
   default is a tall narrow image in five columns; --wide gives a landscape
   image seven. */
.cs-split { row-gap: var(--space-xl); }
@media (min-width: 840px) {
  .cs-split > .cs-split__head { grid-column: 1 / span 6; }
  .cs-split > .cs-split__text { grid-column: 1 / span 6; grid-row: 2; }
  .cs-split > .cs-split__media { grid-column: 7 / -1; grid-row: 2; }
}
@media (min-width: 1200px) {
  .cs-split > .cs-split__head,
  .cs-split > .cs-split__text { grid-column: 1 / span 5; }
  .cs-split > .cs-split__media { grid-column: 7 / 12; }
  .cs-split--wide > .cs-split__media { grid-column: 6 / -1; }
}
@media (max-width: 839px) {
  .cs-split > .cs-split__media { margin-top: calc(var(--cs-text-media) - var(--space-xl)); }  /* + the 24px row gap = text -> media */
}
/* The vertical routing flow is drawn on its own pale-blue field. */
.case-study .cs-media--flow { border-radius: var(--radius-media); border-color: var(--color-gray-3); }

/* ---- Key Insights: the tonal band ------------------------------------------------
   Full bleed, the same pale wash as More Things (the grid shows through).
   Inside, two equal columns: the heading, then the intro beside the first
   card, then the remaining cards, so the cards step down the page instead
   of forming a plain 2x2.
   .cs-band--tuck (a page opts in) pulls the first card up beside the
   heading AND intro, lined up with the bottom of the intro, so it starts
   part-way down the heading and the next cards follow one normal gap
   below, with no dead space under a longer intro. K-12 uses it. */
.cs-band {
  margin-block: var(--cs-module);
  padding-block: var(--cs-band-pad);
  background: var(--color-band);
}
.cs-band__grid { display: grid; row-gap: var(--space-xl); }
.cs-band__intro { align-self: start; }
@media (min-width: 840px) {
  .cs-band__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--grid-gutter);
    row-gap: var(--space-2xl);
  }
  .cs-band__head { grid-column: 1 / -1; margin-bottom: calc(var(--space-sm) * -1); }
  .cs-band__head .cs-heading { max-width: calc(50% - var(--grid-gutter) / 2 - 56px); }
  .cs-band__intro { padding-right: 56px; }
  /* auto 1fr: when the first card is taller than the heading and intro,
     the extra height goes below the intro, never between heading and intro. */
  .cs-band--tuck .cs-band__grid { grid-template-rows: auto 1fr; }
  .cs-band--tuck .cs-band__head { grid-column: 1; grid-row: 1; padding-right: 56px; }
  .cs-band--tuck .cs-band__head .cs-heading { max-width: none; }
  .cs-band--tuck .cs-band__intro { grid-column: 1; grid-row: 2; }
  .cs-band--tuck .cs-band__intro + .cs-insight { grid-column: 2; grid-row: 1 / span 2; align-self: end; }
}
@media (min-width: 1200px) {
  .cs-grid > .cs-band__grid { grid-column: 2 / -1; }
}
.cs-insight {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  padding: var(--space-2xl);
}
.cs-insight__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-detail);
  font-size: var(--text-details200-size);
  font-weight: var(--text-details200-weight);
  line-height: var(--text-details200-leading);
  text-transform: uppercase;
  color: var(--color-gray);
  margin-bottom: var(--space-sm);
}
.cs-insight__eyebrow > span { color: var(--color-blue-text); }
.cs-insight__heading {
  font-family: var(--text-h400-font);
  font-size: var(--text-h400-size);
  font-weight: var(--text-h400-weight);
  line-height: var(--text-h400-leading);
  color: var(--color-ink);
  margin-bottom: var(--space-xl);
}
.cs-insight__body li,
.cs-insight__body p {
  font-size: var(--text-body300-size);
  font-weight: var(--text-body300-weight);
  line-height: var(--text-body300-leading);
  color: var(--color-ink);
}
/* Points are separated by a hairline, as are two paragraphs in one card. */
.cs-insight__body li + li,
.cs-insight__body p + p {
  margin-top: var(--space-lg);
  padding-top: var(--space-lg);
  border-top: var(--border-width) solid var(--color-gray-3);
}
@media (max-width: 839px) {
  .cs-insight { padding: var(--space-xl); }
}

/* ---- Approach sections --------------------------------------------------------
   Each is a .cs-grid whose children stack down the page: the copy, then its
   media. READING RULE (Megan): the complete narrative for a section stays
   together BEFORE its media. Never start a thought above an image and
   finish it below. Copy between or beside images is only for a clearly
   separate, visually distinct note (caption, callout, takeaway). */
.cs-approach + .cs-approach { margin-top: var(--cs-step); }
.cs-flow > * + * { margin-top: var(--space-3xl); }
.cs-flow > .cs-copy:first-child + * { margin-top: var(--cs-text-media); }   /* text -> primary media */
.cs-flow > .cs-media + .cs-media,
.cs-flow > .cs-media + .cs-pair,
.cs-flow > .cs-pair + .cs-media { margin-top: var(--space-2xl); }
@media (max-width: 839px) {
  .cs-flow > * + * { margin-top: var(--space-2xl); }
  .cs-flow > .cs-copy:first-child + * { margin-top: var(--cs-text-media); }
  .cs-flow > .cs-media + .cs-media,
  .cs-flow > .cs-media + .cs-pair,
  .cs-flow > .cs-pair + .cs-media { margin-top: var(--space-xl); }
}
/* Continuous narrative is never set in side-by-side columns (tried for
   Approach 03 and rejected as less readable). Side-by-side text is only for
   genuinely independent ideas. */

/* ---- Artifact captions + contextual results ----------------------------------------
   .cs-caption (Figma "V2 | Case Study | SL Dashboard" 324:215279): a quiet ARTIFACT
   ANNOTATION, never a paragraph. "// " prefix (drawn by CSS, hidden from screen
   readers), Nitti Regular 14 / 135%, UPPERCASE, gray, 16px under the artifact and
   aligned to its left edge (--right / --offset follow the media's placement).
   Figma uses #A0A0A0; the site's accessible --color-gray-2 is used instead (AA).
   Short: what the reader is looking at, or one concise observation. The narrative
   lives in the body copy.
   .cs-result: an approved business result repeated next to the decision it relates
   to: one ruled line (light-blue rule above and below, 16px padding), the figure in
   34px Semibold blue, the description in 16px Light blue-gray. It never sits inside a
   sentence, so the copy never claims the feature caused it. */
.cs-caption {
  font-family: var(--font-detail);
  font-size: var(--text-details200-size);
  font-weight: var(--weight-regular);
  line-height: var(--text-details200-leading);
  text-transform: uppercase;
  color: var(--color-gray-2);
}
.cs-caption::before { content: "// "; content: "// " / ""; }
.cs-flow > .cs-caption,
figure > .cs-caption { margin-top: var(--space-lg); }
/* a caption closes its artifact; the next artifact follows a step later */
.cs-flow > .cs-caption + * { margin-top: var(--space-2xl); }
@media (min-width: 840px) {
  .cs-grid > .cs-caption--right { grid-column: 2 / -1; }
  .cs-grid > .cs-caption--inset { grid-column: 2 / 12; }
}
.cs-result {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-xs) var(--space-lg);
  max-width: 892px;
  margin-top: var(--cs-result-gap);
  padding-block: var(--space-lg);
  border-block: var(--border-width) solid var(--color-things-rule);
}
.cs-result__number {
  font-family: var(--text-h100-font);
  font-size: var(--text-h100-size);
  font-weight: var(--text-h100-weight);
  line-height: var(--text-h100-leading);
  color: var(--color-blue-text);
}
.cs-result__value {
  font-size: var(--text-body200-size);
  font-weight: var(--weight-light);
  line-height: 1.5;
  color: var(--color-blue-gray);
}

/* Media placed from column 4 (3 on tablet), e.g. a supporting artifact that steps in
   from the section's left edge (Student Dashboard Approach 04 welcome summary). */
@media (min-width: 840px) {
  .cs-grid > .cs-media--offset,
  .cs-grid > .cs-caption--offset { grid-column: 3 / -1; }
}
@media (min-width: 1200px) {
  .cs-grid > .cs-media--offset,
  .cs-grid > .cs-caption--offset { grid-column: 4 / -1; }
}

/* A set of equal states inset from column 2, each cell cropped to the Figma 344:250
   frame (object-fit: cover, centred), three across (Student Dashboard Approach 02). */
@media (min-width: 840px) {
  .cs-grid > .cs-film--inset { grid-column: 2 / -1; }
}
.case-study .cs-film--inset > .cs-media { aspect-ratio: 344 / 250; }
.case-study .cs-film--inset > .cs-media img { height: 100%; object-fit: cover; }

/* ---- Optional: full-screen long screen (generic, not used on any page yet) ---------
   A small editorial inline artifact whose expand control (shown on every device via
   .cs-media--expandable, labelled "Full screen" by main.js when the img has
   data-full-src) opens the COMPLETE screen from data-full-src in a readable-width,
   vertically scrolling lightbox (.modal-card--tall, from data-lightbox="tall").
   Use only when inspecting a whole long product screen adds value (CLAUDE.md). */
.case-study .cs-media--expandable .media-expand { display: inline-flex; }
/* The labelled control gets its own 44px strip under the screenshot (a white
   letterbox, part of the artwork's presentation, same in both themes), so it never
   covers any UI. */
.case-study .cs-media--expandable { background: var(--color-white); padding-bottom: 44px; }
@media (min-width: 840px) {
  .case-study .cs-pair .cs-media--expandable img { inset: 0 0 44px 0; height: calc(100% - 44px); }
}
.case-study .cs-media--expandable .media-expand--labelled { right: var(--space-sm); bottom: 6px; }
/* Phones: a pair whose caption describes the WIDE image keeps that caption directly
   under it (wide, caption, narrow) instead of after the stacked narrow image. */
@media (max-width: 839px) {
  .cs-pair--captioned { display: contents; }
  .cs-pair--captioned > * { grid-column: 1 / -1; }
  /* the pair's own box is gone, so restore its spacing: flow step above the wide
     image, the pair's 24px gap above the narrow one */
  .cs-copy + .cs-pair--captioned > .cs-pair__wide { margin-top: var(--cs-text-media); }  /* copy → media */
  .cs-media + .cs-pair--captioned > .cs-pair__wide { margin-top: var(--space-xl); }   /* media → pair */
  .cs-pair--captioned > .cs-pair__narrow { order: 1; margin-top: var(--space-xl); }
}
.media-expand--labelled {
  width: auto;
  gap: var(--space-xs);
  padding: 0 var(--space-md) 0 10px;
  font-family: var(--font-detail);
  font-size: var(--text-details300-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
dialog.modal-card--image.modal-card--tall { width: fit-content; }
dialog.modal-card--image.modal-card--tall .image-lightbox__body {
  display: block;
  max-height: calc(100vh - var(--space-2xl) * 2);
  max-height: calc(100dvh - var(--space-2xl) * 2);
  overflow-y: auto;
}
dialog.modal-card--image.modal-card--tall .image-lightbox__body img {
  width: min(550px, 100%);
  max-height: none;
  margin-inline: auto;
  border-radius: 0;
}

/* ---- Outcome (Launch / Solution): the hero's split ------------------------------ */
.cs-outcome { row-gap: var(--space-xl); }
@media (min-width: 840px) {
  .cs-outcome > .cs-outcome__head { grid-column: 1 / span 4; }
  .cs-outcome > .cs-prose { grid-column: 5 / -1; }
}
@media (min-width: 1200px) {
  .cs-outcome > .cs-outcome__head { grid-column: 2 / span 3; }
  .cs-outcome > .cs-prose { grid-column: 5 / 12; }
}
.cs-outcome__head .cs-label:last-child { margin-bottom: 0; }

/* ---- Reflection: the closing beat ------------------------------------------------
   Brand blue in both themes, one column in on each side, with room to
   breathe. A statement, not a card: no shadow, no border. */
.cs-reflection {
  margin: var(--cs-group) 0 0;   /* Solution / Launch -> Reflection: one closing group */
  padding: var(--cs-group) var(--space-3xl);
  border-radius: var(--radius-media-lg);
  background: var(--color-blue);
  color: var(--color-white);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;   /* Figma 324:215279 */
  text-align: center;
}
.cs-reflection__kicker {
  font-family: var(--font-detail);
  font-size: var(--text-details200-size);
  line-height: var(--text-details200-leading);
  text-transform: uppercase;
  color: var(--color-white);
  opacity: 0.75;
}
.cs-reflection__quote {
  max-width: 22em;
  font-family: var(--text-h200-font);
  font-size: var(--text-h200-size);
  line-height: var(--text-h200-leading);
  color: var(--color-white);
}
.cs-reflection__quote strong { font-weight: var(--weight-semibold); }
/* One supporting line under the statement. */
.cs-reflection__note {
  max-width: 34em;
  font-size: var(--text-body200-size);
  font-weight: var(--text-body200-weight);
  line-height: var(--text-body200-leading);
  color: var(--color-white);
  opacity: 0.85;
}
@media (min-width: 1200px) {
  .cs-grid > .cs-reflection { grid-column: 2 / 12; }
}
@media (max-width: 839px) {
  .cs-reflection { padding: var(--cs-group) var(--space-xl); border-radius: var(--radius-media); }
  .cs-reflection__quote { font-size: 24px; }
}

/* ---- Project stories (lightweight variant) -----------------------------------------
   .case-study--project: a shorter page for a project told through a few product
   decisions and a prominent external experience (ECE, Degree Planner). Same hero,
   type, media and rhythm as the full case studies, without Key Insights, numbered
   Approaches, the Reflection or a recap. Each decision is a .cs-beat (copy, then
   its media, like an Approach). */
.cs-beat + .cs-beat { margin-top: var(--cs-step); }

/* Before / after: two screens side by side at 840+, each with a small label. */
.cs-compare { display: grid; gap: var(--space-xl) var(--grid-gutter); }
@media (min-width: 840px) {
  .cs-compare { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.cs-compare__item { margin: 0; }
.cs-compare__label {
  margin-top: var(--space-sm);
  font-family: var(--font-detail);
  font-size: var(--text-details200-size);
  line-height: var(--text-details200-leading);
  text-transform: uppercase;
  color: var(--color-gray);
}

/* A main screen with supporting detail beside it: 8 + 4 columns. Both images
   keep their own proportions (the detail panel is composed to match the main
   screen's height at 1200+). Stacked on phones. */
.cs-gallery { display: grid; row-gap: var(--space-xl); }
@media (min-width: 840px) {
  .cs-gallery {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    column-gap: var(--grid-gutter);
  }
  @supports (grid-template-columns: subgrid) {
    .cs-gallery { grid-template-columns: subgrid; }
    .cs-gallery > :first-child { grid-column: span 8; }
    .cs-gallery > :last-child { grid-column: span 4; }
  }
}

/* The external experience: a tonal panel with one prominent link. */
.cs-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg) var(--space-2xl);
  padding: var(--space-2xl);
  border: var(--border-width) solid var(--color-tile-border);
  border-radius: var(--radius-media-lg);
  background: var(--color-tile-bg);
}
@media (min-width: 1200px) {
  .cs-grid > .cs-cta { grid-column: 2 / 12; }
}
.cs-cta__text {
  font-size: var(--text-body200-size);
  font-weight: var(--text-body200-weight);
  line-height: var(--text-body200-leading);
  color: var(--color-ink);
}
.cs-cta__text .cs-label { margin-bottom: var(--space-xs); }
.cs-cta__link {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  font-family: var(--font-detail);
  font-size: var(--text-details100-size);
  line-height: var(--text-details100-leading);
  text-transform: uppercase;
  color: var(--color-blue-text);
}
.cs-cta__label { white-space: nowrap; }
.cs-cta__arrow { display: inline-block; transition: transform var(--duration-base) var(--ease-standard); }
a.cs-cta__link:hover .cs-cta__arrow,
a.cs-cta__link:focus-visible .cs-cta__arrow { transform: translateX(4px); }
/* Not linked yet (the destination isn't ready to share): muted, with its state
   in words. */
.cs-cta__link--pending { color: var(--color-gray); }
.cs-cta__status {
  padding: 2px var(--space-sm);
  border: var(--border-width) solid var(--color-rule);
  border-radius: var(--radius-pill);
  font-size: var(--text-details200-size);
  line-height: var(--text-details200-leading);
}
@media (max-width: 839px) {
  .cs-cta { padding: var(--space-xl); flex-direction: column; align-items: flex-start; }
}

/* Hero utility CTA: straight to the external artifact, directly under the facts column
   (the intro spans both rows beside it). 32px below the facts at 840+, 24px on phones
   (Megan, 2026-10-07). */
@media (min-width: 840px) {
  /* The flexible last row takes the intro's extra height, so the facts row stays
     content-sized and the CTA sits right under the facts. */
  .case-study--project .cs-hero .cs-grid { grid-template-rows: auto auto 1fr; }
  .case-study--project .cs-hero .cs-grid > .cs-meta { grid-row: 2; margin-bottom: 0; }
  .case-study--project .cs-hero .cs-grid > .cs-hero__intro { grid-row: 2 / span 2; }
  .case-study--project .cs-hero .cs-grid > .cs-hero__action {
    grid-row: 3;
    grid-column: 1 / span 4;
    margin-top: calc(var(--space-2xl) - 40px);   /* 32px under the facts; hero row-gap is 40px */
  }
}
@media (min-width: 1200px) {
  .case-study--project .cs-hero .cs-grid > .cs-hero__action { grid-column: 2 / span 3; }
}
@media (max-width: 839px) {
  .cs-hero .cs-hero__action { order: 4; }
}
.cs-cta__arrow--external { font-family: var(--font-body); }
a.cs-cta__link:hover .cs-cta__arrow--external,
a.cs-cta__link:focus-visible .cs-cta__arrow--external { transform: translate(2px, -2px); }

/* A closing group: the contextual CTA and the outcome read as one ending, so the
   outcome follows it by --cs-group with no rule (ECE). */
.cs-outcome--grouped { margin-top: var(--cs-group); }

/* Outcome with proof points in place of prose: two tiles side by side. */
.cs-proof {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--grid-gutter);
}
.cs-outcome > .cs-proof { grid-column: 1 / -1; }
@media (min-width: 840px) {
  .cs-outcome > .cs-proof { grid-column: 5 / -1; }
}
@media (min-width: 1200px) {
  .cs-outcome > .cs-proof { grid-column: 5 / 12; }
}
@media (max-width: 839px) {
  .cs-proof { grid-template-columns: 1fr; gap: var(--space-md); }
}

/* ---- Narrow project story (Degree Planner) ------------------------------------------
   .case-study--narrow: the same system, composed lighter and more vertical. Prose runs
   on the hero intro's measure (655px), text-only beats step across the grid
   (.cs-from-5 is the one extra start), and a single product image sits on its own
   stage instead of a full-width hero crop. */
.case-study--narrow { --cs-measure: 655px; }
@media (min-width: 840px) {
  .cs-grid > .cs-from-5 { grid-column-start: 3; }
}
@media (min-width: 1200px) {
  .cs-grid > .cs-from-5 { grid-column-start: 5; }
}
/* The opening product proof: two real ChatGPT screens side by side (six columns each,
   about 2x at 1200+), equal height by crop, each with its own caption. Stacked on phones. */
.cs-duo {
  display: grid;
  gap: var(--space-xl) var(--grid-gutter);
}
.cs-duo > figure { margin: 0; min-width: 0; }
@media (min-width: 840px) {
  .cs-duo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Sets of figures (the three concepts, the proof-of-concept cards): each figure keeps
   its own caption; the set sits one text -> media step under its copy. */
.cs-film > figure { margin: 0; min-width: 0; }
/* --stack: the same set, one figure per row across the content width, so each
   screen is large enough to read (Degree Planner's three concepts). Whole
   images at their own ratios; caption 16 under its image, 40 (32 on phones)
   to the next image. */
.cs-film--stack { grid-template-columns: 1fr; row-gap: 40px; }
.cs-grid > .cs-film--stack { grid-column: 1 / -1; }
@media (max-width: 839px) { .cs-film--stack { row-gap: 32px; } }
/* "Make the Plan Actionable": the copy beside the full live result, a tall narrow screen
   (772px source) in four columns at 1200+, five on tablet; stacked on phones. */
@media (min-width: 840px) {
  .cs-split--tall > .cs-split__head,
  .cs-split--tall > .cs-split__text { grid-column: 1 / span 7; }
  .cs-split--tall > .cs-split__media { grid-column: 8 / -1; }
}
@media (min-width: 1200px) {
  .cs-split--tall > .cs-split__head,
  .cs-split--tall > .cs-split__text { grid-column: 1 / span 6; }
  .cs-split--tall > .cs-split__media { grid-column: 8 / 12; }
}
/* A before/after pair of real header strips in one card (realism -> % realistic), the same
   4:3 box as its neighbours, centred on a neutral field (artwork: not themed). */
.case-study .cs-media.cs-media--evolve {
  aspect-ratio: 4 / 3;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-md);
  padding: var(--space-lg);
  background: #F8FAFD;
}
.cs-evolve__arrow {
  align-self: center;
  width: 10px;
  height: 10px;
  border-right: 1.5px solid #9AA3B2;
  border-bottom: 1.5px solid #9AA3B2;
  transform: rotate(45deg);
}
/* This CTA's label is longer than ECE's, so on phones it wraps instead of running
   past the panel. */
@media (max-width: 839px) {
  .case-study--narrow .cs-cta__label { white-space: normal; }
}
/* The outcome's CTA panel follows the outcome copy in the same columns. */
@media (min-width: 840px) {
  .cs-outcome > .cs-cta { grid-column: 5 / -1; }
}
@media (min-width: 1200px) {
  .cs-outcome > .cs-cta { grid-column: 5 / 12; }
}

/* ---- Ending -----------------------------------------------------------------------
   Next Case Study + View All Work keep their approved pattern and styling
   (.case-next, components.css). Only its vertical spacing is set here: a module
   change to its one rule, then the nav content centred in its own band, --cs-group
   below the rule and --cs-group above the footer. */
.case-study + .case-next { margin-top: var(--cs-module); }
.case-study + .case-next .case-next__inner { padding-block: var(--cs-group); }
