/* Case study scenes (30 Sept 2026): the scroll-driven moments of the three
   templates (mobile, web, both), see assets/img/cases/README.md. Every scene
   is a pinned stage (.cs-track / .cs-stick from case-mac.css) whose --p runs
   0 to 1 over its travel (case-mac.js). Only the project's real screens are
   shown; devices are Lena's renders or the case film's laptop. Reduced
   motion: each scene rests in its final state. */

.cs-head { text-align: center; max-width: 44rem; }
.cs-head h2 { margin: 0; font-size: clamp(1.75rem, 3.2vw, 2.75rem); line-height: 1.08; letter-spacing: -.04em; font-weight: 500; text-wrap: balance; }
.cs-head h2 span { color: var(--ed-muted, #6b7280); }
.cs-head p { margin: .875rem auto 0; max-width: 34rem; font-size: 1.0625rem; line-height: 1.5; color: var(--ed-muted, #51565e); }
.cs-caption { margin: 1.75rem 0 0; font-size: clamp(1.0625rem, 1.5vw, 1.375rem); line-height: 1.35; color: var(--ed-muted, #6b7280); text-align: center; }
.cs-caption b { color: var(--ed-ink, #121417); font-weight: 500; }

/* ================= The exploded phone (mobile, both) =================
   What we built underneath: the layers pull apart in 3D as the scroll
   tilts the phone back, each named on the right. The interface layer is
   the real screen; the others are drawn (no invented data on them). */
.ex .cs-stick { grid-template-columns: minmax(0, 1fr); }
.ex__wrap { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: clamp(2rem, 6vw, 6rem); width: min(64rem, 92vw); margin-top: 1.5rem; }
.ex__scene { position: relative; height: min(56vh, 34rem); aspect-ratio: 9 / 19.5; margin: 0 auto; perspective: 1500px; }
.ex__group { position: absolute; inset: 0; transform-style: preserve-3d; transform: rotateX(calc(var(--p, 0) * 56deg)) rotateZ(calc(var(--p, 0) * -24deg)) translateY(calc(var(--p, 0) * 4%)); }
.ex__layer { position: absolute; inset: 0; border-radius: 12% / 5.5%; overflow: hidden; transform: translateZ(calc(var(--z) * var(--p, 0) * 1px)); box-shadow: 0 0 0 1px rgb(18 20 23 / .08), 0 30px 50px -30px rgb(18 32 80 / .45); }
.ex__layer--data { --z: -300; background: #121417 radial-gradient(rgb(255 255 255 / .28) 1px, transparent 1.5px) 0 0 / 14px 14px; }
.ex__layer--services { --z: -200; background: rgb(0 82 248 / .06); border: 1px solid rgb(0 82 248 / .35); }
.ex__layer--services i { position: absolute; border: 1.5px solid #0052f8; border-radius: 6px; background: rgb(0 82 248 / .08); }
.ex__layer--components { --z: -100; background: #f4f6f9; }
.ex__layer--components i { position: absolute; border-radius: 8px; background: #d5dbe5; }
.ex__layer--ui { --z: 0; background: #fff; }
.ex__layer--ui img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.ex__layer--glass { --z: 110; background: linear-gradient(115deg, rgb(255 255 255 / .5) 0, rgb(255 255 255 / .05) 45%, rgb(255 255 255 / .3) 100%); border: 1px solid rgb(255 255 255 / .9); box-shadow: 0 0 0 1px rgb(18 20 23 / .06); opacity: calc(var(--p, 0) * .9); }
.ex__labels { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.25rem; }
.ex__labels li { display: grid; gap: .2rem; padding-left: 1.25rem; border-left: 2px solid var(--ed-line, #d8dce1); opacity: calc(var(--p, 0) * 1.4 - var(--i) * .22); transition: border-color 300ms; }
.ex__labels b { font-size: 1.125rem; font-weight: 500; }
.ex__labels span { font-size: .9375rem; color: var(--ed-muted, #51565e); }
@media (max-width: 899px) { .ex__wrap { grid-template-columns: 1fr; } .ex__labels { grid-template-columns: 1fr 1fr; } }

/* ================= Device cascade (web, both) =================
   The same product on each screen: the laptop slides in from the left,
   the phone from the right, a tablet between them when the project has one. */
.cc .cs-stick { padding-top: 5rem; }
.cc__stage { position: relative; width: min(58rem, 90vw); height: min(50vh, 30rem); margin-top: 2.5rem; }
.cc__laptop { position: absolute; left: 8%; bottom: 0; width: 54%; aspect-ratio: 1306 / 1123;
  --t: clamp(0, calc(var(--p, 0) / .5), 1); transform: translateX(calc((1 - var(--t)) * -30%)); opacity: var(--t); }
.cc__laptop img.cc__device { position: absolute; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 26px 34px rgb(18 32 80 / .22)); }
.cc__laptop .cc__screen { position: absolute; left: 9.01%; top: 2.97%; width: 81.5%; height: 61.3%; overflow: hidden; border-radius: .4% / .6%; background: #fff; }
.cc__screen img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.cc__tablet { position: absolute; left: 52%; bottom: 4%; width: 26%; --t: clamp(0, calc((var(--p, 0) - .25) / .5), 1); transform: translateX(calc((1 - var(--t)) * 30%)); opacity: var(--t); }
.cc__tablet img { display: block; width: 100%; height: auto; border-radius: 14px; box-shadow: 0 0 0 1px rgb(18 20 23 / .08), 0 26px 40px -24px rgb(18 32 80 / .45); }
.cc__phone { position: absolute; right: 14%; bottom: -3%; height: 70%; width: auto; z-index: 2; --t: clamp(0, calc((var(--p, 0) - .4) / .5), 1); transform: translateX(calc((1 - var(--t)) * 40%)); opacity: var(--t); filter: drop-shadow(0 26px 34px rgb(18 32 80 / .25)); }

/* ================= The morph (both) =================
   The desktop window reshapes into the phone: same product, every size. */
.mo .cs-stick { padding-top: 5rem; }
/* Type on the left, the device on the right, centred on one axis (Hulusi: the type floated above the phone). */
.mo__wrap { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); align-items: center; gap: clamp(2rem, 5vw, 5rem); width: min(64rem, 92vw); --m: var(--p, 0); }
.mo__copy .cs-head { text-align: left; max-width: 22rem; }
.mo__copy .cs-head h2 { font-size: clamp(1.75rem, 3vw, 2.5rem); }
.mo__stage { position: relative; display: grid; place-items: center; height: min(62vh, 38rem); }
.mo__box { position: relative; overflow: hidden; background: #fff;
  /* The phone state is an iPhone 15 Pro: 9:19.5, corners at 14% of its width; the height leads, the width follows. */
  --ph-h: min(32rem, 58vh); --ph-w: calc(var(--ph-h) * 0.4614);
  width: calc(min(36rem, 54vw) * (1 - var(--m)) + var(--ph-w) * var(--m));
  height: calc(min(24rem, 42vh) * (1 - var(--m)) + var(--ph-h) * var(--m));
  border-radius: calc(14px * (1 - var(--m)) + var(--ph-w) * .14 * var(--m));
  box-shadow: 0 0 0 1px rgb(18 20 23 / .07), 0 40px 70px -36px rgb(18 32 80 / .5); }
.mo__box img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.mo__web { opacity: clamp(0, calc(1.3 - var(--m) * 2), 1); }
.mo__app { opacity: clamp(0, calc(var(--m) * 2 - .7), 1); }
/* The toggle: which state the morph is in, its thumb sliding with the scroll. */
.mo__tab { position: relative; display: inline-grid; grid-template-columns: 1fr 1fr; margin: 1.75rem 0 0; padding: .25rem; border-radius: 999px; background: #eef0f3; font-size: .9375rem; font-weight: 500; }
.mo__tab i { position: absolute; top: .25rem; bottom: .25rem; left: .25rem; width: calc(50% - .25rem); border-radius: 999px; background: #fff; box-shadow: 0 1px 2px rgb(18 20 23 / .08), 0 0 0 1px rgb(18 20 23 / .04); transform: translateX(calc(var(--m) * 100%)); }
.mo__tab span { position: relative; padding: .5rem 1.25rem; text-align: center; white-space: nowrap; color: var(--ed-muted, #51565e); }
.mo__tab span:first-child { color: color-mix(in srgb, var(--ed-ink, #121417) calc((1 - var(--m)) * 100%), var(--ed-muted, #51565e)); }
.mo__tab span:last-child { color: color-mix(in srgb, var(--ed-ink, #121417) calc(var(--m) * 100%), var(--ed-muted, #51565e)); }

/* ================= Scroll inside the phone (mobile, both), on the hand raise ================= */
.ph[data-long] .ph__screen img { object-position: 0 calc(var(--sy, 0) * 100%); }

@media (prefers-reduced-motion: reduce) {
    .ex__group, .ex__layer, .ex__labels li, .ex__layer--glass { --p: 1; }
  .cc__laptop, .cc__tablet, .cc__phone { --t: 1; }
  .mo__wrap { --m: 1; }
}
@media (max-width: 899px) {
  .cc__laptop { width: 100%; } .cc__phone { height: 60%; right: 0; } .cc__tablet { display: none; }
}
/* Longer travels for the extended scenes. */
.ph[data-long] .ph__track { height: 400vh; }

/* The scenes bleed to the window's edges (Hulusi, 30 Sept: the orbiting
   screens were cut at the page container's edge): each pinned stage spans
   the viewport, so its overflow is clipped at the window, not at the column. */
.ex, .cc, .mo { width: 100vw; margin-left: calc(50% - 50vw); }
.ex .cs-stick, .cc .cs-stick, .mo .cs-stick { padding-inline: clamp(1rem, 4vw, 4rem); }
@media (max-width: 899px) { .mo__wrap { grid-template-columns: 1fr; } .mo__copy .cs-head { text-align: center; max-width: none; margin-inline: auto; } .mo__copy { text-align: center; } .mo__stage { height: min(56vh, 30rem); } }
