/* ══════════════════════════════════════════════════════════════════
   VISION SINDH — CATEGORY FLAGSHIPS  (/tops.html · /bottoms.html)
   Commerce pages. Zero WebGL, zero canvas: the craft is typography,
   scroll choreography and very large imagery.
   Mobile-first — designed at 390×844 as a portrait film strip; the
   desktop grid is the adaptation, not the origin.
   Rules kept from the system:
     · ember (#d9611f) is LIGHT only — underlines, glows, tips.
     · nothing here is load-bearing: no .cat-js = everything visible.
   ══════════════════════════════════════════════════════════════════ */

.cat-page {
  --bleed: calc(var(--gutter) * -1);
  --ember-l: var(--ember, #d9611f);
}

/* ═══ 1 · TITLE MOMENT ═════════════════════════════════════════════
   Two states from one DOM:
   STATIC (no JS, no IntersectionObserver, or reduced motion) — the page
   opens exactly as a quiet editorial cover: kicker, title, one plate.
   PINNED (.cat-pin, added by category.js) — the stage sticks, the first
   three plates rise THROUGH the title: a paper veil covers the band and
   the two words are holes punched in it, so passing garments are seen
   inside the letterforms, frosted by the band's backdrop-filter.       */
.cat-hero { padding-block: clamp(30px, 6vh, 74px) 0; }
.cat-hero__stage { position: relative; }
/* static state: the band is just the title, inside the page gutter */
.cat-hero__band { padding-inline: var(--gutter); max-width: 1480px; margin-inline: auto; }
.cat-open { padding-block: clamp(22px, 4vh, 44px) 0; }

.cat-kicker {
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  color: var(--ash); margin-bottom: clamp(18px, 3vh, 30px);
}
.cat-kicker span + span::before { content: '·'; margin-right: 14px; color: var(--line); }

.cat-title {
  font-size: clamp(56px, 20vw, 210px);
  line-height: 0.86;
  letter-spacing: 0.002em;
  margin-bottom: clamp(20px, 3vh, 34px);
}
.cat-title .w { display: block; overflow: hidden; padding-block: 0.02em 0.04em; }
.cat-title .w > span { display: block; }
.cat-title .w--out > span {
  -webkit-text-stroke: clamp(1px, 0.32vw, 2.4px) var(--ink);
  color: transparent;
  padding-left: 0.06em;
}
/* the ember rule that closes the title — light, never fill */
.cat-title::after {
  content: ''; display: block; height: 1px; margin-top: clamp(14px, 2.4vh, 26px);
  background: linear-gradient(to right, var(--ember-l) 0 22%, var(--line) 22% 100%);
  box-shadow: 0 0 7px -1px color-mix(in srgb, var(--ember-l) 60%, transparent);
  transform-origin: left center;
}

.cat-lede {
  max-width: 44ch; color: var(--ink-soft);
  font-size: clamp(15px, 1.25vw, 19px);
  margin-top: clamp(16px, 2.6vh, 26px);
}

.cat-epi { margin-top: clamp(26px, 4vh, 44px); max-width: 34ch; }
.cat-epi p {
  font-family: var(--font-display); font-size: clamp(20px, 5.4vw, 30px);
  line-height: 1.2; text-wrap: balance;
}
.cat-epi cite { display: block; margin-top: 10px; color: var(--ash); font-style: normal; }

.cat-jump {
  display: flex; flex-wrap: wrap; gap: 0 clamp(14px, 2vw, 26px);
  margin-top: clamp(26px, 4vh, 40px);
  border-top: 1px solid var(--line);
}
.cat-jump a {
  color: var(--ash); min-height: 46px; display: inline-flex; align-items: center; gap: 3px;
  border-bottom: 1px solid transparent; margin-bottom: -1px;
  transition: color 0.25s, border-color 0.25s;
}
.cat-jump sup { font-size: 0.75em; color: var(--line); }
.cat-jump a:hover { color: var(--ink); }
.cat-jump a[aria-current="true"] {
  color: var(--ink);
  border-bottom-color: var(--ember-l);
  box-shadow: 0 1px 7px -2px color-mix(in srgb, var(--ember-l) 75%, transparent);
}
.cat-jump a[aria-current="true"] sup { color: var(--ash); }

/* the opening plate — edge to edge, taller than anything on /shop.
   In the static state only the first one shows; pinned, all three ride. */
.cat-hero__track { margin-top: clamp(30px, 5vh, 56px); }
.cat-hero__plate { position: relative; background: var(--white); overflow: clip; }
.cat-hero__plate + .cat-hero__plate { display: none; }
.cat-hero__plate img {
  width: 100%; aspect-ratio: 3 / 4; object-fit: cover; object-position: center 22%;
  border-block: 1px solid var(--line);
}
.cat-hero__glass--back, .cat-hero__cue, .cat-title__pane, .cat-hero__tick { display: none; }

@media (min-width: 900px) {
  .cat-open .wrap { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 0 clamp(30px, 4vw, 70px); align-items: end; }
  .cat-jump { grid-column: 1 / -1; }
  .cat-title { font-size: clamp(120px, 16.4vw, 250px); line-height: 0.83; margin-bottom: clamp(24px, 4vh, 40px); }
  .cat-title .w--out > span { padding-left: 0.1em; }
  .cat-lede { margin-top: 0; padding-bottom: 4px; }
  .cat-epi { margin-top: 0; max-width: 32ch; }
  .cat-epi p { font-size: clamp(19px, 1.6vw, 25px); }
  .cat-hero__plate img { aspect-ratio: 16 / 9; object-position: center 24%; }
}

/* ═══ 1b · PINNED STATE — a dimensional title that loads with product ══
   Stage grammar: spacer (svh) + sticky stage + DOM-rect-keyed progress.
   Short road: ~2 viewports of scroll, so the whole moment reads in two
   or three thumb flicks. Three things happen on that road —
     · the glass title tilts in perspective, its cut letters showing a
       real aperture wall (three veils stacked on Z inside the band);
     · three garments LOAD IN left → right, one after another, each a
       clip wipe keyed to its own slice of the scroll (scroll back and
       they un-load right → left — it is a pure function of progress);
     · an ember hairline under the glass tracks that loading.
   Nothing here exists without .cat-pin, which category.js adds only
   when JS runs AND the reader has not asked for reduced motion.        */
.cat-pin .cat-hero { height: 200svh; padding: 0; }
.cat-pin .cat-hero__stage {
  position: sticky; top: 0; height: 100svh;
  overflow: clip; isolation: isolate; z-index: 0;
}
/* the plates fade in and out at the stage edges instead of hard-cutting */
.cat-pin .cat-hero__stage::before,
.cat-pin .cat-hero__stage::after {
  content: ''; position: absolute; left: 0; right: 0; z-index: 3; pointer-events: none;
}
.cat-pin .cat-hero__stage::before { top: 0; height: 17svh; background: linear-gradient(to bottom, var(--paper) 22%, transparent); }
.cat-pin .cat-hero__stage::after { bottom: 0; height: 15svh; background: linear-gradient(to top, var(--paper) 18%, transparent); }

.cat-pin .cat-hero__top {
  position: absolute; top: clamp(12px, 2.6svh, 30px); left: 0; right: 0; z-index: 5;
}
.cat-pin .cat-kicker { margin-bottom: 0; }

/* Two flat wrappers, one full-stage box each, same perspective and the
   same origin — so the tilted glass and the ink plane behind the plates
   project identically and stay registered. The wrappers carry the intro
   and the release wipe; the 3D lives strictly inside them, where no
   grouping property can flatten it. */
.cat-pin .cat-hero__glass {
  position: absolute; inset: 0; z-index: 4;
  perspective: 1150px; perspective-origin: 50% 47%;
  pointer-events: none;
  clip-path: inset(0 -100vw calc(var(--wipe, 0) * 100%) -100vw);
  opacity: 0; transform: translateY(2.5%);
  transition: opacity 0.85s var(--ease), transform 1.1s var(--ease);
}
.cat-pin .cat-hero__glass--back { display: block; z-index: 1; }
.cat-pin .cat-hero__stage.is-in .cat-hero__glass { opacity: 1; transform: none; }

.cat-pin .cat-hero__band,
.cat-pin .cat-hero__plane {
  position: absolute; inset: 0; margin: auto; height: auto;
  width: min(100%, 104svh); max-width: none; aspect-ratio: 1000 / 520;
  padding-inline: 0;
  transform: rotateX(var(--tilt, 6deg)) translateZ(var(--depth, 0px));
}
.cat-pin .cat-hero__band { transform-style: preserve-3d; }
.cat-pin .cat-hero__plane { background: var(--ink); }

.cat-pin .cat-title {
  display: block; width: 100%; height: 100%; margin: 0; font-size: 0;
  transform-style: preserve-3d;
}
.cat-pin .cat-title::after { display: none; }
.cat-pin .cat-title__set {            /* kept for AT and for copy/paste */
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
/* the aperture: three identical veils on the Z axis. Head on the holes
   line up and you look straight through; tilted, the back veils become
   the inner wall of each letter — the glass has thickness. */
.cat-pin .cat-title__pane { display: block; position: absolute; inset: 0; }
.cat-pin .cat-title__pane--1 { transform: translateZ(0); }
.cat-pin .cat-title__pane--2 { transform: translateZ(-9px); }
.cat-pin .cat-title__pane--3 { transform: translateZ(-18px); }
.cat-pin .cat-title__pane--tint {
  left: -100vw; right: -100vw; transform: translateZ(-26px);
  /* the ink in the glass: hidden by the veil everywhere but the letters,
     so a white studio ground still reads as dark type and the letters
     fall back to solid ink before anything has loaded */
  background: color-mix(in srgb, var(--ink) 58%, transparent);
}
/* the glass casts on the picture below it — the cheapest honest depth cue */
.cat-pin .cat-hero__band::after,
.cat-pin .cat-hero__band::before {
  content: ''; position: absolute; left: -100vw; right: -100vw;
  height: clamp(16px, 3svh, 44px); transform: translateZ(-30px); pointer-events: none;
}
.cat-pin .cat-hero__band::after {
  top: 100%;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--ink) 26%, transparent), transparent);
}
.cat-pin .cat-hero__band::before {
  bottom: 100%; height: clamp(8px, 1.6svh, 22px);
  background: linear-gradient(to top, color-mix(in srgb, var(--ink) 12%, transparent), transparent);
}
.cat-pin .cat-title__pane--2 .cat-knock__veil { fill: color-mix(in srgb, var(--paper) 88%, var(--ink)); }
.cat-pin .cat-title__pane--3 .cat-knock__veil { fill: color-mix(in srgb, var(--paper) 74%, var(--ink)); }

.cat-pin .cat-knock { display: block; width: 100%; height: 100%; overflow: visible; }
.cat-knock__w { font-family: var(--font-display); font-size: 252px; fill: #000; }
.cat-knock__veil { fill: var(--paper); fill-opacity: 0.97; }
.cat-knock__sheen { pointer-events: none; }
.cat-knock__rule { fill: var(--line); }

/* the ember tick: the loading bar of the whole moment, glued to the
   glass's lower edge so it tilts with it. Light only, as ever. */
.cat-pin .cat-hero__tick {
  display: block; position: absolute; bottom: -1px; left: -100vw; right: -100vw;
  height: 1px; background: var(--line); transform: translateZ(1px);
}
.cat-pin .cat-hero__tick i {
  display: block; height: 100%; margin-left: 100vw;
  /* grows as a transform, never as a width: no layout per scroll frame */
  width: min(100vw, 104svh);
  transform: scaleX(var(--load, 0)); transform-origin: 0 50%;
  background: var(--ember-l);
  box-shadow: 0 0 7px 0 color-mix(in srgb, var(--ember-l) 85%, transparent);
}

/* THE LOADING CANVAS — three garments stacked in one frame; each wipes
   in from the left over its own slice of the scroll, so the picture
   fills the way a progress bar does. */
.cat-pin .cat-hero__track {
  position: absolute; inset: 0; margin: auto; z-index: 2;
  width: min(100%, 132svh); height: min(78svh, 128vw);
  display: grid; grid-template-areas: 'plate';
}
.cat-pin .cat-hero__plate,
.cat-pin .cat-hero__plate + .cat-hero__plate {
  display: block; grid-area: plate; width: 100%; height: 100%;
  border: 0; background: none;
  clip-path: inset(0 calc((1 - var(--r, 0)) * 100%) 0 0);
}
.cat-pin .cat-hero__plate img {
  width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover;
  object-position: center 22%; border: 0;
  transform: scale(calc(1.04 - 0.04 * var(--r, 0)));
}

.cat-pin .cat-hero__cue {
  display: block; position: absolute; z-index: 5;
  left: 0; right: 0; bottom: clamp(14px, 3svh, 34px);
  text-align: center; color: var(--ash);
  opacity: calc(1 - var(--p, 0) * 4);
}

/* Landscape: the same photographs, cut wide, so the cloth crosses every
   letter of a masthead that is now ~900px across. Same road, same timing. */
@media (min-width: 900px) {
  .cat-pin .cat-hero { height: 190svh; }
  .cat-pin .cat-hero__track { height: min(74svh, 56vw); }
  .cat-pin .cat-hero__plate img { object-position: center 42%; }
}

/* ═══ 2 · STRATA — one chapter = one layer of the dig ══════════════ */
.stratum { position: relative; padding-top: clamp(54px, 10vh, 130px); overflow: clip; scroll-margin-top: 72px; }
.stratum__head { position: relative; }
.stratum__head::before {
  content: ''; position: absolute; top: 0; left: var(--gutter); right: var(--gutter);
  height: 1px; background: var(--line);
}
.stratum__glyph {
  position: absolute; right: -0.05em; top: -0.16em; z-index: 0;
  font-size: clamp(150px, 46vw, 400px); line-height: 0.8;
  color: color-mix(in srgb, var(--ink) 7%, transparent);
  pointer-events: none; user-select: none; white-space: nowrap;
}
.stratum__line {
  position: relative; z-index: 1;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px;
  color: var(--ash); padding-top: 16px;
}
.stratum__roman {
  font-size: clamp(22px, 3.6vw, 34px); color: var(--ink);
  line-height: 1; letter-spacing: 0.02em; margin-right: 2px;
}
.stratum__count { color: color-mix(in srgb, var(--ink) 34%, transparent); }
.stratum__name {
  position: relative; z-index: 1;
  font-size: clamp(46px, 13.5vw, 104px); line-height: 0.95;
  margin-top: clamp(6px, 1vh, 12px);
}
.stratum__desc {
  position: relative; z-index: 1;
  max-width: 38ch; color: var(--ink-soft); font-size: clamp(14px, 1.05vw, 16px);
  margin-top: clamp(12px, 2vh, 18px);
}

/* ═══ 3 · THE STRIP — portrait film strip (mobile) ═════════════════ */
.strip {
  list-style: none;
  display: grid; gap: clamp(46px, 8vh, 96px) 0;
  margin-top: clamp(30px, 5vh, 60px);
  position: relative; z-index: 1;
}
.cut { min-width: 0; }
.cut__link { display: block; }

.cut__fig {
  position: relative; overflow: hidden;
  aspect-ratio: 3 / 4; background: var(--white);
  border: 1px solid var(--line);
}
.cut__img, .cut__alt { width: 100%; height: 100%; object-fit: cover; }
.cut__alt { position: absolute; inset: 0; opacity: 0; z-index: 3; }

/* THE ROTATION — the plates a piece turns through unattended. Injected by
   JS on the first turn, so no-JS and reduced-motion never see them. Only
   clip-path / transform / opacity animate; the grid stays composited. The
   worn shot (.cut__alt, z-index 3) still outranks them on hover/press. */
.cut__plate {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; clip-path: inset(0 0 0 0);
}
.cut__plate.is-up { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .cut__plate { display: none; } }
.cut__n {
  position: absolute; top: 12px; left: 12px; z-index: 2;
  color: var(--ash); font-size: 10.5px;
  padding-left: 16px;
}
.cut__n::before {
  content: ''; position: absolute; left: 0; top: 0.62em; width: 10px; height: 1px;
  background: var(--ember-l);
  box-shadow: 0 0 5px 0 color-mix(in srgb, var(--ember-l) 70%, transparent);
}
.cut__tag {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  background: var(--ink); color: var(--paper); font-size: 9.5px; padding: 5px 9px;
}

.cut__meta { position: relative; display: grid; gap: 5px; padding-top: 15px; }
.cut__meta::before {
  content: ''; position: absolute; inset: 0 0 auto; height: 1px;
  background: var(--line); transform-origin: left center;
}
.cut__meta::after {
  content: ''; position: absolute; left: 0; top: 0; width: 30px; height: 1px;
  background: var(--ember-l);
  box-shadow: 0 0 7px 0 color-mix(in srgb, var(--ember-l) 65%, transparent);
  transform-origin: left center;
}
.cut__name { font-size: clamp(21px, 6vw, 30px); line-height: 1.1; }
.cut__price { color: var(--ink-soft); }
.cut__hook { color: var(--ash); font-size: 13.5px; line-height: 1.5; max-width: 42ch; }
.cut__go { color: var(--ash); margin-top: 4px; transition: color 0.25s; }
.cut__go i { font-style: normal; display: inline-block; transition: transform 0.35s var(--ease); }

/* mobile rhythm: bleed, left inset, right inset — a strip that breathes */
.cut:nth-child(3n + 1) .cut__fig { margin-inline: var(--bleed); border-inline: 0; }
.cut:nth-child(3n + 2) { padding-right: 16%; }
.cut:nth-child(3n + 3) { padding-left: 16%; }
.cut:nth-child(3n + 3) .cut__meta { text-align: right; }
.cut:nth-child(3n + 3) .cut__meta::after { left: auto; right: 0; }
.cut:nth-child(3n + 3) .cut__hook { margin-left: auto; }
.cut:nth-child(3n + 3) .cut__n { left: auto; right: 12px; padding-left: 0; padding-right: 16px; }
.cut:nth-child(3n + 3) .cut__n::before { left: auto; right: 0; }
.cut:nth-child(3n + 3) .cut__tag { right: auto; left: 10px; }

/* ═══ 3b · desktop — the strip opens into an editorial grid ════════ */
@media (min-width: 900px) {
  .strip {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: clamp(50px, 7vh, 110px) clamp(18px, 2vw, 34px);
    align-items: start;
  }
  .strip .cut { padding: 0; grid-column: span 5; }
  .strip .cut .cut__fig { margin-inline: 0; border-inline: 1px solid var(--line); }
  .strip .cut .cut__meta { text-align: left; }
  .strip .cut .cut__meta::after { left: 0; right: auto; }
  .strip .cut .cut__hook { margin-left: 0; }
  .strip .cut .cut__n { left: 14px; right: auto; padding-left: 18px; padding-right: 0; }
  .strip .cut .cut__n::before { left: 0; right: auto; }
  .strip .cut .cut__tag { right: 12px; left: auto; }

  .cut:nth-child(4n + 1) { grid-column: 1 / span 7; }
  .cut:nth-child(4n + 2) { grid-column: 9 / span 4; margin-top: clamp(70px, 12vh, 170px); }
  .cut:nth-child(4n + 3) { grid-column: 2 / span 4; }
  .cut:nth-child(4n + 4) { grid-column: 7 / span 6; margin-top: clamp(50px, 8vh, 120px); }
  .cut:nth-child(4n + 1) .cut__name, .cut:nth-child(4n + 4) .cut__name { font-size: clamp(26px, 2.4vw, 38px); }
}

/* ═══ 4 · END PLATE ════════════════════════════════════════════════ */
.cat-end { padding-block: clamp(60px, 11vh, 140px) clamp(20px, 4vh, 40px); text-align: center; }
.cat-end__line { color: var(--ash); }
.cat-end__cta { margin-block: 22px 18px; }
.cat-end__note { color: var(--ash); font-size: 13px; max-width: 52ch; margin-inline: auto; }

/* ═══ 5 · INDEX RAIL — count / chapter / ember progress ════════════
   JS-derived state, so it only exists when JS runs. It rides the
   scroll: present while you move, gone a beat after you stop, so it
   never permanently occludes a garment.                              */
.cat-rail { display: none; }
.cat-js .cat-rail {
  position: fixed; z-index: 20;
  left: max(12px, env(safe-area-inset-left, 0px));
  bottom: max(12px, env(safe-area-inset-bottom, 0px));
  display: flex; align-items: baseline; gap: 8px;
  padding: 9px 14px 10px;
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  border: 1px solid var(--line);
  color: var(--ash); font-size: 10.5px;
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  opacity: 0; pointer-events: none;
  transition: opacity 0.35s var(--ease), transform 0.45s var(--ease);
}
.cat-js .cat-rail.is-live { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .cat-js .cat-rail { transform: translateY(10px); }
  .cat-js .cat-rail.is-live { transform: none; }
}
.cat-rail__n { color: var(--ink); font-size: 13px; }
.cat-rail__ch { color: var(--ink-soft); }
.cat-rail__ch::before { content: '·'; margin-right: 8px; color: var(--line); }
.cat-rail__bar { position: absolute; left: -1px; right: -1px; bottom: -1px; height: 1px; background: var(--line); }
.cat-rail__bar i {
  display: block; height: 100%; width: 100%;
  transform: scaleX(var(--p, 0)); transform-origin: 0 50%;
  background: var(--ember-l);
  box-shadow: 0 0 6px 0 color-mix(in srgb, var(--ember-l) 80%, transparent);
}

/* ═══ 6 · MOTION — identical on mobile and desktop, all scroll-driven
   Every rule below is inside no-preference AND behind .cat-js, so
   reduced-motion and no-JS both get the finished page, statically.   */
@media (prefers-reduced-motion: no-preference) {
  /* title: masked word rise, then the ember rule draws */
  .cat-js .cat-title .w > span { transform: translateY(104%); transition: transform 1.05s var(--ease) var(--d, 0s); }
  .cat-js .cat-title.is-in .w > span { transform: none; }
  .cat-js .cat-title::after { transform: scaleX(0); transition: transform 1.3s var(--ease) 0.42s; }
  .cat-js .cat-title.is-in::after { transform: scaleX(1); }

  /* imagery: a clip wipe up from the lower edge, the frame settling out of scale */
  /* the same wipe as a compositor-only animation: a plate-coloured curtain
     retracting downward (transform), instead of an animated clip-path,
     which repaints the whole figure every frame of its 1.15s */
  .cat-js .cut__fig::after {
    content: ''; position: absolute; inset: 0; z-index: 5; pointer-events: none;
    background: var(--white);
    transform-origin: 50% 100%; transform: scaleY(1);
    transition: transform 1.15s var(--ease);
  }
  .cat-js .cut.is-in .cut__fig::after { transform: scaleY(0); }
  .cat-js .cut__img, .cat-js .cut__alt { transform: scale(1.06); transition: transform 1.5s var(--ease), opacity 0.45s var(--ease); }
  .cat-js .cut.is-in .cut__img, .cat-js .cut.is-in .cut__alt { transform: none; }

  /* meta: the hairline runs, the ember tick lights after it */
  .cat-js .cut__meta::before { transform: scaleX(0); transition: transform 0.95s var(--ease) 0.1s; }
  .cat-js .cut.is-in .cut__meta::before { transform: scaleX(1); }
  .cat-js .cut__meta::after { transform: scaleX(0); transition: transform 0.7s var(--ease) 0.5s; }
  .cat-js .cut.is-in .cut__meta::after { transform: scaleX(1); }

  /* strata head: rule draws, the ghost glyph lifts */
  .cat-js .stratum__head::before { transform: scaleX(0); transform-origin: left center; transition: transform 1.2s var(--ease); }
  .cat-js .stratum.is-in .stratum__head::before { transform: scaleX(1); }
  .cat-js .stratum__glyph { opacity: 0; transform: translateY(26px); transition: opacity 1.4s var(--ease) 0.15s, transform 1.6s var(--ease) 0.15s; }
  .cat-js .stratum.is-in .stratum__glyph { opacity: 1; transform: none; }

  /* scroll-driven drift on engines that have view timelines — no JS at all */
  @supports (animation-timeline: view()) {
    .cat-js .stratum__glyph {
      animation: glyph-drift linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 62%;
    }
    @keyframes glyph-drift {
      from { transform: translateY(34px); opacity: 0; }
      40%  { opacity: 1; }
      to   { transform: translateY(-30px); opacity: 1; }
    }
  }
}

/* ═══ 7 · THE TURN — flat front → three-quarter ════════════════════
   State lives outside the motion query so the swap still happens with
   reduced motion (it just happens instantly). Press on touch, hover on
   a mouse, focus on a keyboard — affordance only, never information. */
.cut.is-peek .cut__alt { opacity: 1; }
.cut.is-peek .cut__img { opacity: 0; }
.cut.is-peek .cut__go { color: var(--ink); }
.cut.is-peek .cut__go i { transform: translateX(5px); }

@media (hover: hover) and (pointer: fine) {
  .cut:hover .cut__alt { opacity: 1; }
  .cut:hover .cut__img { opacity: 0; }
  .cut:hover .cut__go { color: var(--ink); }
  .cut:hover .cut__go i { transform: translateX(5px); }
}
@media (prefers-reduced-motion: no-preference) {
  .cut__alt, .cut__img { transition: opacity 0.45s var(--ease); }
}
.cut__link:focus-visible { outline-offset: 5px; }
