/* ============================================================
   Case study page — the few pieces the shared components don't
   already cover. Everything else comes from design-system.css
   (grid, spacers, themes, type) and components.css (nav, cursor,
   media, buttons, section-top).
   ============================================================ */

/* the project title sits at hero scale but shorter than the home wordmark */
.case-title {
  font-size: clamp(2.75rem, 9vw, 9rem);
  line-height: .9;
  letter-spacing: -.03em;
}


/* Decision blocks: A / B / chosen. The chosen one is marked by weight and a
   rule rather than a new colour — the dark theme only has --fg to spend. */
.case-options { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; }
.case-options li {
  padding: 16px 0 0;
  border-top: 1px solid var(--line);
}
.case-options span { display: block; margin-bottom: 8px; }
.case-options .is--chosen { font-weight: 600; }
.case-options .is--chosen span { color: var(--fg); }
.case-options em { font-style: normal; font-weight: 600; }

.case-decision { row-gap: 24px; align-items: start; }

.case-actions { display: flex; gap: 12px; flex-wrap: wrap; justify-content: flex-end; }

@media (max-width: 767px) {
  .case-actions { justify-content: flex-start; }
}

/* ── case-study media layout ──────────────────────────────────────────── */
/* Column offsets so figures can sit inset rather than spanning the grid.
   grid-column-start alone would override the `span` in .u-col-*, collapsing the
   figure to one column — so start and span are set together via --span. */
.case-fig { --span: 1; }
.case-fig.u-col-2 { --span: 2; }
.case-fig.u-col-3 { --span: 3; }
.case-fig.u-col-4 { --span: 4; }
.case-fig.u-col-5 { --span: 5; }
.case-fig.u-col-6 { --span: 6; }
.case-fig.u-start-2 { grid-column: 2 / span var(--span); }
.case-fig.u-start-3 { grid-column: 3 / span var(--span); }
.case-fig.u-start-4 { grid-column: 4 / span var(--span); }
.case-fig.u-start-5 { grid-column: 5 / span var(--span); }

/* Extra ratios: product screens are 16:9, dashboards closer to 3:2. */
.media-w[data-wf--media--variant="ratio-16-9"]  { --ratio: 16 / 9; }
.media-w[data-wf--media--variant="ratio-16-10"] { --ratio: 16 / 10; }
.media-w[data-wf--media--variant="ratio-3-2"]   { --ratio: 3 / 2; }
.media-w[data-wf--media--variant="ratio-2-4-1"] { --ratio: 2.4 / 1; }

/* UI screenshots must not be cropped — contain them on a tinted plate. */
.media-inner .img--contain {
  object-fit: contain;
  background: var(--plate, rgba(0, 0, 0, .04));
}
[data-section-theme="dark"] .media-inner .img--contain { --plate: rgba(255, 255, 255, .06); }
[data-section-theme="orange"] .media-inner .img--contain { --plate: rgba(0, 0, 0, .07); }
.media-inner video.img { display: block; }

/* Art that wants to be narrower than its column. Capping the figure itself
   doesn't work: auto margins and justify-self both switch a grid item to
   fit-content, and .media-w has no intrinsic width — its image is absolutely
   positioned — so the box collapses. Capping the media box inside a still-
   stretched cell keeps the width definite, and the caption follows it so the
   pair stays centred instead of stepping down a whole column and losing the
   midline the rest of the run sits on. */
.case-fig.is--narrow .media-w { max-width: var(--fig-max, 520px); margin-inline: auto; }
.case-fig.is--narrow figcaption { text-align: center; }

/* Three figures that only mean anything read together. No span of the
   5-column mobile grid divides into three, so on small screens the row
   switches to its own three-track grid instead of stacking into three
   screen-height heads and losing the comparison entirely. */
@media (max-width: 767px) {
  .row.is--triptych { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .row.is--triptych > .case-fig { grid-column: span 1; }
}

/* Figure + caption */
.case-fig { margin: 0; }
.case-fig figcaption { display: block; margin-top: 12px; opacity: .55; }

@media (max-width: 767px) {
  .case-fig.u-start-2, .case-fig.u-start-3,
  .case-fig.u-start-4, .case-fig.u-start-5 { grid-column: span 5; }
}

/* Two clips ship with a caption burned into the frame at a size that fights the
   page. The box is set to the clip's ratio minus that band and the video is
   anchored to the top, so the band is cropped and the caption below is ours. */
.media-inner.is--cropfoot {
  inset: 0;          /* cancel the -12%/124% parallax oversize so the crop is exact */
  height: 100%;
}
.media-inner.is--cropfoot video {
  object-fit: cover;
  object-position: top center;
}


/* Screenshot sits flush in a frame cut to its own ratio: cancel the parallax
   oversize, or `cover` fills the 124%-tall inner and crops the sides off. */
.media-inner.is--flush {
  inset: 0;
  height: 100%;
}

/* Figures sized to the source page's own container dimensions: a fixed
   max-width, centred in the grid, with the media box cut to the same ratio. */
.case-fig.is--fixed { margin-inline: auto; width: 100%; }

/* The theme comparison carries a hairline and a soft corner in the original. */
.case-fig.is--plate .media-w {
  border: 1px solid rgba(0, 0, 0, .1);
  border-radius: 8px;
}

/* ============================================================
   LAYOUT · editorial spread
   The page used to be one flat stack: label left, prose right,
   full-width figure under it, repeated eight times. These are the
   pieces that break that up.
   ============================================================ */

/* ── eyebrow pills ────────────────────────────────────────────────────── */
/* Replaces the square-bullet section label. A filled chip reads as a tag
   rather than a heading, which is what it is. */
.case-eyebrow {
  display: inline-block;
  padding: 6px 12px;
  border-radius: 100px;
  background: rgba(0, 0, 0, .07);
  color: var(--fg);
}
.case-eyebrow.is--accent { background: var(--c-orange); color: var(--c-black); }
.case-eyebrow.is--invert { background: var(--fg); color: var(--bg); }

.case-eyebrows { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.case-eyebrow__date { margin-left: 4px; }

/* ── hero meta ────────────────────────────────────────────────────────── */
/* The four facts are ruled rows, not filled cards: the page states everything
   else — tour rows, captions, decision options — with a hairline and a caps
   label, and the hero shouldn't be the one place that introduces a box. */
.case-notes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
}
.case-note {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  padding: 11px 0;
  border-top: 1px solid var(--line);
}
.case-note:last-child { border-bottom: 1px solid var(--line); }
.case-note span { flex: none; }

/* ── the spread ───────────────────────────────────────────────────────── */
/* Prose sits centred against the media column rather than riding its top
   edge, so a short paragraph doesn't leave a tall gap beside a tall figure.
   .is--flip puts the media on the left. Below 768px it collapses to one
   column and the order is text, then media. */
.spread { display: grid; gap: 40px; }
.spread__text > * + * { margin-top: 16px; }
.spread__text h2,
.spread__text h3 { margin-top: 28px; }
.spread__text > :first-child { margin-top: 0; }
.spread__media { display: grid; gap: 40px; }

@media (min-width: 768px) {
  .spread {
    grid-template-columns: 3fr 5fr;
    gap: 56px;
    align-items: center;   /* prose sits on the media's midline */
  }
  /* the flip mirrors the columns too, so the narrow side stays with the prose */
  .spread.is--flip { grid-template-columns: 5fr 3fr; }
  .spread.is--flip .spread__text { order: 2; }
  .spread.is--flip .spread__media { order: 1; }
}

/* Figures in a spread run smaller than their column: at full width the
   screenshots overpower the prose they sit beside, and the UI inside them is
   already small enough to need a second look either way. */
@media (min-width: 768px) {
  .spread__media .case-fig { max-width: var(--fig-w, 80%); }
}

/* A spread with no prose beside it: the media runs wider than the figures that
   sit next to an argument — this is the one that should carry the page — and
   the note tucks into the narrow column beside it. */
.spread.is--media-only { grid-template-columns: 1fr; }

@media (min-width: 768px) {
  .spread.is--media-only .spread__media {
    grid-template-columns: 2fr 1fr;
    align-items: center;
    gap: 40px 48px;
  }
  .spread.is--media-only .spread__media .case-fig { max-width: 100%; }
}

/* a note that belongs to the media, not the argument */
.case-aside { opacity: .75; max-width: 46ch; }

/* ── result callout ───────────────────────────────────────────────────── */
/* The one line in a section that carries the finding. A rule and a slight
   size bump, rather than another colour. */
.case-result {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-weight: 600;
}
.case-result em { font-style: normal; font-weight: 700; }

/* ── pull quote ───────────────────────────────────────────────────────── */
.case-quote__text {
  max-width: 26ch;
  margin-inline: auto;            /* centred, which also clears the fixed rail */
  text-align: center;
  font-size: clamp(1.5rem, 4.5vw, 3.25rem);
  line-height: 1.1;
  letter-spacing: -.02em;
}

/* ── decision cards ───────────────────────────────────────────────────── */
/* Option A / Option B / Chosen as three cards rather than three list rows:
   the comparison is the point, so they get equal boxes and read across. */
.case-decision2 + .case-decision2 { margin-top: 64px; }
.case-decision2__head { max-width: 52ch; }
.case-decision2__head h3 { margin-top: 12px; }

.opt-list {
  list-style: none; margin: 28px 0 0; padding: 0;
  display: grid; gap: 16px;
}
.opt {
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: 12px;
}
.opt__label { display: block; margin-bottom: 8px; color: var(--c-light-40); }
.opt p { margin: 0; }
.opt em { font-style: normal; font-weight: 600; }

/* the chosen one takes the accent stroke — orange is the site's "here" colour */
.opt.is--chosen {
  border-color: var(--c-orange);
  background: rgba(255, 255, 255, .06);
}
.opt.is--chosen .opt__label { color: var(--c-orange); font-weight: 700; }

@media (min-width: 900px) {
  .opt-list { grid-template-columns: repeat(3, 1fr); }
}

/* ── misc ─────────────────────────────────────────────────────────────── */
.case-lede { max-width: 52ch; }
.case-sub__note { max-width: 46ch; }
.case-hero__row { row-gap: 32px; align-items: start; }

/* ── browser chrome ───────────────────────────────────────────────────── */
/* Product screenshots sit in a macOS-style window so a UI shot reads as a
   captured screen rather than as page furniture. Photos and the cover image
   stay unframed — the frame is a claim that what's inside is software. */
.browser {
  overflow: hidden;
  border: 1px solid rgba(0, 0, 0, .10);
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .12);
}
.browser__bar {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 14px;
  background: #f3f1ee;
  border-bottom: 1px solid rgba(0, 0, 0, .07);
}
.browser__bar i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #ff5f57;
}
.browser__bar i:nth-child(2) { background: #febc2e; }
.browser__bar i:nth-child(3) { background: #28c840; }

@media (max-width: 767px) {
  .browser { border-radius: 10px; }
  .browser__bar { height: 26px; padding: 0 10px; gap: 6px; }
  .browser__bar i { width: 8px; height: 8px; }
}

/* The Zenbot recording already carries its own title bar, so it takes the
   frame without a second one — border and radius only. */
.browser.is--bare .media-w { border-radius: 13px; }

/* A photograph gets the frame's corner radius but none of its chrome: it is
   not a screen, so traffic lights would be a lie about what you're looking at. */
.case-fig.is--round .media-w {
  overflow: hidden;
  border-radius: 14px;
}

/* ── decisions ────────────────────────────────────────────────────────── */
/* Each decision reads as a spread like the rest of the page: the call and its
   consequence on one side, the options considered on the other. The three
   options are a ruled list rather than three equal cards — equal cards implied
   the rejected paths carried equal weight, which is the opposite of the point. */
.decision .spread__text > .p-s { display: block; }
.decision__result {
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-weight: 600;
}

.opts { display: grid; margin: 0; padding: 0; list-style: none; }
.opt2 {
  position: relative;
  padding: 22px 0 22px 24px;
  border-top: 1px solid var(--line);
}
.opt2:last-child { border-bottom: 1px solid var(--line); }
.opt2::before {
  content: "";
  position: absolute;
  top: 22px;
  bottom: 22px;
  left: 0;
  width: 2px;
  background: var(--line);
}
.opt2__tag { display: block; margin-bottom: 8px; color: var(--c-light-40); }
.opt2 p { margin: 0; opacity: .7; }

/* the chosen path is the only one that gets the accent and full contrast */
.opt2.is--chosen::before { background: var(--c-orange); }
.opt2.is--chosen .opt2__tag { color: var(--c-orange); font-weight: 700; }
.opt2.is--chosen p { opacity: 1; }

/* ── image placeholders ───────────────────────────────────────────────── */
/* A case study gets built before its screenshots exist. The placeholder holds
   the exact box the real asset will occupy — it sits directly in .media-w
   rather than in the oversized .media-inner, so its label stays centred in the
   visible frame. Swapping in the real asset means replacing the .case-ph with
   the usual <div class="media-inner"><img class="img" …></div>. */
.case-ph {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 16px;
  background: repeating-linear-gradient(45deg,
    transparent 0 11px,
    rgba(128, 128, 128, .10) 11px 22px);
  border: 1px dashed var(--line);
}
.case-ph span { opacity: .45; }

/* inside browser chrome the dashed edge would double the frame's own border */
.browser .case-ph { border: 0; border-top: 1px dashed var(--line); }
.browser.is--bare .case-ph { border-top: 0; }

/* ============================================================
   LAYOUT · variants for the non-Zenxo case studies
   Zenxo is one argument told in spreads: prose beside a screen,
   eight times. Brand work is a set of places a mark shows up, and
   another product can't borrow the same nine beats without reading
   as a template. These are the few pieces those pages need —
   grid, themes, type and media still come from the shared files.
   ============================================================ */

/* A hero that centres rather than splitting. Used where the project
   opens on an image instead of an argument, so the facts belong
   under the title rather than in a column beside it. */
.case-hero.is--centred { text-align: center; }
.case-hero.is--centred .case-eyebrows { justify-content: center; }
.case-hero.is--centred .case-lede { margin-inline: auto; }

/* Equal squares that read across as a set — palette chips, pack
   faces, screens. The .row supplies the columns; this only stops
   the figure inheriting the spread's 80% cap. */
.case-tile { margin: 0; max-width: none; }
.case-tile figcaption { margin-top: 10px; opacity: .55; }

/* A run of applications scrolled rather than stacked: brand
   touchpoints are a list of places, not a sequence of steps, so
   they get a horizontal shelf instead of eight stacked figures. */
.case-strip {
  display: flex;
  gap: var(--gutter);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 10px;
}
.case-strip > * {
  flex: none;
  width: clamp(200px, 24vw, 340px);
  scroll-snap-align: start;
  margin: 0;
}
.case-strip::-webkit-scrollbar { height: 4px; }
.case-strip::-webkit-scrollbar-thumb { background: var(--line); }

/* Chapters of a build, numbered. The figure sits top-aligned beside
   its prose at full column width — deliberately not .spread, whose
   centred midline and 80% figure are Zenxo's rhythm. */
.case-chapter { row-gap: 24px; align-items: start; }
.case-chapter + .case-chapter { margin-top: 88px; }
.case-chapter__num { display: block; margin-bottom: 10px; opacity: .45; }

/* One number stated large under a ruled label, for a results row.
   Opacity rather than --c-dark-40 so it survives the dark theme. */
.case-stat { border-top: 1px solid var(--line); padding-top: 14px; }
.case-stat__n {
  display: block;
  font-size: clamp(1.75rem, 3.4vw, 3rem);
  line-height: 1;
  letter-spacing: -.03em;
  font-weight: 700;
}
.case-stat__l { display: block; margin-top: 10px; opacity: .55; }

@media (max-width: 767px) {
  .case-chapter + .case-chapter { margin-top: 56px; }
}

/* ── phone chrome ─────────────────────────────────────────────────────── */
/* The handset counterpart to .browser, making the same claim: a portrait
   shot framed as a phone reads as the product on a phone, rather than as a
   tall crop of the desktop page. Bezel and radius only — no notch is drawn,
   because the screenshot arrives carrying its own status bar and anything
   painted over it would be a second, fake one. */
.phone {
  position: relative;
  padding: 8px;
  border-radius: 30px;
  background: var(--bezel, #e6e2dc);
  border: 1px solid rgba(0, 0, 0, .12);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .16);
}
.phone .media-w { border-radius: 23px; }
.phone .case-ph { border: 0; }

/* the bezel is the one part that has to be re-stated per theme: a light
   shell vanishes on the dark sections this page is mostly made of */
[data-section-theme="dark"]   .phone { --bezel: #262626; border-color: rgba(255, 255, 255, .16); }
[data-section-theme="orange"] .phone { --bezel: rgba(0, 0, 0, .14); }

.media-w[data-wf--media--variant="ratio-9-19-5"] { --ratio: 9 / 19.5; }

/* Phones run as a centred row at a capped width rather than on the 8-column
   grid: at two columns each a 9:19.5 frame is 700px tall, which turns four
   screens into a wall. They wrap instead of scrolling — a handful of screens
   is a set to take in, not a shelf to travel along. */
.case-phones {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(16px, 2.4vw, 36px);
}
.case-phones > * { flex: 0 1 clamp(172px, 18vw, 264px); margin: 0; }
.case-phones figcaption { text-align: center; }

@media (max-width: 767px) {
  .phone { border-radius: 24px; padding: 6px; }
  .phone .media-w { border-radius: 19px; }
}

/* A phone design is a whole scrolling page — 390×2666 in the file, not a
   390×844 viewport. Cover-cropping it from the centre would land the frame
   somewhere in the middle of the page with the header gone, so the crop is
   anchored to the top: what you see is the screen as it opens. is--flush
   cancels the parallax oversize so the crop is exactly the frame. */
.phone .media-inner .img { object-position: top center; }

/* The desk screens are whole scrolling pages too, at eight different heights.
   One shared ratio makes the set read as a set; anchoring to the top means the
   window shows each page as it opens rather than slicing out its middle.
   Scoped to is--flush so Zenxo's parallax browser shots keep their own crop. */
.browser .media-inner.is--flush .img { object-position: top center; }

/* .xp__org and .xp__note are dark-on-light by default — they were written for
   the about page's experience list, which only ever sits on a light ground.
   Reused on a dark section they resolve to black at 40% and disappear, so
   restate them against the inverted ground. */
[data-section-theme="dark"] .xp__org,
[data-section-theme="dark"] .xp__note { color: var(--c-light-40); }
