/* ============================================================
   ERF SETS — Photo Set + Gear Manifest
   Two ways of presenting a body of work: frames with air around
   them, and the kit as a camera report. Same mono furniture as
   the rest of the site; 4vw rails.
   ============================================================ */

/* ══ PHOTO SET ══════════════════════════════════════════════
   Two presentations of the same set. MONTAGE is the site's own
   language (edge to edge, 6px seams, dense) as used on the case
   studies; GALLERY gives each frame air. Neither ever crops:
   frames keep their true aspect, so portraits stay whole. */
.erf-ps{
  --ink:#ffffff; --faint:#6a6a6a; --line:#1e1e1e;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  display:flex; flex-direction:column; align-items:center;
  gap:var(--ps-gap,7rem);
  padding:var(--ps-padv,6rem) 4vw;
  width:100%; box-sizing:border-box;
}
.erf-ps *{box-sizing:border-box}
.erf-ps-block{width:100%;display:flex;justify-content:center;gap:1.25rem}

/* ── montage: the case-study grid. Portraits take a column, landscapes
      run the full width. Nothing is cropped; rows size to the frames. ── */
.erf-ps.is-montage{
  display:grid;grid-template-columns:repeat(var(--ps-cols,3),1fr);
  gap:6px;padding:0;align-items:start;
}
.erf-ps.is-montage .erf-ps-fig{margin:0;position:relative;display:block;min-width:0}
.erf-ps.is-montage .erf-ps-fig img{width:100%;height:auto;max-height:none;display:block}
/* an even grid: identical-shape frames all crop to one ratio so the rows
   line up instead of each cell setting its own height */
.erf-ps.is-montage.is-even .erf-ps-fig img{aspect-ratio:var(--ps-ratio,1.19);object-fit:cover}
.erf-ps.is-montage .erf-ps-fig.is-wide{grid-column:1 / -1}
.erf-ps.is-montage figcaption{position:absolute;left:10px;bottom:8px;margin:0;
  font-family:var(--mono);font-size:10px;letter-spacing:2px;
  color:rgba(230,223,204,.9);text-shadow:0 1px 6px rgba(0,0,0,.8);opacity:0;transition:opacity .2s}
.erf-ps.is-montage .erf-ps-fig:hover figcaption{opacity:1}
@media(max-width:900px){
  .erf-ps.is-montage{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:560px){
  .erf-ps.is-montage{grid-template-columns:1fr}
}
/* A one-column set is a deliberate full-bleed frame used to break up the grid
   rows, so it must stay one column at every width. Without this the responsive
   rules above collapse it to two and it reads as just another grid row. */
.erf-ps.is-montage.is-single{grid-template-columns:1fr}
.erf-ps-fig{margin:0;position:relative;display:flex;flex-direction:column;align-items:flex-start}
.erf-ps-fig img{display:block;max-width:100%;height:auto}

/* a landscape frame takes the width it is given */
.erf-ps-block.is-wide .erf-ps-fig{width:var(--ps-wide,100%)}
.erf-ps-block.is-wide img{width:100%;height:auto}

/* a portrait stands to its own height, never cropped */
.erf-ps-block.is-tall img{max-height:var(--ps-tall,82vh);width:auto;max-width:100%}
.erf-ps-block.is-square img{max-height:calc(var(--ps-tall,82vh) * .82);width:auto;max-width:100%}

/* two portraits, side by side, matched on height */
.erf-ps-block.is-pair{align-items:flex-start;gap:1.25rem}
.erf-ps-block.is-pair .erf-ps-fig{flex:0 1 auto;min-width:0}
.erf-ps-block.is-pair img{max-height:calc(var(--ps-tall,82vh) * .86);width:auto;max-width:100%}

.erf-ps-fig figcaption{
  margin-top:.85rem;font-family:var(--mono);font-size:10px;letter-spacing:2px;
  color:var(--faint);font-variant-numeric:tabular-nums;
}
.erf-ps[data-erf-lightbox] .erf-ps-fig img{cursor:zoom-in;transition:opacity .25s ease}
.erf-ps[data-erf-lightbox] .erf-ps-fig img:hover{opacity:.92}

/* viewer */
/* above the site header (99999), or it clips the top of every frame */
.erf-ps-lb{position:fixed;inset:0;z-index:100010;background:rgba(4,4,4,.985);
  display:none;align-items:center;justify-content:center;padding:6vh 6vw}
.erf-ps-lb.open{display:flex}
.erf-ps-lb img{max-width:100%;max-height:88vh;width:auto;height:auto;display:block;
  margin:auto;cursor:zoom-in;transition:max-height .2s ease,max-width .2s ease}
/* past 1x the viewer scrolls; margin:auto keeps it centred until it overflows */
.erf-ps-lb.is-zoomed{overflow:auto}
.erf-ps-lb-zoom{position:absolute;bottom:1.5rem;right:1.5rem;display:flex;align-items:center;gap:2px;
  font-family:'JetBrains Mono',ui-monospace,monospace;z-index:2}
.erf-ps-lb-zoom button{width:34px;height:32px;border:1px solid rgba(230,223,204,.3);background:rgba(7,7,7,.6);
  color:#e6dfcc;font-size:14px;line-height:1;cursor:pointer;transition:.15s}
.erf-ps-lb-zoom button:hover{border-color:#e6dfcc}
.erf-ps-lb-zoom .lvl{min-width:52px;text-align:center;font-size:10px;letter-spacing:1.5px;color:#8a8a84;
  font-variant-numeric:tabular-nums}
.erf-ps-lb-close{position:absolute;top:1.5rem;right:1.5rem;font-family:var(--mono);font-size:11px;
  letter-spacing:2px;color:#e6dfcc;background:none;border:1px solid rgba(230,223,204,.35);
  padding:9px 14px;cursor:pointer;transition:.15s}
.erf-ps-lb-close:hover{border-color:#e6dfcc}
.erf-ps-lb-n{position:absolute;bottom:1.5rem;left:1.5rem;font-family:var(--mono);font-size:10px;
  letter-spacing:2px;color:#6a6a66;font-variant-numeric:tabular-nums}
.erf-ps-lb-nav{position:absolute;top:0;bottom:0;width:22vw;border:none;background:none;
  cursor:pointer;color:#e6dfcc;font-size:24px;opacity:0;transition:opacity .2s}
.erf-ps-lb-nav:hover{opacity:.7}
.erf-ps-lb-nav.prev{left:0}
.erf-ps-lb-nav.next{right:0}

@media(max-width:860px){
  .erf-ps{gap:calc(var(--ps-gap,7rem) * .5);padding:3rem 4vw}
  .erf-ps-block.is-pair{flex-direction:column;align-items:center;gap:calc(var(--ps-gap,7rem) * .5)}
  .erf-ps-block.is-tall img,.erf-ps-block.is-pair img{max-height:70vh}
}
@media(prefers-reduced-motion:reduce){
  .erf-ps *,.erf-ps-lb *{transition:none!important}
}

/* ══ GEAR MANIFEST ══════════════════════════════════════════ */
.erf-gm{
  --ink:#ffffff; --muted:#8a8a8a; --faint:#6a6a6a; --line:#1e1e1e; --line2:#141414; --phos:#38ff70;
  --mono:'JetBrains Mono',ui-monospace,monospace; --disp:'Kanit',system-ui,sans-serif;
  color:var(--ink);font-family:var(--mono);width:100%;box-sizing:border-box;
}
.erf-gm *{box-sizing:border-box}
.erf-gm-bar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px;
  padding:18px 4vw;border-bottom:1px solid var(--line);
  font-size:11px;letter-spacing:2px;color:var(--faint)}
.erf-gm-bar .l{display:flex;align-items:center;gap:12px}
.erf-gm-bar b{color:var(--ink);font-weight:500}
.erf-gm-bar .dot{width:6px;height:6px;border-radius:50%;background:var(--muted);flex:0 0 auto}

.erf-gm-head{padding:var(--gm-padv,5rem) 4vw 1.6rem;border-bottom:1px solid var(--line)}
.erf-gm-head:empty{display:none}
.erf-gm-head .eyebrow{margin:0 0 14px;font-size:10px;letter-spacing:3px;color:var(--faint);text-transform:uppercase}
.erf-gm-head h2{margin:0;font-family:var(--disp);font-weight:600;letter-spacing:-.02em;line-height:.95;
  font-size:clamp(34px,5.2vw,72px);text-wrap:balance;color:var(--ink)}
.erf-gm-head .intro{margin:22px 0 0;font-size:13px;line-height:1.75;color:var(--muted);max-width:58ch}

.erf-gm-body{padding:0 4vw calc(var(--gm-padv,5rem) * .6)}
.erf-gm-bar + .erf-gm-body{padding-top:26px}
.erf-gm-sec{padding:22px 0 4px}
.erf-gm-sh{display:flex;justify-content:space-between;align-items:baseline;gap:16px;
  padding-bottom:12px;border-bottom:1px solid var(--line)}
.erf-gm-sh h3{margin:0;font-size:11px;font-weight:500;letter-spacing:3px;text-transform:uppercase;color:var(--ink)}
.erf-gm-sh span{font-size:10px;letter-spacing:2px;color:var(--faint);text-transform:uppercase}
.erf-gm-row{display:grid;grid-template-columns:60px minmax(180px,1fr) 1.2fr auto;gap:16px;align-items:baseline;
  padding:10px 0;border-bottom:1px solid var(--line2)}
/* Departments read as columns divided by hairlines, not as boxes. A boxed
   grid with align-items:stretch made a one-item department (Grip) look like a
   mostly empty container; a rule that simply runs the full height reads as
   deliberate structure instead. Rows still align across the band. */
/* no border-top here: the bar (or masthead) above already draws that rule,
   and two of them stacked was the doubled line */
.erf-gm-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(232px,1fr));
  align-items:stretch;gap:0}
.erf-gm-cards .erf-gm-card{border:0;border-left:1px solid var(--line);background:none;
  padding:22px 26px 26px;display:flex;flex-direction:column;min-width:0}
.erf-gm-cards .erf-gm-card:first-child{border-left:0;padding-left:0}
.erf-gm-cards .erf-gm-card.is-wide{grid-column:span 2}
.erf-gm-cards .erf-gm-card.is-wide .list{columns:2;column-gap:30px}
.erf-gm-cards .erf-gm-card.is-wide .it{break-inside:avoid}
@media(max-width:900px){
  .erf-gm-cards{grid-template-columns:1fr}
  .erf-gm-cards .erf-gm-card{border-left:0;border-top:1px solid var(--line);padding:20px 0}
  .erf-gm-cards .erf-gm-card:first-child{border-top:0}
  .erf-gm-cards .erf-gm-card.is-wide{grid-column:span 1}
  .erf-gm-cards .erf-gm-card.is-wide .list{columns:1}
}
.erf-gm-card h4{margin:0 0 18px;display:block;
  font-size:10px;letter-spacing:3px;color:var(--muted);text-transform:uppercase;font-weight:500}
.erf-gm-card .it{padding:13px 0}
.erf-gm-card .it + .it{border-top:1px solid var(--line2)}
.erf-gm-card .list .it:first-child{padding-top:0}
.erf-gm-card .it .k{display:block;font-size:9px;letter-spacing:2px;color:var(--faint);
  text-transform:uppercase;margin-bottom:5px;font-variant-numeric:tabular-nums}
.erf-gm-card .it b{display:block;font-weight:500;font-size:13px;color:var(--ink);letter-spacing:.01em}
.erf-gm-card .it small{display:block;font-size:10px;letter-spacing:1.2px;color:var(--faint);
  text-transform:uppercase;margin-top:4px}
.erf-gm-card .it u{display:block;text-decoration:none;font-size:11px;line-height:1.6;
  color:var(--muted);margin-top:7px;letter-spacing:0;text-transform:none}
.erf-gm-row .ix{font-size:10px;letter-spacing:1px;color:var(--faint);font-variant-numeric:tabular-nums}
.erf-gm-row .item{font-size:13px;font-weight:500;color:var(--ink)}
.erf-gm-row .item small{display:block;margin-top:3px;font-size:10px;font-weight:400;letter-spacing:1.5px;
  text-transform:uppercase;color:var(--faint)}
.erf-gm-row .note{font-size:11px;line-height:1.7;color:var(--muted)}
.erf-gm-row .chip{justify-self:end;white-space:nowrap;font-size:9px;letter-spacing:1.5px;text-transform:uppercase;
  border:1px solid var(--line);color:var(--faint);padding:4px 9px}
.erf-gm-row .chip.is-kit{border-color:#3a3a34;color:var(--ink)}

.erf-gm-foot{display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;
  padding:20px 4vw calc(var(--gm-padv,5rem) * .6);border-top:1px solid var(--line);
  font-size:10px;letter-spacing:2px;color:var(--faint);text-transform:uppercase}

@media(max-width:820px){
  .erf-gm-row{grid-template-columns:56px 1fr auto}
  .erf-gm-row .note{grid-column:2 / -1;grid-row:2;margin-top:-4px}
}

/* On a phone each item stacked its code, its name and its spec on three lines,
   so fourteen of them ran to nearly two screens. The L-01 codes are a rental
   convention, useful on a printed sheet and noise on a phone, so they go and
   the spec sits beside the name instead. Roughly halves the section. */
@media(max-width:640px){
  .erf-gm-card{padding:16px 0}
  .erf-gm-card h4{margin-bottom:12px}
  .erf-gm-card .it{padding:9px 0;display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
  .erf-gm-card .it .k{display:none}
  .erf-gm-card .it b{font-size:12px}
  .erf-gm-card .it small{margin-top:0}
  .erf-gm-card .it u{flex:1 0 100%;margin-top:4px}
}

/* grab cursors while a zoomed photo can be dragged around */
.erf-ps-lb.is-zoomed img{cursor:grab}
.erf-ps-lb.is-panning,.erf-ps-lb.is-panning img{cursor:grabbing;user-select:none}

/* Erf 2026-08-02: --ink was #e6dfcc, a warm cream that read as yellow
   against the black page. Every set widget is pure white now, so the
   family matches. The greys carried the same cast at lower brightness
   (#8a8a84 and #6a6a66 both pull the blue channel down), so they are
   neutral now too. The lead/body/eyebrow HIERARCHY is unchanged, only
   the temperature. */
/* ══ CREDITS · roll ═════════════════════════════════════════ */
.erf-cr{
  --ink:#ffffff; --muted:#8a8a8a; --faint:#6a6a6a; --line:#1e1e1e;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  color:var(--ink);font-family:var(--mono);width:100%;box-sizing:border-box;
  padding:var(--cr-padv,5rem) 4vw;text-align:center;
}
.erf-cr *{box-sizing:border-box}
.erf-cr-eyebrow{margin:0 0 2.6rem;font-size:10px;letter-spacing:3.4px;
  color:var(--faint);text-transform:uppercase}
.erf-cr-block{margin-bottom:30px}
.erf-cr-block:last-child{margin-bottom:0}
.erf-cr-pair{margin-bottom:16px}
.erf-cr-pair:last-child{margin-bottom:0}
.erf-cr-role{font-size:9.5px;letter-spacing:3.4px;text-transform:uppercase;
  color:var(--faint);margin-bottom:7px}
.erf-cr-name{font-size:var(--cr-name,16px);color:var(--ink);font-weight:500;letter-spacing:.01em}
.erf-cr-name a{color:inherit;text-decoration:none;border-bottom:1px solid transparent;
  transition:border-color .25s ease}
.erf-cr-name a:hover,.erf-cr-name a:focus-visible{border-bottom-color:var(--muted)}
.erf-cr-note{margin-top:6px;font-size:11px;line-height:1.6;color:var(--faint);
  letter-spacing:0;text-transform:none;max-width:52ch;margin-left:auto;margin-right:auto}
.erf-cr-rule{width:26px;height:1px;background:var(--line);margin:34px auto}
/* compact: same shape, tighter rhythm, for a large crew */
.erf-cr.is-compact .erf-cr-block{margin-bottom:20px}
.erf-cr.is-compact .erf-cr-pair{margin-bottom:10px}
.erf-cr.is-compact .erf-cr-role{margin-bottom:4px;letter-spacing:2.8px}
.erf-cr.is-compact .erf-cr-rule{margin:22px auto}

/* ══ BTS · strip ════════════════════════════════════════════ */
.erf-bs{
  --ink:#ffffff; --muted:#8a8a8a; --faint:#6a6a6a; --line:#1e1e1e; --line2:#141414;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  color:var(--ink);font-family:var(--mono);width:100%;box-sizing:border-box;
  padding-bottom:var(--bs-padv,4rem);
}
.erf-bs *{box-sizing:border-box}
.erf-bs-bar{display:flex;justify-content:space-between;align-items:center;gap:14px;
  padding:16px 4vw;border-bottom:1px solid var(--line);
  font-size:10.5px;letter-spacing:2.5px;color:var(--faint);text-transform:uppercase}
.erf-bs-bar .l{display:flex;align-items:center;gap:11px}
.erf-bs-bar b{color:var(--ink);font-weight:500}
.erf-bs-bar .dot{width:6px;height:6px;border-radius:50%;background:var(--muted);flex:0 0 auto}

/* The scroller's BOX is inset, not its padding. With padding the container ran
   the full width and frames were clipped by the browser edge; with a margin the
   container itself stops at 4vw, so frames clip on the same line the header,
   the transport and every other section align to. */
.erf-bs-track{display:flex;gap:0;overflow-x:auto;padding:26px 0 0;margin:0 4vw;
  scrollbar-width:none;-ms-overflow-style:none;scroll-behavior:smooth;
  cursor:grab;outline:none}
.erf-bs-track::-webkit-scrollbar{display:none}
.erf-bs.is-dragging .erf-bs-track{cursor:grabbing;scroll-behavior:auto;user-select:none}
.erf-bs-track:focus-visible{box-shadow:inset 0 0 0 1px var(--muted)}
/* strip that fits: no scroll affordance, frames centred */
.erf-bs.is-static .erf-bs-track{justify-content:center;overflow-x:hidden;cursor:default}
.erf-bs.is-static .erf-bs-transport{display:none}

.erf-bs-frame{flex:0 0 auto;width:var(--bs-w,300px);margin:0;padding:0 9px;
  border-right:1px solid var(--line);position:relative}
.erf-bs-frame:first-child{border-left:1px solid var(--line)}
/* The track is a drag-scroller (cursor:grab) and the frames were unconditionally
   zoom-in, so the two fought: the pointer promised a zoom while the gesture that
   actually works is a drag. zoom-in now appears only where a click really does
   open the lightbox; otherwise the frame inherits the track's grab. */
.erf-bs-frame img{width:100%;aspect-ratio:var(--bs-ratio,1.5);object-fit:cover;display:block;
  background:#0c0c0c;cursor:inherit}
.erf-bs[data-erf-lightbox] .erf-bs-frame img{cursor:zoom-in}
.erf-bs.is-dragging .erf-bs-frame img{cursor:grabbing}
.erf-bs-frame .perf{display:block;height:12px;margin:0 -9px;
  background-image:radial-gradient(circle at 6px 50%, transparent 0 2.5px, var(--line) 2.5px 3.5px, transparent 3.5px);
  background-size:22px 12px;background-repeat:repeat-x;opacity:.85}
.erf-bs-frame figcaption{padding:10px 0 2px}
.erf-bs-frame figcaption .c{display:block;font-size:11.5px;letter-spacing:.2px;color:var(--ink)}
.erf-bs-frame figcaption .s{display:block;margin-top:4px;font-size:9.5px;letter-spacing:1.8px;
  text-transform:uppercase;color:var(--faint)}

.erf-bs-transport{display:flex;align-items:center;gap:14px;padding:20px 4vw 0}
.erf-bs-arrow{flex:0 0 auto;width:30px;height:26px;border:1px solid var(--line);
  background:none;color:var(--muted);font-size:15px;line-height:1;cursor:pointer;
  transition:border-color .2s ease,color .2s ease}
.erf-bs-arrow:hover:not(:disabled){border-color:var(--ink);color:var(--ink)}
.erf-bs-arrow:disabled{opacity:.3;cursor:default}
.erf-bs-rail{position:relative;flex:1 1 auto;height:26px;cursor:pointer;outline:none}
.erf-bs-rail:focus-visible{box-shadow:0 0 0 1px var(--muted)}
.erf-bs-ticks{position:absolute;inset:0;display:flex;align-items:center;gap:0}
.erf-bs-ticks i{flex:1 1 0;height:5px;border-left:1px solid var(--line2)}
.erf-bs-ticks i:first-child{border-left:0}
.erf-bs-rail::before{content:"";position:absolute;left:0;right:0;top:50%;height:1px;
  background:var(--line);transform:translateY(-.5px)}
.erf-bs-thumb{position:absolute;top:50%;height:3px;background:var(--muted);
  transform:translateY(-1.5px);min-width:22px;left:0;width:30%;
  transition:background .2s ease}
.erf-bs-rail:hover .erf-bs-thumb,.erf-bs.is-dragging .erf-bs-thumb{background:var(--ink)}
.erf-bs-count{flex:0 0 auto;font-size:10px;letter-spacing:2px;color:var(--faint);
  font-variant-numeric:tabular-nums;min-width:66px;text-align:right}

@media(max-width:760px){
  .erf-bs-frame{width:min(var(--bs-w,300px),78vw)}
  .erf-bs-transport{gap:10px}
  .erf-bs-count{min-width:58px}
}
@media(prefers-reduced-motion:reduce){
  .erf-bs-track{scroll-behavior:auto}
}

/* ══ TEXT · same two-column geometry as the Content Block ═══
   Matched deliberately: 38/62 split, 6vw gutter, Kanit at 1.75rem/700 on the
   left and 1rem/1.75 on the right. A passage set in its own narrow column
   read as a footnote next to the blocks above it. */
.erf-tx{
  --ink:#ffffff; --muted:#8a8a8a; --faint:#6a6a6a; --line:#1e1e1e;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  --disp:'Kanit',system-ui,sans-serif;
  display:flex;flex-wrap:nowrap;align-items:flex-start;
  color:var(--ink);width:100%;box-sizing:border-box;
  padding:var(--tx-padv,3.5rem) 4vw;
}
.erf-tx *{box-sizing:border-box}
.erf-tx.has-rule{border-top:1px solid var(--line)}
.erf-tx-left{flex:0 0 var(--tx-left,38%);max-width:var(--tx-left,38%);padding-right:6vw}
.erf-tx-right{flex:0 0 var(--tx-right,62%);max-width:var(--tx-right,62%)}

.erf-tx-eyebrow{margin:0 0 14px;font-family:var(--mono);font-size:10px;letter-spacing:3px;
  text-transform:uppercase;color:var(--faint)}
.erf-tx-lead{margin:0;font-family:var(--disp);font-weight:700;font-size:1.75rem;
  line-height:1.25;letter-spacing:-.01em;color:var(--ink);text-wrap:balance}
.erf-tx-body{margin:0;font-family:var(--disp);font-size:1rem;line-height:1.75;color:var(--muted)}
.erf-tx-aside{margin:22px 0 0;font-family:var(--mono);font-size:10px;letter-spacing:1.8px;
  text-transform:uppercase;color:var(--faint)}

@media(max-width:900px){
  .erf-tx{flex-direction:column;padding-left:6vw;padding-right:6vw}
  .erf-tx-left,.erf-tx-right{flex:0 0 100%;max-width:100%;padding-right:0}
  .erf-tx-left{margin-bottom:1.5rem}
}

/* Persian. Kanit has no Arabic glyphs, so a right-to-left passage was falling
   back to whatever the reader's OS happened to have, which is why the poems
   looked like a different website. Vazirmatn is the modern Persian text face
   and sits closest to Kanit's weight. Tracking goes to zero because letter
   spacing breaks the joins in a connected script, and the line height opens up
   because Persian ascenders and dots need the room. */
.erf-tx[dir="rtl"]{
  font-family:'Vazirmatn',system-ui,sans-serif;
}
.erf-tx[dir="rtl"] .erf-tx-lead,
.erf-tx[dir="rtl"] .erf-tx-body{
  font-family:'Vazirmatn',system-ui,sans-serif;
  letter-spacing:0;
}
.erf-tx[dir="rtl"] .erf-tx-lead{font-weight:600;line-height:1.5}
.erf-tx[dir="rtl"] .erf-tx-body{line-height:2.1;font-size:1.0625rem}
.erf-tx[dir="rtl"] .erf-tx-left{padding-right:0;padding-left:6vw}
.erf-tx[dir="rtl"] .erf-tx-eyebrow,
.erf-tx[dir="rtl"] .erf-tx-aside{letter-spacing:1px}
@media(max-width:900px){
  .erf-tx[dir="rtl"] .erf-tx-left{padding-left:0}
}

/* ══ REFERENCE LINE ═════════════════════════════════════════ */
.erf-rl{
  --ink:#ffffff; --muted:#8a8a8a; --faint:#6a6a6a; --line:#1e1e1e;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  width:100%;box-sizing:border-box;padding:var(--rl-padv,2rem) 4vw;
}
.erf-rl.has-rule{border-top:1px solid var(--line)}
.erf-rl.align-center{text-align:center}
.erf-rl-line{margin:0;font-family:var(--mono);font-size:10px;letter-spacing:2.4px;
  text-transform:uppercase;color:var(--muted);line-height:2.2}
.erf-rl-line .l{color:var(--faint);margin-right:14px}
.erf-rl-line .sep{color:var(--faint);margin:0 10px}
.erf-rl-line a{color:var(--muted);text-decoration:none;
  border-bottom:1px solid transparent;transition:color .2s ease,border-color .2s ease}
.erf-rl-line a:hover,.erf-rl-line a:focus-visible{color:var(--ink);border-bottom-color:var(--line)}
@media(max-width:640px){.erf-rl-line{letter-spacing:1.8px}.erf-rl-line .sep{margin:0 7px}}

/* ══ FILM MASTHEAD ══════════════════════════════════════════
   The opening record of a film page: rail, title, logline, then
   the fixed fact strip. Same furniture as the gear manifest so
   the two read as one family, 4vw rails, nothing centred.

   The fact strip is a FIXED column count per breakpoint, not
   auto-fit: with auto-fit the first cell of a wrapped second row
   keeps its left hairline and draws a stray rule on the gutter.
   Fixed counts let nth-child kill the rule on exactly the cells
   that start a row. Each reset is re-applied before the next
   breakpoint overrides it, so source order stays honest. */
.erf-fm{
  --ink:#ffffff; --soft:#c9c9c9; --muted:#8a8a8a; --faint:#6a6a6a; --line:#1e1e1e;
  --mono:'JetBrains Mono',ui-monospace,monospace; --disp:'Kanit',system-ui,sans-serif;
  color:var(--ink);font-family:var(--mono);width:100%;box-sizing:border-box;
  padding-top:var(--fm-top,0px);
}
.erf-fm *{box-sizing:border-box}

.erf-fm-bar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px;
  padding:18px 4vw;border-bottom:1px solid var(--line);
  font-size:11px;letter-spacing:2px;color:var(--faint);text-transform:uppercase}
.erf-fm-bar .l{display:flex;align-items:center;gap:12px}
.erf-fm-bar b{color:var(--ink);font-weight:500}
.erf-fm-bar .dot{width:6px;height:6px;border-radius:50%;background:var(--muted);flex:0 0 auto}

.erf-fm-head{padding:var(--fm-padv,5rem) 4vw calc(var(--fm-padv,5rem) * .62)}
.erf-fm-head .eyebrow{margin:0 0 16px;font-size:10px;letter-spacing:3px;
  color:var(--faint);text-transform:uppercase}
.erf-fm-head h1,.erf-fm-head h2{margin:0;font-family:var(--disp);font-weight:600;
  font-size:clamp(34px,7vw,var(--fm-title,76px));line-height:.96;letter-spacing:-.02em;
  color:var(--ink);text-wrap:balance}
/* the logline is the second thing read on the page, so it sits near white and
   in the display face. Body grey would file it away as a caption. */
.erf-fm-head .logline{margin:1.9rem 0 0;font-family:var(--disp);font-weight:400;
  font-size:clamp(17px,2.1vw,25px);line-height:1.42;letter-spacing:-.005em;
  color:var(--soft);max-width:46ch}

.erf-fm-facts{display:grid;grid-template-columns:repeat(5,1fr);margin:0;
  padding:0 4vw calc(var(--fm-padv,5rem) * .6);border-top:1px solid var(--line)}
.erf-fm-fact{border-left:1px solid var(--line);padding:22px 26px 6px;min-width:0}
.erf-fm-fact:nth-child(5n+1){border-left:0;padding-left:0}
.erf-fm-fact .k{margin:0 0 10px;font-size:9px;letter-spacing:3px;font-weight:500;
  text-transform:uppercase;color:var(--faint)}
.erf-fm-fact .v{margin:0;font-size:14px;font-weight:500;line-height:1.5;
  color:var(--ink);letter-spacing:.01em}
/* a runtime is a clock, so it gets clock figures */
.erf-fm-fact.is-time .v{font-variant-numeric:tabular-nums;letter-spacing:.06em}

@media(max-width:1100px){
  .erf-fm-facts{grid-template-columns:repeat(3,1fr)}
  .erf-fm-fact:nth-child(5n+1){border-left:1px solid var(--line);padding-left:26px}
  .erf-fm-fact:nth-child(3n+1){border-left:0;padding-left:0}
}
@media(max-width:640px){
  .erf-fm-facts{grid-template-columns:repeat(2,1fr)}
  .erf-fm-fact{padding:18px 18px 6px}
  .erf-fm-fact:nth-child(3n+1){border-left:1px solid var(--line);padding-left:18px}
  .erf-fm-fact:nth-child(2n+1){border-left:0;padding-left:0}
  .erf-fm-head .logline{max-width:none}
}

/* ══ GRADE WIPE ═════════════════════════════════════════════
   Two versions of one frame under a handle. The picture is the
   control, so the chrome is almost nothing: a white hairline,
   a grip, and two labels that get out of the way.

   The handle is WHITE. It carries no reading, so it is chrome,
   and chrome never takes the signal colour (ruling 2026-07-29,
   the same one that governs playheads). */
.erf-gw{
  --ink:#ffffff; --faint:#6a6a6a;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  width:100%;box-sizing:border-box;padding:var(--gw-padv,4rem) 4vw;
}
.erf-gw.is-bleed{padding-left:0;padding-right:0}
.erf-gw *{box-sizing:border-box}

.erf-gw-frame{
  position:relative;width:100%;overflow:hidden;
  aspect-ratio:var(--gw-ar,16 / 9);
  background:#000;cursor:ew-resize;touch-action:none;
  user-select:none;-webkit-user-select:none;
}
/* both frames fill the same box, so the pair can never disagree by a pixel */
.erf-gw-frame img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;pointer-events:none;
}
/* The ungraded side is revealed by CLIP-PATH, not by a narrowing container.
   A container that shrinks with the handle also shrinks the image inside it, so
   the first version pinned the overlay to 100vw to stop it squashing, and 100vw
   is the VIEWPORT, not the frame: inside the 4vw gutter the two frames were
   scaled differently and no longer lined up. That is the one thing this widget
   exists to guarantee. Both images now sit at the identical inset:0 geometry
   and only the painted region differs, so they cannot disagree. */
.erf-gw-clip{position:absolute;inset:0;clip-path:inset(0 calc(100% - var(--gw-at,50%)) 0 0)}

/* the real control, invisible and full height, so keyboard and touch both work */
.erf-gw-range{
  position:absolute;inset:0;width:100%;height:100%;margin:0;
  opacity:0;cursor:ew-resize;z-index:3;
}
.erf-gw-range:focus-visible + .erf-gw-bar{outline:2px solid var(--ink);outline-offset:2px}

.erf-gw-bar{
  position:absolute;top:0;bottom:0;left:var(--gw-at,50%);
  width:1px;background:var(--ink);transform:translateX(-0.5px);
  pointer-events:none;z-index:2;
}
.erf-gw-grip{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:34px;height:34px;border:1px solid var(--ink);border-radius:50%;
  background:rgba(0,0,0,0.28);
}
/* two chevrons, drawn from the same box, so the grip says which way it moves */
.erf-gw-grip::before,.erf-gw-grip::after{
  content:'';position:absolute;top:50%;width:6px;height:6px;
  border-top:1px solid var(--ink);border-right:1px solid var(--ink);
}
.erf-gw-grip::before{left:8px;transform:translateY(-50%) rotate(-135deg)}
.erf-gw-grip::after{right:8px;transform:translateY(-50%) rotate(45deg)}

.erf-gw-tag{
  position:absolute;bottom:12px;z-index:2;pointer-events:none;
  font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink);mix-blend-mode:difference;
}
.erf-gw-tag.l{left:14px}
.erf-gw-tag.r{right:14px}

.erf-gw-cap{
  margin:14px 0 0;font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--faint);
}
.erf-gw.is-bleed .erf-gw-cap{padding:0 4vw}

@media(max-width:640px){
  .erf-gw-grip{width:28px;height:28px}
  .erf-gw-tag{font-size:9px;letter-spacing:.14em;bottom:9px}
  .erf-gw-tag.l{left:10px}
  .erf-gw-tag.r{right:10px}
}
@media(prefers-reduced-motion:reduce){.erf-gw-frame{scroll-behavior:auto}}

/* ══ FRAME GRABS ════════════════════════════════════════════
   Stills held to the film's own shape. The box carries the
   aspect and the picture is CONTAINED inside it, never covered:
   a still that does not match gets letterboxed, which is the
   truth about that file, where a crop would quietly restate the
   framing. Same call as erf_collage's zero-crop rule.

   No border, no hover lift, no plate over the image. The only
   chrome is a mono line underneath. */
.erf-fr{
  --ink:#ffffff; --muted:#8a8a8a; --faint:#6a6a6a;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  width:100%;box-sizing:border-box;padding:var(--fr-padv,4rem) 4vw;
}
.erf-fr.is-bleed{padding-left:0;padding-right:0}
.erf-fr *{box-sizing:border-box}

.erf-fr-eyebrow{
  margin:0 0 1.4rem;font-family:var(--mono);font-size:10px;letter-spacing:.3em;
  text-transform:uppercase;color:var(--faint);
}
.erf-fr.is-bleed .erf-fr-eyebrow{padding:0 4vw}

.erf-fr-grid{
  display:grid;grid-template-columns:repeat(var(--fr-cols,2),minmax(0,1fr));
  gap:calc(var(--fr-gap,6px) * 2.2) var(--fr-gap,6px);
}
.erf-fr-item{margin:0;min-width:0}
/* the film's shape, once, for every frame in the run */
.erf-fr-box{
  position:relative;width:100%;aspect-ratio:var(--fr-ar,2.39);
  background:#000;overflow:hidden;
}
.erf-fr-box img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;display:block;
}
.erf-fr-item figcaption{
  display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  margin-top:9px;font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--faint);
}
.erf-fr-item figcaption .n{color:var(--faint);font-variant-numeric:tabular-nums}
/* a timecode is a clock, so it gets clock figures and never wraps mid-number */
.erf-fr-item figcaption .tc{color:var(--muted);font-variant-numeric:tabular-nums;letter-spacing:.1em;white-space:nowrap}
.erf-fr-item figcaption .nt{color:var(--faint);letter-spacing:.1em;text-transform:none;min-width:0}

@media(max-width:900px){
  /* three across stops being frames and starts being thumbnails */
  .erf-fr-grid{grid-template-columns:repeat(min(var(--fr-cols,2),2),minmax(0,1fr))}
}
@media(max-width:640px){
  .erf-fr-grid{grid-template-columns:minmax(0,1fr)}
  .erf-fr-item figcaption{font-size:9px;gap:9px;margin-top:7px}
}

/* ══ CHAPTER INDEX ══════════════════════════════════════════
   A running order for a long piece. The house language: numbered,
   left on the gutter, mono, the whole row is the target rather
   than the title alone, because a timestamp is a smaller thing
   to hit than a sentence. */
.erf-ci{
  --ink:#ffffff; --muted:#8a8a8a; --faint:#6a6a6a; --line:#1e1e1e;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  width:100%;box-sizing:border-box;padding:var(--ci-padv,4rem) 4vw;
  font-family:var(--mono);
}
.erf-ci *{box-sizing:border-box}
.erf-ci-eyebrow{
  margin:0 0 1.2rem;font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--faint);
}
.erf-ci-list{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.erf-ci-row{border-bottom:1px solid var(--line)}
.erf-ci-hit{
  display:grid;grid-template-columns:34px 74px minmax(0,1fr);gap:14px;align-items:baseline;
  padding:13px 0;text-decoration:none;color:inherit;
}
.erf-ci.no-num .erf-ci-hit{grid-template-columns:74px minmax(0,1fr)}
.erf-ci-hit .n{font-size:10px;letter-spacing:.14em;color:var(--faint);font-variant-numeric:tabular-nums}
/* a timecode is a clock: tabular figures, and it never wraps mid-number */
.erf-ci-hit .t{font-size:11px;letter-spacing:.08em;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.erf-ci-hit .ttl{font-size:13px;letter-spacing:.01em;color:var(--ink);line-height:1.5;min-width:0}
.erf-ci-hit .ttl em{
  display:block;font-style:normal;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--faint);margin-top:4px;
}
a.erf-ci-hit .t,a.erf-ci-hit .ttl{transition:color .18s ease}
a.erf-ci-hit:hover .ttl,a.erf-ci-hit:focus-visible .ttl{color:var(--ink)}
a.erf-ci-hit:hover .t,a.erf-ci-hit:focus-visible .t{color:var(--ink)}
a.erf-ci-hit:focus-visible{outline:1px solid var(--ink);outline-offset:-2px}

@media(max-width:640px){
  .erf-ci-hit{grid-template-columns:26px 62px minmax(0,1fr);gap:10px;padding:11px 0}
  .erf-ci.no-num .erf-ci-hit{grid-template-columns:62px minmax(0,1fr)}
  .erf-ci-hit .ttl{font-size:12px}
}
@media(prefers-reduced-motion:reduce){a.erf-ci-hit .t,a.erf-ci-hit .ttl{transition:none}}
