/* grammar: custom:framed-current · dominant: mare.run · donor axes: contralabs.com
   surface (warm paper) · typography (compressed scale contrast) · motion (horizontal displacement)

   The surface moves continuously and quietly. Nothing enters theatrically: there are no fade
   entrances, no clip or mask reveals, no rotation and no animated filters — deliberate deviations
   from the dominant reference, which measures rotate 19 and blur 39. Exceptional motion is confined
   to four reversible lateral chapter relays. */

/* == piece tokens == */
:root {
  --p-ground: #F7F4EE;
  --p-ground-2: #EDE8DF;
  --p-ink: #151515;
  --p-ink-2: #4A4740;
  --p-ink-3: #6B6861;              /* 5.06:1 on the paper; small text needs 4.5:1 */
  --p-accent: #2854AD;            /* sampled from the Plasmacluster displays in the photographs */
  --p-rule: rgba(21, 21, 21, 0.14);
  --p-plate: #EDE8DF;
  --p-ground-rgb: 247 244 238;
  --p-radius: 3px;                 /* one radius, on every framed image in the piece */
  --p-gutter: 1.5rem;              /* the 12-column gutter */
  --p-drift: 620ms;                /* settle time for a plate that has left the active set */
}
/* == end piece tokens == */

@font-face { font-family: EmagSerif; font-weight: 400; font-display: swap;
  src: url("../fonts/SourceSerif4-Regular.woff2") format("woff2"); }
@font-face { font-family: EmagSerif; font-weight: 600 700; font-display: swap;
  src: url("../fonts/SourceSerif4-SemiBold.woff2") format("woff2"); }
@font-face { font-family: EmagCond; font-weight: 500 800; font-display: swap;
  src: url("../fonts/Archivo-CondExtraBold.woff2") format("woff2"); }
@font-face { font-family: EmagCap; font-weight: 400; font-display: swap;
  src: url("../fonts/BeVietnamPro-Regular.woff2") format("woff2"); }
@font-face { font-family: EmagCap; font-weight: 600; font-display: swap;
  src: url("../fonts/BeVietnamPro-SemiBold.woff2") format("woff2"); }

.td-emag__wrapper :where(div, span, img, br, b) { margin: 0; padding: 0; box-sizing: border-box; }
.td-emag__wrapper :where(img) { display: block; max-width: 100%; height: auto; }

.td-emag__wrapper {
  position: relative;
  background-color: var(--p-ground); color: var(--p-ink);
  font-family: EmagSerif, Georgia, serif; -webkit-font-smoothing: antialiased;
  overflow-x: clip;                       /* containment only — this never animates */
}

/* the one held element: a tonal plane inside the article wrapper, sized below the publisher header.
   Sticky, not fixed: the piece never takes ownership of the host viewport. */
.fc-ground {
  position: sticky; top: var(--td-host-offset); z-index: 0; height: 0;
  pointer-events: none;
}
.fc-ground::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0;
  height: calc(100vh - var(--td-host-offset));
  background: linear-gradient(to bottom, var(--p-ground-2) 0%, var(--p-ground) 62%);
  opacity: 0.55;
}

/* ---------- the 12-column field ----------
   Body copy sits in six columns, which lands at about 42rem — the reading measure the fixed 1.2rem
   body needs to hold 62-66 characters. Photographs take 5 to 10 columns from their own ratio and
   alternate alignment, so the field is asymmetric without any picture ever bleeding. */
.fc-ch, .fc-cover, .fc-close, .fc-footer {
  position: relative; z-index: 1;
  max-width: 85rem; margin: 0 auto; padding: 0 var(--td-space-xl);
}
.fc-ch { padding-top: var(--td-space-2xl); padding-bottom: var(--td-space-2xl); }
/* a band that closes its chapter already carries its own caption room below the photographs */
.fc-ch:has(> .fc-gal:last-child) { padding-bottom: 0; }
/* the standalone page only: this class does not exist in a host document, so nothing leaks into
   the publisher's page — but without it a full-bleed band stops 8px short of the window */
.td-emag__body { margin: 0; }
.fc-read { font-size: var(--td-body-size); line-height: 1.68; }
.fc-gate { padding-bottom: var(--td-space-l); border-bottom: 1px solid var(--p-rule); }
.fc-gate__head {
  font-family: EmagCond, system-ui, sans-serif; font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.9rem, 2.9vw, 2.7rem); line-height: 1.1; letter-spacing: -0.008em;
}


/* ---------- a plate ----------
   Picture and caption are one unit and drift as one. Intrinsic sizing only: no aspect-ratio, no
   resting object-fit, so nothing is cropped. */
.fc-plate--cover { grid-column: auto; }
.fc-plate__frame {
  position: relative; overflow: hidden; border-radius: var(--p-radius);
  background: var(--p-plate); outline: 1px solid var(--p-rule); outline-offset: -1px;
}
.fc-plate__frame img { width: 100%; height: auto; }
.fc-plate__cap {
  margin-top: 1rem; max-width: 34rem;   /* > the 10px drift differential, so the
                                             caption can never climb onto its picture */
  font-family: EmagCap, system-ui, sans-serif; font-weight: 400;
  font-size: 0.8125rem; line-height: 1.5; color: var(--p-ink-3); text-align: left;
}

/* ---------- the chapter gate ----------
   The four thresholds where the piece spends its horizontal axis: the heading travels one way while
   that chapter's first photograph arrives from the other. Scroll-linked and reversible, not a
   one-shot trigger — a concentrated form of the same continuous surface behaviour. */
.fc-gate__label { grid-column: 1 / -1; margin-bottom: var(--td-space-m);
  font-family: EmagCond, system-ui, sans-serif; font-weight: 600; font-size: 0.75rem;
  line-height: 1.25; letter-spacing: 0.22em; color: var(--p-accent); }

/* ---------- the cover ---------- */
.fc-cover { padding-top: var(--td-space-xl); padding-bottom: var(--td-space-3xl); }
.fc-cover__bar { display: flex; justify-content: space-between; align-items: baseline;
  padding-bottom: var(--td-space-m); border-bottom: 1px solid var(--p-rule); }
.fc-cover__date { font-family: EmagCond, system-ui, sans-serif; font-size: 0.75rem;
  letter-spacing: 0.2em; color: var(--p-ink-3); }
/* The headline and the sapo share one band, the photograph takes the full measure beneath them.
   With the sapo parked beside the picture, the headline's line breaks left half the band empty. */
.fc-cover__head { margin: var(--td-space-xl) 0 var(--td-space-2xl); }
.fc-cover__title {
  margin-bottom: var(--td-space-xl);
  font-family: EmagCond, system-ui, sans-serif; font-weight: 800; text-transform: uppercase;
  font-size: clamp(2.6rem, 4.2vw, 4.4rem); line-height: 1.06; letter-spacing: -0.015em;
}
.fc-cover__ln { display: block; }
.fc-cover__ln--accent { color: var(--p-accent); }
.fc-cover__sapo { max-width: 42rem; font-size: 1.5rem; line-height: 1.42; color: var(--p-ink-2); }
.fc-cover__by { margin-top: var(--td-space-m); font-family: EmagCond, system-ui, sans-serif;
  font-size: 0.75rem; letter-spacing: 0.16em; color: var(--p-ink-3); }

/* ---------- closing ----------
   One centred statement on the article's axis, set in the caption sans at display size and in two
   tones: the subject in ink, the rest of the sentence receding. Credits under it, then a single
   quiet line to end on. The page's only symmetrical moment, so the ending reads as an ending. */
.fc-close { padding: var(--td-space-4xl) var(--td-space-xl) var(--td-space-3xl); text-align: center; }
.fc-close__rule { width: 2.5rem; height: 2px; margin: 0 auto var(--td-space-xl);
  border-radius: 2px; background: var(--p-accent); }
.fc-close__t { max-width: 21em; margin: 0 auto;
  font-family: EmagCap, system-ui, sans-serif; font-weight: 600;
  font-size: clamp(2rem, 3.1vw, 3rem); line-height: 1.22; letter-spacing: -0.02em;
  color: var(--p-ink-3); text-wrap: balance; }
.fc-close__lead { color: var(--p-ink); }
.fc-close__credits { display: flex; justify-content: center; gap: var(--td-space-3xl);
  margin-top: var(--td-space-2xl); }
.fc-close__credit { display: flex; flex-direction: column; align-items: center; gap: 0.4rem; }
.fc-close__role { font-family: EmagCap, system-ui, sans-serif; font-weight: 400; font-size: 0.75rem;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--p-ink-3); }
.fc-close__name { font-family: EmagCap, system-ui, sans-serif; font-weight: 600; font-size: 1.0625rem;
  color: var(--p-ink); }
.fc-footer { display: flex; justify-content: center; align-items: baseline; gap: 0.6rem;
  padding-top: var(--td-space-l); padding-bottom: var(--td-space-2xl);
  border-top: 1px solid var(--p-rule); }
.fc-footer__dot, .fc-footer__meta { font-family: EmagCond, system-ui, sans-serif; font-size: 0.75rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--p-ink-3); }
.td-tag { font-family: EmagCond, system-ui, sans-serif; font-weight: 600; font-size: 0.75rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--p-ink-2); }
.td-tag__accent { color: var(--p-accent); }



/* ---------- register 2: the held column ----------
   The media column sticks while the prose scrolls past it, and the photograph changes as the reader
   moves from paragraph to paragraph. The column arrives from the right as the section is entered.
   Nothing is cropped: the photograph is fitted inside the held box at its own ratio. */
.fc-held { display: block; }
.fc-held__media { display: none; }          /* below the field width the run reads as prose + plates */
.fc-held__read > .fc-read { max-width: 42rem; margin: 0 auto var(--td-space-m); }

@media (min-width: 1180px) {
  .fc-held { grid-column: 1 / -1;
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 33rem);
    column-gap: var(--td-space-2xl); align-items: start; }
  .fc-held--flip { grid-template-columns: minmax(0, 33rem) minmax(0, 1fr); }
  /* No script: the run's photographs simply stack in the media column, all of them visible. The
     held behaviour is the enhancement, gated on the class the script sets for itself. */
  .fc-held__media { display: block; grid-column: 1; }
  .fc-shot { margin-bottom: var(--td-space-l); }
  .js .fc-held__media {
    position: sticky; top: calc(var(--td-host-offset) + var(--td-space-l));
    align-self: start;
    /* the arrival travels less than the column gap, or it slides into the reading column */
    transform: translate3d(var(--hx, 0px), var(--pin, 0px), 0);
  }
  /* a host whose wrapper is a scroll container breaks sticky; the script then holds the column by
     offset (--pin), so the element stays in flow at the top of its section */
  .fc-pin-js .fc-held__media { position: relative; top: auto; will-change: transform; }
  /* a fixed picture area; the photograph fits inside it whole, never cropped to fill */
  .js .fc-held__stack { position: relative; height: 62vh; overflow: hidden; }
  .js .fc-shot {
    position: absolute; inset: 0; margin: 0; opacity: 0;
    transform: translate3d(0, var(--sy, 2.2rem), 0) scale(var(--ss, 1.015));
    transition: opacity 520ms var(--td-ease-out), transform 760ms var(--td-ease-out);
  }
  .js .fc-shot.is-on { opacity: 1; --sy: 0rem; --ss: 1; }
  /* the frame hugs the photograph and sits on the floor of the held area, so its caption stays 1rem
     under it whatever the ratio. A fitted-to-the-box image drew plate-coloured bars above and below
     every landscape photograph instead. */
  .js .fc-shot { display: flex; align-items: flex-end; justify-content: flex-start; }
  .js .fc-shot__frame { max-width: 100%; }
  .js .fc-shot__frame img { width: auto; height: auto; max-width: 100%; max-height: 62vh; margin: 0; }
  /* the one leaving goes the other way, so a change reads as a change of occupant rather than a
     dissolve — and the direction follows the direction of reading */
  .js .fc-shot.is-out { --sy: -1.6rem; --ss: 0.995; }

  /* the second held run mirrors the first: column right, prose left */
  .fc-held--flip .fc-held__media { grid-column: 2; }
  .fc-held--flip .fc-held__read { grid-column: 1; }
  /* one caption, not one per photograph: cross-fading captions in a fixed box overlap each other
     while they cross, and a caption sliding under another caption reads as breakage */
  .js .fc-shot__cap { display: none; }
  .fc-held__cap { display: none; }
  .js .fc-held__cap { display: block; margin-top: 1rem;   /* under its picture, like every
    other caption in the piece */
    font-family: EmagCap, system-ui, sans-serif; font-weight: 400; font-size: 0.8125rem;
    line-height: 1.5; color: var(--p-ink-3); text-align: left; }
  .fc-shot__frame { overflow: hidden; border-radius: var(--p-radius); background: var(--p-plate);
    outline: 1px solid var(--p-rule); outline-offset: -1px; }
  .fc-shot__frame img { width: auto; max-width: 100%;
    max-height: calc(100vh - var(--td-host-offset) - 8rem); margin: 0 auto; }
  .fc-shot__cap { margin-top: 1rem; font-family: EmagCap, system-ui, sans-serif; font-weight: 400;
    font-size: 0.8125rem; line-height: 1.5; color: var(--p-ink-3); text-align: left; }
  .fc-held__read { grid-column: 2; }
  .fc-held__read > .fc-read { grid-column: auto; }
  .fc-held__read > .fc-read { max-width: none; margin: 0 0 var(--td-space-xl); }
  .fc-held__read > .fc-read:last-child { margin-bottom: 0; }
  .fc-held__read > .fc-read + .fc-read { margin-top: 0; }   /* no row-gap here to cancel */
}

/* ---------- register 3: the horizontal band ----------
   The track runs right to left as the reader scrolls down. With no script the stage is simply a
   scrollable region — without that the track sits wider than its clip and every photograph past
   the first is unreachable. */
/* The band bleeds to both edges of the window: the negative inline margin pulls it out of the
   article column, and the wrapper's clip absorbs the scrollbar's width. At rest its first photograph
   still starts on the column's left edge, and at the end of its run the last one stops on the
   right edge, so the band leaves and returns to the grid rather than floating free of it. */
.fc-gal {
  --gal-frame: min(68vh, calc(100vh - var(--td-host-offset) - 9rem));   /* one strip height */
  --gal-cap: 4rem;                                                        /* 1rem gap + two lines */
  --gal-edge: max(var(--td-space-xl), calc((100vw - 85rem) / 2 + var(--td-space-xl)));
  grid-column: 1 / -1; margin: 0 calc(50% - 50vw);
}
/* The band is only as tall as its photographs and captions, and holds centred in the window. A
   full-window stage put a fifth of a screen of empty paper above and below the strip. */
.fc-gal__stage {
  position: sticky;
  top: calc(var(--td-host-offset)
       + (100vh - var(--td-host-offset) - var(--gal-frame) - var(--gal-cap)) / 2);
  height: calc(var(--gal-frame) + var(--gal-cap));
  display: flex; align-items: flex-start;
  overflow-x: auto; overflow-y: hidden;      /* the no-script state: a real scroller */
}
.fc-gal__stage:focus-visible { outline: 2px solid var(--p-accent); outline-offset: -4px; }
.js .fc-gal__stage { overflow: hidden; }     /* the script has taken the axis over */
/* where the host breaks sticky the script holds the band by offset instead (piece-current.js) */
.fc-pin-js .fc-gal__stage { position: relative; top: auto;
  transform: translate3d(0, var(--pin, 0px), 0); will-change: transform; }
/* max-content, so the closing padding is part of the track's own width: left to overflow, the end
   padding drops out of scrollWidth and the run stops with the last photograph on the window edge */
.fc-gal__track { display: flex; align-items: flex-start; gap: var(--td-space-l);
  flex: 0 0 auto; width: max-content; padding: 0 var(--gal-edge); }
.js .fc-gal__track { transform: translate3d(calc(var(--lat, 0) * -1px), 0, 0); will-change: transform; }
.fc-gal__item { flex: 0 0 auto; }
.fc-gal__frame { overflow: hidden; border-radius: var(--p-radius); background: var(--p-plate);
  outline: 1px solid var(--p-rule); outline-offset: -1px;
  height: var(--gal-frame); }           /* one height for the strip; width follows the ratio */
.fc-gal__frame img { height: 100%; width: auto; }
/* a caption wraps inside its photograph's width instead of widening the item past it */
.fc-gal__cap { width: 0; min-width: 100%; margin-top: 1rem;
  font-family: EmagCap, system-ui, sans-serif; font-weight: 400;
  font-size: 0.8125rem; line-height: 1.5; color: var(--p-ink-3); text-align: left; }

@media (prefers-reduced-motion: reduce) {
  .fc-held__media { position: static; height: auto; transform: none; }
  .fc-held__stack { position: static; }
  .fc-shot { position: static; opacity: 1; transition: none; margin-bottom: var(--td-space-l); }
  .fc-gal__stage { position: static; height: auto; overflow-x: auto; }
  .js .fc-gal__track { transform: none !important; }
}

/* ---------- the pointer layer ----------
   A cursor-following label over any photograph. This is where the reference spends most of its
   interaction budget, and it costs nothing structurally — no layout moves, nothing scales. */
.fc-cursor {
  position: fixed; left: 0; top: 0; z-index: 40; pointer-events: none;
  padding: 0.45rem 0.75rem; border-radius: var(--p-radius);
  background: var(--p-ink); color: var(--p-ground);
  font-family: EmagCond, system-ui, sans-serif; font-weight: 600; font-size: 0.7rem;
  letter-spacing: 0.18em; text-transform: uppercase;
  opacity: 0; transform: translate3d(var(--cx, 0px), var(--cy, 0px), 0) translate(-50%, -140%);
  transition: opacity 200ms var(--td-ease-out);
}
.fc-cursor.is-on { opacity: 1; }
@media (hover: none) { .fc-cursor { display: none; } }

/* ---------- the composed transform ----------
   One owner per element. The drift and the gate write different variables into the same
   declaration, so they can never fight over `transform` the way two rules would. */
[data-plate], [data-cap], [data-gate-head] {
  transform: translate3d(var(--gx, 0px), var(--dy, 0px), 0) scale(var(--gs, 1));
}
[data-plate].is-live, [data-gate-head].is-live { will-change: transform; }

/* the lightbox trigger is created by the script that powers it — never authored into the markup */
.fc-zoom {
  position: absolute; inset: 0; z-index: 2; cursor: zoom-in;
  background: none; border: 0; appearance: none;
}
.fc-zoom:focus-visible { outline: 2px solid var(--p-accent); outline-offset: -3px; }

@media (prefers-reduced-motion: reduce) {
  [data-plate], [data-cap], [data-gate-head] { transform: none !important; }
}

/* The twelve-column field needs room; below 1180px this bundle still serves the page — the mobile
   cutoff is 640px — so the single measure is what the stylesheet starts from and the field is the
   enhancement. Stated as min-width: a competing max-width breakpoint would shadow the 640px
   constant this project owns. */
.fc-ch { display: block; }
.fc-read { max-width: 42rem; margin-left: auto; margin-right: auto; }
.fc-read + .fc-read { margin-top: var(--td-space-m); }
.fc-plate { margin: var(--td-space-2xl) auto; max-width: 52rem; }
.fc-plate__cap, .fc-plate--r .fc-plate__cap { margin-left: 0; text-align: left; max-width: none; }
.fc-gate { display: block; margin-bottom: var(--td-space-xl); }
.fc-gate__head { margin-top: var(--td-space-s); }

@media (min-width: 1180px) {
  .fc-ch { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--p-gutter); row-gap: var(--td-space-xl); }
  .fc-read { grid-column: 4 / span 6; max-width: none; margin: 0; }
  .fc-read + .fc-read { margin-top: calc(-1 * var(--td-space-xl) + var(--td-space-s)); }
    .fc-plate { --track: calc((100% - 11 * var(--p-gutter)) / 12);
    width: calc(var(--span) * var(--track) + (var(--span) - 1) * var(--p-gutter));
    margin: 0; max-width: none; }
  /* a wide plate is centred on the article's own axis, not on a column line: nine columns cannot
     be centred on twelve at integer positions, and every off-by-one column read as a broken edge */
  .fc-plate--c { grid-column: 1 / -1; margin-left: auto; margin-right: auto; }
  /* the accents keep real grid lines: the left ones start at the page margin, the right ones end
     at it, so each narrow plate still shares an edge with something */
  .fc-plate--l { grid-column: 1 / -1; margin-right: auto; }
  .fc-plate--r { grid-column: 1 / -1; margin-left: auto; }
  .fc-plate__cap { max-width: 34rem; }
  .fc-gate { grid-column: 1 / -1; display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--p-gutter);
    margin-bottom: 0; }
  .fc-gate__head { grid-column: 3 / span 10; margin-top: 0; }
  /* the sapo sits on the headline's last line, in the last four columns of the same field */
  .fc-cover__head { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--p-gutter); align-items: end; }
  .fc-cover__title { grid-column: 1 / span 8; margin-bottom: 0; }
  .fc-cover__side { grid-column: 9 / -1; }
  .fc-cover__sapo { max-width: none; font-size: 1.35rem; }
}
