/* ══════════════════════════════════════════════════════════════════
   WORN BY — the depth gallery and the field.

   THE PAGE IS FINISHED BEFORE ANY SCRIPT RUNS. Statically it is four
   large stacked figures with their records beside them, and a wall of
   clippings in a column grid — an editorial page, complete, readable,
   and the only thing a reader without JavaScript, without WebGL or
   with reduced motion ever sees.

   `html.worn-live` turns the four into a DEPTH GALLERY: plates in a
   perspective stage, one at the focus plane, the next waiting behind
   it in depth, the rest not rendered at all. `html.worn-drag` turns
   the wall into a FIELD: one deterministic composition larger than
   the viewport, panned by drag across and by page scroll down.

   ATTRIBUTION IS A LEDGER. There are no chips, no pills and no
   borders around a claim anywhere on this page. `.ledger` is the one
   grammar: a mono label down the left, the archive's own words on the
   right, hairlines between. It reads the same at 9px in a field
   caption and at 11px under a six-foot name.

   Tokens, type and the descent grammar are site.css + descent.css.
   EMBER (#d9611f) is light — rim and glow. It never fills.
   ══════════════════════════════════════════════════════════════════ */

.worn-page { --ember: 217, 97, 31; }

/* ═══ masthead ═══════════════════════════════════════════════════ */
.worn-head__title {
  font-size: clamp(64px, 15.5vw, 208px);
  line-height: 0.84; letter-spacing: -0.02em; margin-top: 4px;
}
.worn-head .lede { margin-block: 20px 38px; max-width: 32ch; }
.worn-facts {
  display: grid; gap: 1px;
  background: var(--line); border-block: 1px solid var(--line);
}
.worn-facts > div { background: var(--paper); padding: 16px 0 18px; display: grid; gap: 6px; }
@media (min-width: 720px) {
  .worn-facts { grid-template-columns: repeat(3, 1fr); gap: 1px; }
  .worn-facts > div { padding: 18px 20px; }
  .worn-facts > div:first-child { padding-left: 0; }
}
.worn-facts dt { color: var(--ash); }
.worn-facts dd { color: var(--ink-soft); font-size: 14px; line-height: 1.5; max-width: 34ch; }

/* ═══ THE LEDGER — the page's only attribution grammar ════════════ */
.ledger { display: grid; }
.ledger > div {
  display: grid; grid-template-columns: 8.5ch minmax(0, 1fr);
  gap: 0 14px; align-items: baseline;
  padding: 5px 0; border-top: 1px solid var(--line);
}
.ledger > div:first-child { border-top: 0; padding-top: 0; }
.ledger dt {
  font-size: 9px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--ash); line-height: 1.6;
}
.ledger dd { font-size: 12px; line-height: 1.45; color: var(--ink-soft); }
/* THE RECEIPT is the one line that is quoted rather than described, so it
   is set in the machine's own face, tracked hard — a transcription, not a
   sentence. */
.ledger > div:nth-child(3) dd {
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: 0.07em; line-height: 1.6;
}
/* the archive's own basis line, filed like everything else — the value
   is printed exactly as the ID BASIS column has it, dash included */
.ledger > div:last-child dd {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.22em;
  text-transform: uppercase; color: rgb(var(--ember)); opacity: 0.9;
}
/* on ink */
.on-ink .ledger > div { border-color: rgba(233, 228, 218, 0.11); }
.on-ink .ledger dt { color: #7d766b; }
.on-ink .ledger dd { color: #c3bcaf; }

/* ═══ the static form of the four ════════════════════════════════ */
.dg { position: relative; }
.dg__spacer { position: relative; }
.dg__stage { position: relative; }
.dg__stack, .dg__names, .dg__recs { list-style: none; }
.dg__wash, .dg__grain, .dg__dust, .dg__rail, .dg__hint { display: none; }

.dg__plate { padding: clamp(36px, 8svh, 96px) var(--gutter) 0; }
.dg__card {
  position: relative; overflow: hidden;
  aspect-ratio: var(--ratio, 0.75);
  background: #0b0a09;
}
.dg__card img,
.fld__plane img {
  position: absolute;
  left: calc(var(--cx) * -100% / var(--cw));
  top: calc(var(--cy) * -100% / var(--ch));
  width: calc(100% / var(--cw));
  height: calc(100% / var(--ch));
  object-fit: cover; object-position: 50% calc(var(--py, 0.5) * 100%);
  max-width: none;
}
.dg__card img { filter: saturate(0.54) contrast(1.14) brightness(0.84) sepia(0.10); }
/* the same corner fall-off the shader gives the frame, so the moment the
   canvas takes the plate over is a change of depth and not of grade */
.dg__card::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(76% 64% at 50% 46%, transparent 32%, rgba(9, 8, 7, 0.58));
}

.dg__name { padding: 18px var(--gutter) 0; }
.dg__who {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(42px, 13vw, 118px); line-height: 0.88; letter-spacing: -0.012em;
}
.dg__act {
  font-size: clamp(11px, 1vw, 13px); letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--ash); margin-top: 10px;
}
.dg__rec { padding: 16px var(--gutter) clamp(36px, 8svh, 96px); max-width: 46ch; }
.dg__no { color: var(--ash); letter-spacing: 0.2em; margin-bottom: 12px; }
.dg__no i { font-style: normal; opacity: 0.45; padding-inline: 2px; }

/* THE STATIC PAGE READS plate → name → record, four times. The markup is
   three parallel lists because the live stage needs the plates inside one
   preserve-3d box and the type outside it; here the lists dissolve and
   every item takes the `order` it was given, which puts each photograph
   back with its own name and its own record. */
html:not(.worn-live) .dg__stage { display: flex; flex-direction: column; }
html:not(.worn-live) :is(.dg__names, .dg__stack, .dg__recs) { display: contents; }
/* a story screenshot at gutter width is a thousand pixels of torso, so the
   plate is capped by HEIGHT and keeps its own shape */
html:not(.worn-live) .dg__card { max-height: 62svh; margin-right: auto; }

@media (min-width: 861px) {
  /* on a desk it is a print with its record beside it. Each shot owns two
     grid rows — the name in the first, the ledger in the second, the
     photograph spanning both — and every item is placed explicitly rather
     than flowed, because three parallel lists cannot auto-place into
     pairs. `--gr` is that placement, baked at build time. */
  html:not(.worn-live) .dg__stage {
    display: grid; grid-template-columns: minmax(0, 44%) minmax(0, 1fr);
    column-gap: 6%; align-items: start;
    padding-inline: var(--gutter);
  }
  html:not(.worn-live) :is(.dg__plate, .dg__name, .dg__rec) {
    padding-inline: 0; grid-row: var(--gr, auto);
  }
  html:not(.worn-live) .dg__plate { grid-column: 1; }
  html:not(.worn-live) :is(.dg__name, .dg__rec) { grid-column: 2; }
  html:not(.worn-live) .dg__name { align-self: end; padding-top: clamp(48px, 10svh, 120px); }
  html:not(.worn-live) .dg__card { max-height: 70svh; }
  .dg__plate { padding-top: clamp(48px, 10svh, 120px); }
}

/* ═══ LIVE — the four become a depth gallery ═════════════════════ */
html.worn-live .dg__spacer { height: calc(var(--beats, 3.4) * 95svh); }
@media (min-width: 861px) { html.worn-live .dg__spacer { height: calc(var(--beats, 3.4) * 100svh); } }

html.worn-live .dg__stage {
  position: sticky; top: 0;
  height: 100svh; overflow: clip;
  background: #070605;
  perspective: 1150px;
  perspective-origin: 50% 46%;
  /* the page must never be trapped: vertical touch always scrolls, and
     the horizontal drag below is read from pointer events the browser
     has already declined to claim. */
  touch-action: pan-y;
  cursor: grab;
  /* a surface you drag is not a surface you select on */
  -webkit-user-select: none; user-select: none;
}
html.worn-live .dg__stage.is-grabbing { cursor: grabbing; }

/* THE ROOM — tinted from the plate at the focus plane. --tint is one
   rgb triple per photograph, measured off the SUBJECT at build time and
   pulled to the ink's own luminance, so what arrives is a hue and not a
   colour cast. The ember sits under it as light off the floor. */
html.worn-live .dg__wash {
  display: block; position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(112% 74% at 50% 108%, rgba(var(--ember), calc(0.26 * var(--ember-k, 0))), transparent 64%),
    radial-gradient(92% 62% at 50% 40%, rgb(var(--tint, 26 24 22)), transparent 72%),
    linear-gradient(to bottom, #121010 0%, #060505 76%);
}

/* THE STACK — one box, every plate absolutely inside it, sorted in Z */
html.worn-live .dg__stack {
  --pw: min(56vw, 30svh);
  --pa: 0.72;
  position: absolute; z-index: 2;
  left: 50%; top: 50%;
  width: var(--pw); height: calc(var(--pw) / var(--pa));
  margin-left: calc(var(--pw) / -2);
  margin-top: calc(var(--pw) / var(--pa) / -2);
  transform-style: preserve-3d;
  pointer-events: none;
}
@media (min-width: 861px) {
  html.worn-live .dg__stack { --pw: min(36vw, 50svh); left: 60.5%; top: 50%; }
}
html.worn-live .dg__plate {
  position: absolute; inset: 0; padding: 0;
  transform-style: preserve-3d;
  will-change: transform, opacity;
}
html.worn-live .dg__plate[hidden] { display: none; }
html.worn-live .dg__card {
  position: absolute; inset: 0; aspect-ratio: auto;
  opacity: var(--imgfade, 1);
}
/* the plate's own edge — a hairline and the shadow it throws into the
   room. It belongs to the PLATE, so it leaves the moment the plate's
   room is lifted away and the figure is standing on its own. */
html.worn-live .dg__card::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: 0 0 0 1px rgba(233, 228, 218, 0.085) inset,
              0 46px 90px -34px rgba(0, 0, 0, 0.9);
  opacity: var(--chrome, 1);
}
html.worn-live .worn-gl {
  display: block; position: absolute; inset: 0;
  width: 100%; height: 100%; pointer-events: none;
  will-change: transform, opacity;
}

/* THE NAME — behind the stack, so a lifted figure stands over it */
html.worn-live .dg__names { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
/* THE NAME NEVER MEETS THE PLATE. Its box is the largest rectangle the
   plate's projected rect leaves free — the strip above it on a phone, the
   column beside it on a desk — measured off real DOM rects and handed here
   as three numbers. The size follows from the box rather than from a
   viewport guess, so GURU RANDHAWA and DEEPIKA PADUKONE set smaller than
   AKSHAY KUMAR instead of setting the same and being eaten. Nothing on
   this page is ever cropped by a photograph arriving on top of it. */
html.worn-live .dg__name {
  position: absolute; padding: 0;
  left: var(--gutter);
  width: var(--nzw, calc(100% - 2 * var(--gutter)));
  top: var(--nzt, auto);
  bottom: var(--nzb, auto);
  opacity: var(--nop, 0);
  transform: translate3d(0, calc(var(--ny, 0) * 1svh), 0);
  will-change: transform, opacity;
}
html.worn-live .dg__name[hidden] { display: none; }
html.worn-live .dg__who {
  font-size: var(--nfs, 52px);
  /* one word to a line, always: the measurement assumed it */
  max-width: calc(var(--nlen, 8) * 0.64 * var(--nfs, 52px));
  line-height: 0.82; color: #efece6;
  overflow-wrap: normal; hyphens: none;
  text-shadow: 0 0 80px rgba(var(--ember), calc(0.24 * var(--ember-k, 0)));
  /* INK ON A ROUGH SHEET. A static, deterministic mask with holes bitten
     out of it — the letterforms are distressed once, at build time, and
     never animate. Type that crawls is a gimmick; this is a texture. */
  -webkit-mask-image: url(/img/proof-depth/nibble.png);
  mask-image: url(/img/proof-depth/nibble.png);
  -webkit-mask-size: 420px 420px; mask-size: 420px 420px;
}
html.worn-live .dg__act { color: #a49c8f; margin-top: 14px; letter-spacing: 0.38em; font-size: 10px; }

/* THE RECORD — in front of everything, always legible */
html.worn-live .dg__recs { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
html.worn-live .dg__rec {
  position: absolute; padding: 0;
  left: var(--gutter); right: var(--gutter);
  bottom: calc(9svh + env(safe-area-inset-bottom, 0px));
  max-width: 44ch; opacity: var(--mop, 0);
}
html.worn-live .dg__rec[hidden] { display: none; }
html.worn-live .dg__no { margin-bottom: 10px; color: #8a8377; }
/* the ledger arrives a row at a time as the plate lands — a strip of
   tape pulled across, not a fade */
html.worn-live .ledger > div {
  clip-path: inset(0 calc((1 - var(--wipe, 1)) * 100%) 0 0);
}
@media (min-width: 861px) {
  html.worn-live .dg__rec { max-width: 38ch; right: auto; bottom: 9vh; }
}

/* the stage's own floor shadow, under the plates, over the wash */
html.worn-live .dg__stage::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 34svh;
  z-index: 3; pointer-events: none;
  background: linear-gradient(to top, rgba(10, 9, 8, 0.94), rgba(10, 9, 8, 0.6) 40%, transparent);
}

/* GRAIN — one 96px tile of neutral noise in soft-light, over the lot.
   It is what makes four different screenshots read as one room. */
html.worn-live .dg__grain {
  display: block; position: absolute; inset: -60px; z-index: 5;
  pointer-events: none;
  background-image: url(/img/proof-depth/grain.png);
  background-size: 116px 116px;
  opacity: 0.17; mix-blend-mode: soft-light;
  animation: dg-grain 0.7s steps(1, end) infinite;
}
/* DUST — the frame of a negative that has been in a drawer. Sparse specks
   and a few hairline scratches, screened over the room and stepped through
   a handful of offsets so it flickers the way a projected print does. */
html.worn-live .dg__dust {
  display: block; position: absolute; inset: -90px; z-index: 5;
  pointer-events: none;
  background-image: url(/img/proof-depth/dust.png);
  background-size: 460px 460px;
  opacity: 0.5; mix-blend-mode: screen;
  animation: dg-dust 1.15s steps(1, end) infinite;
}
@keyframes dg-dust {
  0%   { transform: translate3d(0, 0, 0); }
  25%  { transform: translate3d(-187px, 96px, 0); }
  50%  { transform: translate3d(121px, -204px, 0); }
  75%  { transform: translate3d(63px, 158px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}
@keyframes dg-grain {
  0%   { transform: translate3d(0, 0, 0); }
  20%  { transform: translate3d(-14px, 9px, 0); }
  40%  { transform: translate3d(11px, -16px, 0); }
  60%  { transform: translate3d(-7px, -11px, 0); }
  80%  { transform: translate3d(16px, 6px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* how far through — one hairline across the foot of the pin */
html.worn-live .dg__rail {
  display: block; position: absolute; z-index: 6; pointer-events: none;
  left: var(--gutter); right: var(--gutter);
  bottom: calc(2.4svh + env(safe-area-inset-bottom, 0px));
  height: 1px; background: rgba(233, 228, 218, 0.13);
}
html.worn-live .dg__rail i {
  display: block; height: 100%; background: rgb(var(--ember));
  transform: scaleX(0); transform-origin: 0 50%; opacity: 0.85;
}
html.worn-live .dg__hint {
  display: block; position: absolute; z-index: 6; pointer-events: none;
  left: var(--gutter); right: var(--gutter); text-align: right;
  bottom: calc(4.6svh + env(safe-area-inset-bottom, 0px));
  font-size: 9px; letter-spacing: 0.22em; text-transform: uppercase;
  color: #6f6a61; opacity: var(--hint, 0); transition: opacity 0.5s var(--ease);
}
html.worn-live .dg__hint i { font-style: normal; opacity: 0.5; padding-inline: 7px; }
@media (min-width: 861px) {
  html.worn-live .dg__rail { bottom: 3.6vh; }
  html.worn-live .dg__hint { bottom: 5.6vh; }
}

/* ═══ THE FIELD — the static form is an editorial grid ════════════ */
.fld { padding-top: clamp(56px, 12svh, 130px); }
.fld__head { display: grid; gap: 12px; margin-bottom: clamp(28px, 5svh, 52px); }
.fld__lede { color: var(--ink-soft); max-width: 52ch; font-size: 14.5px; line-height: 1.6; }
.fld__hint { display: none; }
@media (min-width: 900px) {
  .fld__head {
    grid-template-columns: minmax(0, 22ch) minmax(0, 1fr);
    gap: 12px 6%; align-items: start;
    border-top: 1px solid rgba(233, 228, 218, 0.11); padding-top: 22px;
  }
  .fld__head .fld__hint { grid-column: 2; }
}

.fld__spacer, .fld__stage, .fld__pan { position: relative; }
.fld__grid {
  list-style: none;
  container-type: inline-size;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  --g: 10px; --cols: 2;
  gap: 26px var(--g);
  --cell: calc((100cqw - (var(--cols) - 1) * var(--g)) / var(--cols));
  padding-inline: var(--gutter);
}
@media (min-width: 720px) { .fld__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); --g: 16px; --cols: 3; } }
@media (min-width: 1100px) { .fld__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); --g: 18px; --cols: 4; } }

.fld__card { display: grid; gap: 10px; align-content: start; }
.fld__frame {
  position: relative; overflow: hidden; background: #0b0a09;
  aspect-ratio: var(--ratio, 0.8);
}
@supports (width: 1cqw) {
  .fld__card { --fw: var(--cell); --fh: calc(var(--cell) * 1.25);
               --nw: max(var(--fw), calc(var(--fh) * var(--ratio)));
               --nh: max(var(--fh), calc(var(--fw) / var(--ratio))); }
  .fld__frame { aspect-ratio: auto; height: var(--fh); }
}
.fld__plane { position: absolute; inset: 0; display: block; }
.fld__plane img { filter: saturate(0.52) contrast(1.10) brightness(0.80) sepia(0.10); }
.fld__frame::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(116% 80% at 50% 38%, transparent 34%, rgba(19, 17, 16, 0.72));
}
.fld__no {
  position: absolute; z-index: 3; top: 8px; left: 9px;
  font-size: 9.5px; letter-spacing: 0.18em; color: rgba(233, 228, 218, 0.42);
  mix-blend-mode: difference;
}
@media (hover: hover) {
  .fld__plane img { transition: filter 0.45s var(--ease); }
  .fld__card:hover .fld__plane img { filter: saturate(0.9) contrast(1.02) brightness(1); }
  .fld__frame::after { transition: opacity 0.45s var(--ease); }
  .fld__card:hover .fld__frame::after { opacity: 0.3; }
}

/* two planes from one estimate: the whole frame, and the subject lifted
   off it by the baked matte. The PLANE moves, not the picture inside it,
   so the silhouette travels with the body it belongs to. */
.fld__plane--far img { transform: translate3d(0, calc(var(--k, 0) * 5px), 0) scale(1.04); }
.fld__plane--near {
  -webkit-mask-image: var(--near); mask-image: var(--near);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  transform: translate3d(0, calc(var(--k, 0) * -7px), 0);
}
.fld__plane--near img { transform: scale(1.03); }
.fld__card.is-flat .fld__plane--near,
.fld__card.is-flat .fld__ember { display: none; }
.fld__ember {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  -webkit-mask-image: var(--near); mask-image: var(--near);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  background: radial-gradient(58% 30% at 50% 107%, rgba(var(--ember), 0.42), transparent 70%);
  mix-blend-mode: screen; opacity: var(--glow, 0);
  transform: translate3d(0, calc(var(--k, 0) * -7px), 0);
}
/* the mask is handed the same cover box `object-fit` gave the image, or
   every cut-out on the wall sits a few percent off its own body */
@supports (width: 1cqw) {
  .fld__plane--near, .fld__ember {
    -webkit-mask-size: var(--nw) var(--nh); mask-size: var(--nw) var(--nh);
    -webkit-mask-position: calc((var(--fw) - var(--nw)) / 2) calc((var(--fh) - var(--nh)) * var(--py, 0.5));
    mask-position: calc((var(--fw) - var(--nw)) / 2) calc((var(--fh) - var(--nh)) * var(--py, 0.5));
  }
}

.fld__cap { display: grid; gap: 8px; justify-items: start; }
.fld__cap b { font-family: var(--font-body); font-weight: 600; font-size: 14px; letter-spacing: 0.01em; color: var(--ink); }
.fld__cap .ledger { width: 100%; }
.fld__cap .ledger > div { grid-template-columns: 7.5ch minmax(0, 1fr); gap: 0 10px; padding: 5px 0; }
.fld__cap .ledger dd { font-size: 11.5px; }

.fld__foot { margin-top: clamp(32px, 6svh, 64px); }
.worn-method { color: var(--ash); font-size: 10px; letter-spacing: 0.1em; margin-top: 18px; text-transform: none; line-height: 1.8; max-width: 76ch; }
.worn-method b { font-weight: 500; color: var(--ink-soft); }

/* ═══ DRAGGABLE — the grid becomes a field ═══════════════════════ */
html.worn-drag .fld__hint {
  display: block; font-size: 9px; letter-spacing: 0.2em;
  text-transform: uppercase; color: #6f6a61;
}
html.worn-drag .fld__hint i { font-style: normal; color: rgb(var(--ember)); opacity: 0.8; padding-inline: 3px 9px; }

html.worn-drag .fld__spacer { height: 150svh; }
@media (min-width: 861px) { html.worn-drag .fld__spacer { height: 165svh; } }

html.worn-drag .fld__stage {
  position: sticky; top: 0;
  height: 100svh; overflow: clip;
  background:
    radial-gradient(90% 60% at 50% 0%, #15120f, transparent 70%),
    #070605;
  /* vertical touch scrolls the page. Always. The field's vertical travel
     is driven by that scroll; only the horizontal axis is dragged. */
  touch-action: pan-y;
  cursor: grab;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
html.worn-drag .fld__stage.is-grabbing { cursor: grabbing; }
/* …except the record itself, which is a record and can be copied */
html.worn-drag .fld__card.is-open .fld__cap { -webkit-user-select: text; user-select: text; pointer-events: auto; }
html.worn-drag .fld__stage::before {
  content: ""; position: absolute; inset: -60px; z-index: 3; pointer-events: none;
  background-image: url(/img/proof-depth/grain.png);
  background-size: 116px 116px;
  /* no blend mode here on purpose: the field is thirteen masked, blended
     cards already, and one more blend group over the top of them is how a
     compositor starts drawing backplates behind text. Plain opacity over
     ink looks the same and composites like nothing at all. */
  opacity: 0.09;
  animation: dg-grain 0.7s steps(1, end) infinite;
}
html.worn-drag .fld__stage::after {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(10, 9, 8, 0.96), transparent 13%, transparent 88%, rgba(10, 9, 8, 0.96)),
    linear-gradient(to right, rgba(10, 9, 8, 0.8), transparent 9%, transparent 91%, rgba(10, 9, 8, 0.8));
}
/* --fcw is the field's CELL WIDTH, and it is not called --cw because every
   card already carries a --cw of its own: the width of its content rect,
   written into the inline style by the letterbox pass. One shared name and
   every tile in the field lays out at one unitless pixel. */
/* the pan holds a 2×2 NEIGHBOURHOOD of the tile, so wherever the modular
   offset lands the viewport is inside it. --fcw takes the LARGER of a
   width- and a height-derived size, which is what keeps the tile bigger
   than the stage on a wide desk and on a tall phone alike. */
html.worn-drag .fld__pan {
  position: absolute; top: 0; left: 0;
  width: calc(var(--fwu) * var(--fcw) * 2); height: calc(var(--fhu) * var(--fcw) * 2);
  transform: translate3d(var(--px, 0px), var(--py2, 0px), 0);
  will-change: transform;
  --fcw: clamp(170px, max(64vw, 25svh), 340px);
}
@media (min-width: 861px) { html.worn-drag .fld__pan { --fcw: clamp(250px, max(28vw, 30svh), 470px); } }

html.worn-drag .fld__grid {
  display: block; position: absolute; inset: auto;
  left: calc(var(--tx, 0) * var(--fwu) * var(--fcw));
  top: calc(var(--ty, 0) * var(--fhu) * var(--fcw));
  width: calc(var(--fwu) * var(--fcw)); height: calc(var(--fhu) * var(--fcw));
  container-type: normal; padding: 0; gap: 0;
}
html.worn-drag .fld__card[hidden] { display: none; }
html.worn-drag .fld__card {
  position: absolute; display: block;
  left: calc(var(--gx) * var(--fcw)); top: calc(var(--gy) * var(--fcw));
  width: var(--fcw); height: calc(var(--gh) * var(--fcw));
}
html.worn-drag .fld__frame {
  position: absolute; inset: 0; height: auto; aspect-ratio: auto;
  --fw: var(--fcw); --fh: calc(var(--gh) * var(--fcw));
  --nw: var(--fcw); --nh: calc(var(--gh) * var(--fcw));
}
/* in the field the frame is the photograph's own shape, so the mask needs
   no cover box at all — it is exactly the frame */
html.worn-drag .fld__plane--near,
html.worn-drag .fld__ember {
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-position: 0 0; mask-position: 0 0;
}
html.worn-drag .fld__card img { object-position: 50% 50%; }

/* THE RECORD, RAISED. Hidden until a frame is asked, then it stands over
   the field on its own ground — the same ledger as everywhere else. */
html.worn-drag .fld__cap {
  position: absolute; z-index: 3; left: 0; right: 0; top: calc(100% + 10px);
  padding: 12px 13px 13px;
  background: rgba(12, 11, 10, 0.93);
  box-shadow: 0 0 0 1px rgba(233, 228, 218, 0.09), 0 30px 50px -24px rgba(0, 0, 0, 0.9);
  opacity: 0; transform: translate3d(0, -6px, 0);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
  pointer-events: none;
}
html.worn-drag .fld__card.is-open { z-index: 5; }
html.worn-drag .fld__card.is-open .fld__cap { opacity: 1; transform: none; }
html.worn-drag .fld__cap b { color: #efece6; }
/* the name stays on the frame at all times — the field is still a record */
html.worn-drag .fld__frame::before {
  content: attr(data-who);
  position: absolute; z-index: 3; left: 0; right: 0; bottom: 0;
  padding: 26px 11px 9px;
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: #cfc8ba;
  background: linear-gradient(to top, rgba(10, 9, 8, 0.88), transparent);
  pointer-events: none;
}

/* ═══ honest degradation ═════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html.worn-live .dg__spacer { height: auto; }
  html.worn-live .dg__stage { position: relative; height: auto; overflow: visible; perspective: none; touch-action: auto; cursor: auto; }
  html.worn-live .dg__stage::after { display: none; }
  html.worn-live :is(.dg__stack, .dg__names, .dg__recs) { position: static; width: auto; height: auto; margin: 0; transform: none; }
  html.worn-live :is(.dg__plate, .dg__name, .dg__rec) { position: relative; inset: auto; opacity: 1; transform: none; }
  html.worn-live .dg__plate { padding: clamp(36px, 8svh, 96px) var(--gutter) 0; }
  html.worn-live .dg__card { position: relative; inset: auto; aspect-ratio: var(--ratio, 0.75); opacity: 1; }
  html.worn-live .dg__card::after { opacity: 0; }
  html.worn-live .dg__name { padding: 18px var(--gutter) 0; }
  html.worn-live .dg__rec { padding: 16px var(--gutter) clamp(36px, 8svh, 96px); max-width: 46ch; }
  html.worn-live .ledger > div { clip-path: none; }
  html.worn-live :is(.worn-gl, .dg__wash, .dg__grain, .dg__dust, .dg__rail, .dg__hint) { display: none; }
  html.worn-live .dg__who { -webkit-mask-image: none; mask-image: none; max-width: none; font-size: clamp(42px, 13vw, 118px); }
  html.worn-drag .fld__stage::before { display: none; }
  html.worn-drag .fld__spacer { height: auto; }
  html.worn-drag .fld__stage { position: relative; height: auto; overflow: visible; background: none; touch-action: auto; cursor: auto; }
  html.worn-drag .fld__stage::after { display: none; }
  html.worn-drag .fld__pan { position: relative; width: auto; height: auto; transform: none; }
  html.worn-drag .fld__grid { display: grid; position: relative; inset: auto; left: auto; top: auto; width: auto; height: auto; container-type: inline-size; padding-inline: var(--gutter); gap: 26px var(--g); }
  html.worn-drag .fld__card { position: relative; display: grid; left: auto; top: auto; width: auto; height: auto; }
  html.worn-drag .fld__frame { position: relative; inset: auto; height: var(--fh); }
  html.worn-drag .fld__frame::before { display: none; }
  html.worn-drag .fld__cap { position: static; opacity: 1; transform: none; padding: 0; background: none; box-shadow: none; }
  html.worn-drag .fld__hint { display: none; }
  html.worn-drag .fld__grid[aria-hidden="true"] { display: none; }
  .fld__plane img { transform: none !important; }
  .fld__ember { opacity: 0 !important; }
}
