/* Product film, Apple-style section (24 Sept, v2). White page, centred
   headline, the MacBook at a readable size (max 60rem), sticky while the
   scroll opens it. The screen layer sits on the lid's glass as measured on
   the final frame (frames cropped to the laptop: x 360 to 1080, y 80 to 700 of the 1440 x 816 video). */
.mac { padding-top: clamp(5rem, 10vw, 9rem); background: #fff; color: var(--ed-ink, #121417); }
.mac__intro { text-align: center; padding-inline: 1.5rem; }
.mac__intro h2 { font-size: clamp(2.5rem, 5.5vw, 4.5rem); line-height: 1.02; letter-spacing: -.045em; font-weight: 500; }
.mac__intro h2 span { color: var(--ed-muted, #6b7280); }
.mac__track { position: relative; height: 320vh; }
.mac__stick { position: sticky; top: 0; height: 100vh; display: grid; grid-template-rows: 1fr auto; align-items: center; justify-items: center; padding-block: 5.5rem 3rem; box-sizing: border-box; overflow: hidden; }
.mac__stage { position: relative; width: min(52rem, 88vw, calc((100vh - 13rem) * 720 / 620)); aspect-ratio: 720 / 620; transform: scale(calc(1 + var(--zoom, 0) * .06)); transform-origin: 50% 60%; }
.mac__stage::after { content: ""; position: absolute; left: 4%; right: 4%; bottom: 5%; height: 7%; z-index: -1; border-radius: 50%; background: radial-gradient(closest-side, rgb(18 20 23 / .22), rgb(18 20 23 / 0)); filter: blur(6px); }
.mac__canvas, .mac__poster { position: absolute; inset: 0; width: 100%; height: 100%; }
.mac__poster { display: none; }
.mac__screen { position: absolute; left: 12.69%; top: 8.42%; width: 73.9%; height: 55.55%; overflow: hidden; border-radius: .4% / .7%; background: #fff; opacity: var(--wake, 0); }
.mac__landing { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; transform: translateY(calc(var(--scroll, 0) * -6%)); filter: blur(calc(var(--adv, 0) * 1.5px)); }
/* One line of copy under the device per phase. */
.mac__captions { position: relative; width: min(40rem, 90vw); height: 3.5rem; list-style: none; margin: 0; padding: 0; text-align: center; }
.mac__captions li { position: absolute; inset: 0; font-size: clamp(1.125rem, 1.7vw, 1.5rem); line-height: 1.35; letter-spacing: -.02em; color: var(--ed-muted, #6b7280);
  opacity: 0; transform: translateY(8px); transition: opacity 450ms ease, transform 550ms cubic-bezier(.2, .8, .2, 1); }
.mac__captions li b { color: var(--ed-ink, #121417); font-weight: 500; }
.mac__captions li.is-on { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .mac__track { height: auto; }
  .mac__stick { position: relative; height: auto; }
  .mac__canvas { display: none; } .mac__poster { display: block; }
  .mac__screen { --wake: 1; }
  .mac__captions { height: auto; } .mac__captions li { position: static; opacity: 1; transform: none; margin-top: .5rem; }
  .mac__caret { animation: none; }
}

/* ================= Case hero v2 ================= */
.ch { width: min(100% - 3rem, 75rem); margin: 0 auto; padding-top: 2rem; color: var(--ed-ink, #121417); }
.ch__back { display: inline-flex; align-items: center; gap: .5rem; font-size: .9375rem; color: var(--ed-muted, #51565e); text-decoration: none; }
.ch__back svg { width: 1rem; height: 1rem; }
.ch__back:hover { color: var(--brand); }
.ch__grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(2rem, 5vw, 5rem); align-items: center; margin-top: clamp(2.5rem, 5vw, 4rem); }
.ch__logo { height: 1.75rem; width: auto; }
.ch__title { margin-top: 1.5rem; font-size: clamp(2.25rem, 4vw, 3.5rem); line-height: 1.04; letter-spacing: -.045em; font-weight: 500; text-wrap: balance; }
.ch__lede { margin-top: 1.25rem; font-size: 1.125rem; line-height: 1.55; color: var(--ed-muted, #51565e); max-width: 32rem; }
.ch__facts { display: flex; gap: 2.5rem; margin: 2rem 0 0; padding-top: 1.25rem; border-top: 1px solid var(--ed-line, #d8dce1); }
.ch__facts dt { font-size: .875rem; color: var(--ed-muted, #51565e); }
.ch__facts dd { margin: .25rem 0 0; font-size: 1rem; font-weight: 500; }
.ch__shot { margin: 0; }
.ch__window { border-radius: 12px; overflow: hidden; background: #fff; box-shadow: 0 0 0 1px rgb(18 20 23 / .06), 0 30px 60px -30px rgb(18 32 80 / .35); }
.ch__dots { display: flex; gap: 6px; padding: 10px 14px; background: #f3f4f6; border-bottom: 1px solid #e7e9ee; }
.ch__dots i { width: 10px; height: 10px; border-radius: 50%; background: #d8dce1; }
.ch__window img { display: block; width: 100%; height: auto; }
.ch__kpis { list-style: none; margin: clamp(3.5rem, 6vw, 5rem) 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--ed-line, #d8dce1); border-bottom: 1px solid var(--ed-line, #d8dce1); }
.ch__kpis li { display: grid; gap: .375rem; padding: 2rem 1.5rem 2rem 0; }
.ch__kpis li + li { padding-left: 1.5rem; border-left: 1px solid var(--ed-line, #d8dce1); }
.ch__kpis b { font-size: clamp(2.75rem, 5vw, 4.5rem); line-height: 1; letter-spacing: -.05em; font-weight: 500; font-variant-numeric: tabular-nums; }
.ch__kpis li:first-child b { color: var(--brand); }
.ch__kpis span { font-size: 1rem; color: var(--ed-muted, #51565e); }
@media (max-width: 899px) {
  .ch__grid { grid-template-columns: 1fr; }
  .ch__kpis { grid-template-columns: 1fr; } .ch__kpis li + li { padding-left: 0; border-left: 0; border-top: 1px solid var(--ed-line, #d8dce1); }
}
/* Product film: the closed laptop is there from the start, no empty gap. */
.mac { padding-top: clamp(4rem, 8vw, 7rem); }
.mac__stage { background: url("../../video/sortlist-macbook/open-001.webp?v=2") center / 100% 100% no-repeat; }
.mac__stage.is-ready { background: none; }
.mac__stick { padding-block: 4.5rem 2.5rem; }
.ch__mac { display: block; width: 100%; height: auto; filter: drop-shadow(0 30px 30px rgb(18 32 80 / .18)); }
/* Template rule (24 Sept): the screen shows only the project's own
   screenshots, no UI built by us on top. The page scrolls gently inside. */
.mac__landing { filter: none; }
/* Hero v3 (Hulusi): no device; one cobalt plate with the product's own
   screen laid on it, bleeding off the plate's right edge. It rises in. */
.ch__plate { position: relative; aspect-ratio: 5 / 4; border-radius: 10px; overflow: hidden; background: #0b2a8a url("../../img/backgrounds/dream/figma/hero/ai-bg-097.webp") center / cover; }
.ch__ui { position: absolute; left: 9%; top: 16%; width: 108%; max-width: none; height: auto; border-radius: 8px;
  box-shadow: 0 1px 0 rgb(255 255 255 / .5) inset, 0 30px 60px -20px rgb(0 10 60 / .55); animation: ch-rise 1100ms cubic-bezier(.2, .8, .2, 1) 150ms both; }
@keyframes ch-rise { from { transform: translateY(8%); opacity: 0; } }
/* Figures: fixed width while they count, so nothing jumps. */
.ch__kpis b { display: block; min-width: 5ch; }
@media (prefers-reduced-motion: reduce) { .ch__ui { animation: none; } }

/* ================= Case sections (template) ================= */
.cs-track { position: relative; height: 260vh; }
.cs-stick { position: sticky; top: 0; height: 100vh; box-sizing: border-box; padding: 6rem clamp(1.5rem, 5vw, 5rem) 3rem; display: grid; align-content: center; justify-items: center; overflow: hidden; }
.cs-head { text-align: center; max-width: 44rem; }
.cs-head h2 { font-size: clamp(2.25rem, 4.6vw, 3.75rem); line-height: 1.04; letter-spacing: -.045em; font-weight: 500; }
.cs-head h2 span { color: var(--ed-muted, #6b7280); }
.cs-head p { margin-top: 1rem; font-size: 1.125rem; line-height: 1.5; color: var(--ed-muted, #51565e); }
.cs-shot, .cs-card img, .cs-zoom__frame, .cs-row__rail img { border-radius: 10px; box-shadow: 0 0 0 1px rgb(18 20 23 / .06), 0 30px 60px -30px rgb(18 32 80 / .35); background: #fff; }

/* Stack: the screens fly in from below, fanned, and settle as a layered deck. */
.cs-stack__deck { position: relative; width: min(56rem, 86vw); aspect-ratio: 16 / 8; margin-top: 3rem; }
.cs-card { position: absolute; margin: 0; width: 78%; left: calc(var(--i) * 22%); top: calc(var(--i) * 22%);
  --t: calc(1 - var(--p, 0)); transform: translateY(calc(var(--t) * (60% + var(--i) * 40%))) rotate(calc(var(--t) * (var(--i) * 6deg - 3deg))); opacity: calc(.2 + var(--p, 0) * .8);
  transition: transform 150ms linear; z-index: calc(var(--i) + 1); }
.cs-card img { display: block; width: 100%; height: auto; transition: transform 400ms cubic-bezier(.2, .8, .2, 1), box-shadow 400ms ease; }
@media (hover: hover) and (pointer: fine) { .cs-card:hover { z-index: 9; } .cs-card:hover img { transform: translateY(-4%) scale(1.03); box-shadow: 0 0 0 1px rgb(18 20 23 / .06), 0 40px 70px -30px rgb(18 32 80 / .5); } }

/* Zoom: one real screen, the scroll pushes into a detail; the copy arrives. */
.cs-zoom .cs-stick { grid-template-columns: minmax(0, 1fr); }
.cs-zoom__frame { position: relative; width: min(62rem, 90vw); aspect-ratio: 1062 / 424; overflow: hidden; }
.cs-zoom__frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transform-origin: 22% 88%; transform: scale(calc(1 + var(--p, 0) * 2.2)); }
.cs-zoom__copy { max-width: 40rem; margin-top: 2.5rem; text-align: center; opacity: clamp(0, calc((var(--p, 0) - .45) * 3), 1); transform: translateY(calc((1 - clamp(0, calc((var(--p, 0) - .45) * 3), 1)) * 12px)); }
.cs-zoom__copy h2 { font-size: clamp(1.75rem, 3.4vw, 2.75rem); line-height: 1.1; letter-spacing: -.035em; font-weight: 500; }
.cs-zoom__copy p { margin-top: .75rem; font-size: 1.125rem; line-height: 1.5; color: var(--ed-muted, #51565e); }

/* Row: the screens slide sideways as the page scrolls down. */
.cs-row .cs-stick { justify-items: start; }
.cs-head--left { text-align: left; }
.cs-row__rail { display: flex; gap: 2rem; margin-top: 3rem; transform: translateX(calc(var(--p, 0) * -1 * var(--travel, 0px))); will-change: transform; }
.cs-row__rail figure { margin: 0; flex: 0 0 auto; }
.cs-row__rail img { display: block; height: min(22rem, 42vh); width: auto; }
.cs-row__rail figcaption { margin-top: .875rem; font-size: 1rem; color: var(--ed-muted, #51565e); }
@media (prefers-reduced-motion: reduce) {
  .cs-track { height: auto; } .cs-stick { position: relative; height: auto; }
  .cs-card, .cs-zoom__frame img, .cs-row__rail { transform: none !important; opacity: 1 !important; }
  .cs-zoom__copy { opacity: 1; transform: none; } .cs-row__rail { flex-wrap: wrap; }
}
/* tuning: the zoom stays within the screenshot's resolution; a larger deck. */
.cs-zoom__frame img { transform-origin: 26% 86%; transform: scale(calc(1 + var(--p, 0) * .6)); }
.cs-stack__deck { width: min(64rem, 90vw); }

/* Laptop tier (24 Sept, Hulusi: most visitors use a 14" MacBook, about
   1350 x 700 of window). Title on 3 lines, big headings scaled down. */
@media (min-width: 1024px) and (max-width: 1600px) {
  .ch { padding-top: 1.25rem; }
  .ch__grid { grid-template-columns: minmax(0, 6fr) minmax(0, 7fr); margin-top: clamp(1.5rem, 3.5svh, 2.5rem); }
  .ch__title { font-size: clamp(2.125rem, 3.2vw, 2.75rem); }
  .ch__lede { font-size: 1.0625rem; }
  #mac-title { font-size: clamp(2.25rem, 3.8vw, 3.25rem); }
  #cs-zoom-title { font-size: clamp(1.875rem, 2.6vw, 2.25rem); }
}

/* ================= Case hero v5 (25 Sept): minimal, flush-left =================
   Hulusi: v4 (centred, tilting browser windows) "still shitty"; professional
   and minimal. The site's Swiss grid: headline flush left with the grey
   second half, one ruled row of lede and facts, one cobalt plate with the
   product's own screen at a size its pixels hold. */
.hx { padding-top: 1.5rem; }
.hx__title { margin: clamp(2.5rem, 6vh, 4.5rem) 0 0; max-width: 14em; font-size: clamp(2.5rem, 5.4vw, 4.75rem); line-height: 1.02; letter-spacing: -.05em; font-weight: 500; }
.hx__title em { font-style: normal; color: var(--ed-muted, #6b7280); }
.hx__line { display: block; overflow: hidden; padding-bottom: .08em; }
.hx__line > span { display: inline-block; animation: hx-rise 1000ms cubic-bezier(.2, .8, .2, 1) both; }
.hx__line:nth-child(2) > span { animation-delay: 90ms; }
@keyframes hx-rise { from { transform: translateY(105%); } }
@keyframes hx-fade { from { opacity: 0; transform: translateY(10px); } }

.hx__meta { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 2rem clamp(2rem, 6vw, 6rem); margin-top: clamp(2rem, 5vh, 3.5rem); padding-top: 1.25rem; border-top: 1px solid var(--ed-line, #d8dce1);
  animation: hx-fade 800ms cubic-bezier(.2, .8, .2, 1) 250ms both; }
.hx__lede { margin: 0; max-width: 30rem; font-size: 1.0625rem; line-height: 1.55; color: var(--ed-muted, #51565e); }
.hx__facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.5rem; margin: 0; }
.hx__facts dt { font-size: .875rem; color: var(--ed-muted, #51565e); }
.hx__facts dd { margin: .25rem 0 0; font-size: 1rem; font-weight: 500; }

/* The plate: cobalt atmosphere, the screen set low so it rises out of the
   bottom edge. It opens from a slightly inset frame on load. */
.hx__plate { position: relative; margin: clamp(2.5rem, 6vh, 4rem) 0 0; height: clamp(20rem, 54vh, 33rem); overflow: hidden; border-radius: 12px;
  background: #0b2a8a url("../../img/backgrounds/dream/figma/hero/ai-bg-097.webp") center / cover; /* 13 Oct 2026: dream plate under the photograph, no grain */
  animation: hx-open 1200ms cubic-bezier(.2, .8, .2, 1) 150ms both; }
@keyframes hx-open { from { clip-path: inset(6% 4% 0 4% round 12px); } to { clip-path: inset(0 round 12px); } }
.hx__screen { position: absolute; left: 50%; bottom: 0; width: min(86%, 56rem); height: auto; max-width: none; border-radius: 10px 10px 0 0;
  box-shadow: 0 0 0 1px rgb(255 255 255 / .25), 0 -20px 60px -20px rgb(0 10 60 / .5);
  transform: translate(-50%, calc(12% - var(--hx, 0) * 8%)); animation: hx-screen 1300ms cubic-bezier(.2, .8, .2, 1) 300ms both; }
@keyframes hx-screen { from { opacity: 0; translate: 0 8%; } }
.hx .ch__kpis { margin-top: clamp(3rem, 6vw, 4.5rem); }

@media (max-width: 899px) {
  .hx__meta { grid-template-columns: 1fr; }
  .hx__facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hx__plate { height: auto; aspect-ratio: 16 / 10; }
  .hx__screen { width: 94%; }
}
@media (prefers-reduced-motion: reduce) {
  .hx__line > span, .hx__meta, .hx__plate, .hx__screen { animation: none; }
  .hx__screen { transform: translate(-50%, 8%); }
}

/* Film: the straightened screens; the Advisor takes over from the landing
   page at the second caption (--adv from case-mac.js). */
.mac__landing { object-position: left top; }
.mac__landing--adv { opacity: var(--adv, 0); transform: none; transition: opacity 400ms ease; }

/* Story blocks rise in as they enter (case-mac.js adds .is-in). */
.js-reveal { opacity: 0; transform: translateY(24px); transition: opacity 700ms ease, transform 900ms cubic-bezier(.2, .8, .2, 1); }
.js-reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .js-reveal { opacity: 1; transform: none; transition: none; } }

/* ================= Phone raise (template, 25 Sept, v2) =================
   Hulusi: the scene sat in a grey box (the frames' own ground). The 124
   frames now have their background cut out (video/phone-raise-alpha), so the
   hand floats on the page. Behind it, the section's title in giant type,
   its two lines sliding apart as the phone rises (--pp, 0 to 1). The app's
   own screen lights up at the end. For mobile projects; real screens only. */
.ph { position: relative; width: 100vw; margin: clamp(4rem, 8vw, 7rem) 0 0 calc(50% - 50vw); color: var(--ed-ink, #121417); }
.ph__track { position: relative; height: 280vh; }
.ph__stick { position: sticky; top: 4.5rem; height: calc(100vh - 4.5rem); display: grid; grid-template-rows: 1fr auto; justify-items: center; align-items: end; padding-block: 0 2.5rem; box-sizing: border-box; overflow: hidden; }
.ph__type { position: absolute; left: 50%; top: 50%; z-index: 0; width: 100vw; margin: 0; translate: -50% -58%; display: grid; gap: .1em; text-align: center; pointer-events: none;
  font-size: clamp(2rem, 8.6vw, 9.5rem); line-height: .95; letter-spacing: -.055em; font-weight: 500; white-space: nowrap; }
.ph__l1 { display: block; transform: translateX(calc(var(--pp, 0) * -22%)); }
.ph__l2 { display: block; color: var(--ed-muted, #6b7280); transform: translateX(calc(var(--pp, 0) * 22%)); }
.ph__stage { position: relative; z-index: 1; height: min(80vh, 48rem); aspect-ratio: 704 / 768; align-self: end;
  -webkit-mask-image: linear-gradient(#000 82%, transparent); mask-image: linear-gradient(#000 82%, transparent); }
.ph__stage canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
/* The display, measured on the last frame. */
/* The display, measured on the last frame: the bezel spans x 221 to 477 and
   y 111 to 665 of 704 x 768, the glass 6 px inside it. Corners follow the
   phone's (about 15% of the display's width), and the Dynamic Island is
   drawn on the glass, since the generated phone has none. */
.ph__screen { position: absolute; left: 32.2%; top: 15.2%; width: 34.8%; height: 70.5%; overflow: hidden; border-radius: 15% / 6.9%; opacity: var(--wake, 0); background: #000; }
.ph__screen::after { content: ""; position: absolute; left: 50%; top: 2.4%; width: 32%; height: 3.4%; translate: -50% 0; border-radius: 999px; background: #0b0b0d; box-shadow: inset 0 0 0 1px rgb(255 255 255 / .06); }
.ph__screen img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.ph__captions { position: relative; z-index: 1; width: min(40rem, 90vw); height: 3.5rem; list-style: none; margin: 0; padding: 0; text-align: center; }
.ph__captions li { position: absolute; inset: 0; font-size: clamp(1.125rem, 1.7vw, 1.5rem); line-height: 1.35; color: var(--ed-muted, #6b7280); opacity: 0; transform: translateY(8px); transition: opacity 450ms ease, transform 550ms cubic-bezier(.2, .8, .2, 1); }
.ph__captions li.is-on { opacity: 1; transform: none; }
@media (max-width: 899px) { .ph__track { height: 220vh; } .ph__stage { height: min(62vh, 30rem); } }
@media (prefers-reduced-motion: reduce) {
  .ph__track { height: auto; } .ph__stick { position: relative; top: 0; height: auto; padding-top: 12rem; }
  .ph__l1, .ph__l2 { transform: none; } .ph__screen { --wake: 1; }
  .ph__captions li { position: static; opacity: 1; transform: none; }
}

/* ================= Case pages from Lena's mockups (25 Sept) =================
   The header plate carries the project's slide instead of a screen on the
   cobalt plate; a full-width gallery of the other slides; the client quote;
   "Autres réalisations" as three linked cards. Built by
   project/case-studies/build-pages.py. */
.hx__plate--slide { background: #eceef1; height: auto; aspect-ratio: 16 / 9; }
.hx__slide { display: block; width: 100%; height: 100%; object-fit: cover;
  transform: scale(calc(1.015 - var(--hx, 0) * .015)); transform-origin: 50% 50%; }
/* One to three figures: the row takes as many columns as it has figures. */
.ch__kpis--1 { grid-template-columns: minmax(0, 1fr); }
.ch__kpis--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.cg { display: grid; gap: clamp(1rem, 2vw, 1.5rem); margin-top: clamp(4rem, 8vw, 7rem); }
.cg__item { margin: 0; overflow: hidden; border-radius: 12px; background: #eceef1; aspect-ratio: 16 / 9;
  clip-path: inset(calc((1 - var(--o, 1)) * 6%) calc((1 - var(--o, 1)) * 4%) round 12px); }
.cg__item img { display: block; width: 100%; height: 100%; object-fit: cover; transform: scale(calc(1.08 - var(--o, 1) * .08)); }

.cq { margin: clamp(4rem, 8vw, 7rem) 0 0; padding: 0; border: 0; background: none; }
.cq blockquote { margin: 0; }
.cq blockquote p { margin: 0; max-width: 30em; font-size: clamp(1.5rem, 2.8vw, 2.25rem); line-height: 1.25; letter-spacing: -.03em; font-weight: 500; text-wrap: pretty; }
.cq figcaption { display: grid; gap: .25rem; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--ed-line, #d8dce1); font-size: 1rem; }
.cq figcaption span { color: var(--ed-muted, #51565e); }

/* Other projects (1 Oct): the homepage's frame and cards. */
.co { width: min(100% - 3rem, 75rem); margin: clamp(5rem, 10vw, 8rem) auto 0; color: var(--ed-ink, #121417); }
.co__head { display: flex; align-items: end; justify-content: space-between; gap: 2rem; margin-bottom: 1.5rem; }
.co__head h2 { margin: 0; font-size: clamp(1.75rem, 3.2vw, 2.75rem); line-height: 1.08; letter-spacing: -.04em; font-weight: 500; }
.co__head h2 span { color: var(--ed-muted, #6b7280); }
.co__all { display: inline-flex; align-items: center; gap: .5rem; flex: none; padding-bottom: .5rem; font-size: 1rem; font-weight: 500; color: var(--ed-ink, #121417); text-decoration: none; }
.co__all svg, .co__go svg { width: 1rem; height: 1rem; transition: transform 300ms cubic-bezier(.2, .8, .2, 1); }
.co__all:hover { color: var(--brand, #0052f8); } .co__all:hover svg { transform: translateX(3px); }
.co__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem; padding: .75rem; border-radius: 2rem; background: var(--ed-frame, #eaecee); }
.co__card { display: grid; grid-template-rows: auto 1fr; border-radius: 1.25rem; overflow: hidden; background: var(--surface, #fff); color: inherit; text-decoration: none; }
.co__media { position: relative; display: block; aspect-ratio: 16 / 10; overflow: hidden; background: #eceef1; }
.co__media img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform 600ms cubic-bezier(.2, .8, .2, 1); }
.co__fig { position: absolute; left: 1rem; bottom: 1rem; padding: .375rem .75rem; border-radius: 999px; background: rgb(255 255 255 / .9); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); font-size: .875rem; color: var(--ed-muted, #51565e); }
.co__fig b { font-weight: 500; color: var(--ed-ink, #121417); }
.co__body { display: grid; align-content: start; gap: .625rem; padding: 1.25rem 1.5rem 1.5rem; }
.co__logo { display: block; height: 1.375rem; width: auto; max-width: 8rem; object-fit: contain; object-position: left; }
.co__logo--mono { filter: brightness(0); }
.co__name { font-size: 1.125rem; font-weight: 500; }
.co__line { font-size: .9375rem; line-height: 1.4; color: var(--ed-muted, #51565e); }
.co__go { display: inline-flex; align-items: center; gap: .375rem; margin-top: .375rem; font-size: .9375rem; font-weight: 500; color: var(--brand, #0052f8); }
.co__card:hover .co__media img { transform: scale(1.04); }
.co__card:hover .co__go svg { transform: translateX(3px); }
.co__card:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
@media (max-width: 899px) { .co__grid { grid-template-columns: 1fr; } .hx__plate--slide { aspect-ratio: 4 / 3; } }
@media (prefers-reduced-motion: reduce) {
  .hx__slide, .cg__item img { transform: none; }
  .cg__item { clip-path: none; }
  .co__media img, .co__name svg { transition: none; }
}

/* ================= Case header: our own composition (25 Sept) =================
   Hulusi: no whole slides (their titles came along), our own layout, and the
   client's logo on top. Round 3: CSS-drawn phones looked fake; the plate now
   holds Lena's own iPhone renders, exported one phone at a time with the
   background cut away, rising out of the plate's bottom edge. They rise in
   on load and part a little with the scroll (--hx). */
.hx__logo { display: block; height: 2rem; width: auto; max-width: 11rem; margin-top: clamp(2rem, 5vh, 3.5rem); object-fit: contain; object-position: left center; }
.hx__logo + .hx__title { margin-top: 1.25rem; }
.hx__logo--mono { filter: brightness(0); }

.hx__plate--devices { height: clamp(24rem, 66vh, 40rem); background: #eef0f3 radial-gradient(70% 90% at 50% 100%, #fff 0, rgb(255 255 255 / 0) 70%); }
.dv { position: absolute; inset: 0; }
.dv img { position: absolute; height: auto; max-width: none; filter: drop-shadow(0 30px 40px rgb(18 32 80 / .22)); animation: dv-rise 1300ms cubic-bezier(.2, .8, .2, 1) both; }
/* Straight pair (full phone + a phone cut at its foot): side by side, the
   second a step lower, both leaving through the bottom edge. */
.dv--straight .dv__a { left: 19%; bottom: -30%; width: 30%; z-index: 2; translate: 0 calc(var(--hx, 0) * -8%); }
.dv--straight .dv__b { left: 51%; bottom: 0; width: 30%; z-index: 1; translate: 0 calc(18% - var(--hx, 0) * 3%); animation-delay: 140ms; }
/* Tilted pair: Lena's angled renders, overlapping, the second in front. */
.dv--tilted .dv__a { left: 18%; bottom: -18%; width: 34%; z-index: 1; translate: 0 calc(var(--hx, 0) * -4%); }
.dv--tilted .dv__b { left: 44%; bottom: -26%; width: 35%; z-index: 2; translate: 0 calc(var(--hx, 0) * -9%); animation-delay: 140ms; }
.dv__panel { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transform: scale(calc(1.015 - var(--hx, 0) * .015)); }
@keyframes dv-rise { from { opacity: 0; transform: translateY(14%); } }

@media (max-width: 899px) {
  .hx__plate--devices { height: auto; aspect-ratio: 1; }
  .dv--straight .dv__a { left: 4%; width: 48%; bottom: -34%; }
  .dv--straight .dv__b { left: 50%; width: 48%; }
  .dv--tilted .dv__a { left: -2%; width: 60%; bottom: -20%; }
  .dv--tilted .dv__b { left: 38%; width: 62%; bottom: -28%; }
}
@media (prefers-reduced-motion: reduce) {
  .dv img { animation: none; translate: none; }
  .dv__panel { transform: none; }
}
/* Round 3: no official logo (Dear Saint-Tropez) shows the client's name in text, never a drawn logo. */
.hx__client { margin: clamp(2rem, 5vh, 3.5rem) 0 0; font-size: 1.125rem; font-weight: 500; letter-spacing: -.01em; }
.hx__client + .hx__title { margin-top: 1rem; }
.hx__plate--white { background: #fff; box-shadow: inset 0 0 0 1px var(--ed-line, #d8dce1); }
.dv__panel--contain { object-fit: contain; padding: 4% 0; }
/* Gallery of text-free panels: natural proportions, two per row. */
.cg { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); align-items: start; }
.cg__item { aspect-ratio: auto; }
.cg__item img { height: auto; }

/* ================= Facts as badges (25 Sept, round 4) =================
   Hulusi: no "Client" row (the logo already says it); the facts become the
   reusable badge pills (components/badge.css), grouped under small labels. */
.hx__facts--badges { grid-template-columns: repeat(3, auto); justify-content: start; gap: 1.25rem 2rem; }
.hx__facts--badges dd { margin-top: .5rem; }
.hx__credit { display: none; }
@media (max-width: 899px) { .hx__facts--badges { grid-template-columns: 1fr; gap: 1rem; } }

/* ================= Header option 1: the plate on a photograph (?header=photo) =================
   Hulusi: only the background changes. The header stays as approved (logo,
   title, lede and badges on white); the grey plate behind the phones becomes
   the project's photograph under a dark overlay. Credits: photos/README.md. */
.hx__bg, .hx__credit { display: none; }
html[data-header="photo"] .hx__plate--devices > .hx__bg { display: block; position: absolute; inset: 0; }
html[data-header="photo"] .hx__plate--devices > .hx__bg img { width: 100%; height: 100%; object-fit: cover; transform: scale(calc(1.05 - var(--hx, 0) * .05)); }
html[data-header="photo"] .hx__plate--devices > .hx__bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgb(6 10 22 / .35) 0, rgb(6 10 22 / .6) 100%); }
html[data-header="photo"] .hx__plate--devices .dv img { filter: drop-shadow(0 40px 50px rgb(0 0 0 / .45)); }
html[data-header="photo"] .hx__plate--devices > .hx__credit { display: block; position: absolute; top: .875rem; right: 1.125rem; z-index: 3; font-size: .8125rem; color: rgb(255 255 255 / .7); }
@media (prefers-reduced-motion: reduce) { html[data-header="photo"] .hx__plate--devices > .hx__bg img { transform: none; } }

/* ================= Scroll ribbon (25 Sept) =================
   Hulusi: "one more interesting scroll ribbon thing". Full bleed, two bands
   crossing at an angle: the project's own screens sliding left, a cobalt
   band of its words and figures sliding right (--rp, 0 to 1, from
   case-mac.js as the section crosses the view). */
.rb { position: relative; width: 100vw; margin: clamp(5rem, 10vw, 8rem) 0 0 calc(50% - 50vw); padding-block: 3rem 4rem; overflow: hidden; }
.rb__band { position: relative; }
.rb__track { display: flex; align-items: center; width: max-content; margin: 0; will-change: transform; }
.rb__band--shots { rotate: -3deg; }
.rb__band--shots .rb__track { gap: 1.25rem; transform: translateX(calc(-4% - var(--rp, 0) * 30%)); }
.rb__shot { display: block; height: clamp(14rem, 26vw, 22rem); width: auto; border-radius: 10px; box-shadow: 0 0 0 1px rgb(18 20 23 / .06), 0 24px 50px -28px rgb(18 32 80 / .45); background: #fff; }
.rb__shot--phone { border-radius: 26px; }
.rb__band--words { z-index: 2; margin-top: -2.5rem; rotate: 2deg; background: var(--brand, #0052f8); color: #fff; padding-block: 1.1rem; }
.rb__band--words .rb__track { gap: 1.75rem; transform: translateX(calc(-40% + var(--rp, 0) * 30%)); font-size: clamp(1.75rem, 3.6vw, 3rem); font-weight: 500; letter-spacing: -.035em; line-height: 1; white-space: nowrap; }
.rb__band--words i { width: .45em; height: .45em; border-radius: 50%; background: rgb(255 255 255 / .55); flex: none; }
@media (prefers-reduced-motion: reduce) {
  .rb__band--shots .rb__track { transform: translateX(-4%); }
  .rb__band--words .rb__track { transform: translateX(-20%); }
}
.case-detail { overflow-x: clip; }

/* ================= The figure inside the plate (25 Sept) =================
   Hulusi: the plate was half empty and the KPI came late (under the plate,
   below the fold). The figures now sit large in the plate's left half, the
   phones move right and higher to fill the rest. */
.hx__plate--kpi { height: clamp(24rem, 60vh, 38rem); }
.dv__kpi { position: absolute; left: clamp(1.5rem, 5%, 3.5rem); top: 50%; z-index: 2; translate: 0 -50%; display: grid; gap: 1.75rem; margin: 0; padding: 0; list-style: none; max-width: 38%; }
.dv__kpi li { display: grid; gap: .5rem; animation: hx-fade 900ms cubic-bezier(.2, .8, .2, 1) 350ms both; }
.dv__kpi b { font-size: clamp(4rem, 9vw, 8.5rem); line-height: .9; letter-spacing: -.06em; font-weight: 500; color: var(--brand, #0052f8); font-variant-numeric: tabular-nums; }
.dv__kpi span { font-size: clamp(1.0625rem, 1.5vw, 1.375rem); line-height: 1.3; color: var(--ed-ink, #121417); }
.dv__kpi li + li b { font-size: clamp(2.5rem, 5vw, 4.5rem); color: var(--ed-ink, #121417); }
.hx__plate--kpi .dv--straight .dv__a { left: 44%; width: 26%; top: 12%; bottom: auto; }
.hx__plate--kpi .dv--straight .dv__b { left: 71%; width: 26%; top: 24%; bottom: auto; }
.hx__plate--kpi .dv--tilted .dv__a { left: 38%; width: 34%; top: 10%; bottom: auto; }
.hx__plate--kpi .dv--tilted .dv__b { left: 60%; width: 36%; top: 16%; bottom: auto; }
/* Photo option: the figures in white on the photograph. */
html[data-header="photo"] .dv__kpi b, html[data-header="photo"] .dv__kpi li + li b, html[data-header="photo"] .dv__kpi span { color: #fff; }
@media (max-width: 899px) {
  .hx__plate--kpi { height: auto; aspect-ratio: 4 / 5; }
  .dv__kpi { top: 1.5rem; translate: none; max-width: none; right: 1.5rem; }
  .dv__kpi b { font-size: 4rem; }
  .hx__plate--kpi .dv--straight .dv__a { left: 4%; width: 46%; top: 36%; }
  .hx__plate--kpi .dv--straight .dv__b { left: 50%; width: 46%; top: 44%; }
  .hx__plate--kpi .dv--tilted .dv__a { left: -2%; width: 58%; top: 34%; }
  .hx__plate--kpi .dv--tilted .dv__b { left: 38%; width: 60%; top: 40%; }
}
@media (prefers-reduced-motion: reduce) { .dv__kpi li { animation: none; } }
/* The figure in the first view on a 14" laptop (1350 x 800): tighter
   spacing above the plate, the figure set in its upper half. */
@media (min-width: 900px) {
  .hx--slide .hx__logo { margin-top: 1.5rem; }
  .hx--slide .hx__logo + .hx__title { margin-top: 1rem; }
  .hx--slide .hx__meta { margin-top: 1.75rem; padding-top: 1rem; grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); }
  .hx--slide .hx__lede { max-width: 34rem; font-size: 1rem; }
  .hx--slide .hx__plate { margin-top: 2rem; }
  .dv__kpi { top: 36%; }
}
@media (min-width: 900px) {
  .hx--slide .hx__facts--badges { display: flex; flex-wrap: wrap; gap: .875rem 1.75rem; }
  .hx--slide .hx__facts--badges .badges { flex-wrap: nowrap; }
  .hx--slide .hx__facts--badges dd { margin-top: .375rem; }
}
/* Order (25 Sept): title, plate (figure + phones), then lede and badges, so
   the figure and the product are in the first view. */
@media (min-width: 900px) {
  .hx--slide .hx__logo + .hx__title + .hx__plate { margin-top: 1.75rem; }
  .hx--slide .hx__plate + .hx__meta { margin-top: 2rem; }
  .dv__kpi { top: 50%; }
}
.hx--slide .hx__plate + .hx__meta { border-top: 0; padding-top: 0; }
.dv__kpi b { white-space: nowrap; }
.dv__kpi li.is-long b { font-size: clamp(3rem, 5.6vw, 5.5rem); }
@media (min-width: 900px) { .dv__kpi { top: 38%; } }

/* Plate grounds to choose from (?plate=cobalt|sky|gradient), same as the
   homepage covers; grey stays the default. */
html[data-plate="cobalt"] .hx__plate--devices { background: #e9f0ff url("../../img/backgrounds/dream/figma/hero/ai-bg-097.webp") center / cover; }
html[data-plate="sky"] .hx__plate--devices { background: #cfe2ff url("../../img/hero/cloud-plate-v9.webp") center / cover; }
html[data-plate="gradient"] .hx__plate--devices { background: radial-gradient(90% 80% at 88% 105%, rgb(0 82 248 / .55) 0, rgb(0 82 248 / 0) 62%), radial-gradient(70% 60% at 10% 0%, #fff 0, rgb(255 255 255 / 0) 70%), linear-gradient(180deg, #f1f4f9 0, #dfe6f2 100%); }
/* Ribbon: web screens inside the laptop render (Hulusi: screens go in the
   mockup for web), same screen area as the homepage covers. */
.rb__mac { position: relative; flex: none; height: clamp(14rem, 26vw, 22rem); aspect-ratio: 1306 / 1123; }
.rb__mac-device { position: absolute; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 20px 26px rgb(18 32 80 / .2)); }
.rb__mac-screen { position: absolute; left: 9.01%; top: 2.97%; width: 81.5%; height: 61.3%; overflow: hidden; border-radius: .4% / .6%; background: #fff; }
.rb__mac-screen img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: left top; }

/* 13 Oct 2026 (Hulusi: "combine the dream imagery with the raster, not the
   dark photo"): the case hero's ground is the project's dream plate, the
   product stays, the photograph dissolves into it. The shade keeps the white figure readable on the left. */
.hx__plate.hx__plate--glyph[data-dream] { background: var(--ground, #121417) var(--dream) center / cover no-repeat; }
/* Hulusi, later that day: "combine the real imagery with the dreamy photo", so the photograph stays, dissolving into the plate through its own mask; the character field is off (case-glyph.js). */
.hx__plate--glyph[data-dream] .glyph__shade { background: linear-gradient(90deg, rgb(6 14 40 / .55), rgb(6 14 40 / 0) 52%), linear-gradient(to top, rgb(6 14 40 / .3), rgb(6 14 40 / 0) 40%); }
.hx__plate--glyph[data-dream="033"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-033.webp"); }
.hx__plate--glyph[data-dream="043"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-043.webp"); }
.hx__plate--glyph[data-dream="081"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-081.webp"); }
.hx__plate--glyph[data-dream="088"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-088.webp"); }
.hx__plate--glyph[data-dream="096"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-096.webp"); }
.hx__plate--glyph[data-dream="097"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-097.webp"); }
.hx__plate--glyph[data-dream="053"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-053.webp"); }
.hx__plate--glyph[data-dream="061"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-061.webp"); }
.hx__plate--glyph[data-dream="078"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-078.webp"); }
.hx__plate--glyph[data-dream="086"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-086.webp"); }
.hx__plate--glyph[data-dream="094"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-094.webp"); }
.hx__plate--glyph[data-dream="095"] { --dream: url("../../img/backgrounds/dream/figma/hero/ai-bg-095.webp"); }
