/* ==========================================================================
   PicturesbyMarc - Cinematic Instrument HUD
   Implements DESIGN.md. Monochrome warm-grey, no hue, zero radius.
   ========================================================================== */

/* --- Fonts: self-hosted, never from a third-party CDN (DSGVO) ------------- */
@font-face {
  font-family: "Roboto Mono";
  src: url("../assets/fonts/robotomono-latin.woff2") format("woff2");
  font-weight: 100 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Roboto Mono";
  src: url("../assets/fonts/robotomono-latin-ext.woff2") format("woff2");
  font-weight: 100 700; font-style: normal; font-display: swap;
  unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,
    U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Arimo";
  src: url("../assets/fonts/arimo-latin.woff2") format("woff2");
  font-weight: 400 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Arimo";
  src: url("../assets/fonts/arimo-latin-ext.woff2") format("woff2");
  font-weight: 400 700; font-style: normal; font-display: swap;
  unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,
    U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* --- Tokens (see DESIGN.md section 9) ------------------------------------ */
:root {
  --bg:          #111111;
  --bg-deep:     #0B0B0B;
  --panel:       #2E2E2E;
  --rule:        #3A3A3A;
  --white:       #FFFFFF;   /* active state AND primary action */
  --cream:       #FCF8EF;   /* body copy */
  --cream-dim:   #E4DFD9;
  --grey-150:    #CBC7C2;   /* default text */
  --grey-200:    #B2AEAB;
  --grey-300:    #8E8C87;
  --scrim-25:    rgba(255,255,255,.25);
  --scrim-35:    rgba(255,255,255,.35);
  --scrim-dark:  rgba(17,17,17,.25);
  --sheet-scrim: rgba(17,17,17,.72);

  --font-display: "Helvetica Neue", Arimo, Arial, sans-serif;
  --font-ui:      "Roboto Mono", ui-monospace, monospace;

  /* Lower bound sized so the longest word ("SONNENAUFGANG.") still fits at 320px. */
  --fs-display-lg: clamp(1.875rem, 8.2vw, 72px);
  --fs-display-sm: clamp(1.5rem, 6.4vw, 44px);
  --fs-menu:  18px;
  --fs-ui:    15px;
  --fs-hud:   13px;
  --fs-micro: 11px;

  --frame: 40px;
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px; --s-7: 28px; --s-8: 40px;
  --s-section: clamp(3rem, 8vw, 7.5rem);

  --dur-heavy:   1.6s;
  --ease-heavy:  cubic-bezier(.887, 0, .113, 1);
  --dur-sheet:   1s;
  --dur-strip:   1.6s;   /* hero filmstrip: a stage-sized move */
  --dur-meta:    .45s;
  --delay-meta:  .45s;
  --dur-light:   .3s;
  --dur-quick:   .25s;
  --ease-light:  cubic-bezier(.4, 0, .15, 1);
  --stage-lift:  24px;
  --vig-size:    45%;
  --vig-radius:  min(114vh, 114vw);
}
@media (max-width: 767px) {
  :root {
    --frame: 20px;
    /* A finger swipe expects a quicker response than a mouse drag; 1.6s felt
       sluggish on touch. Kept slower than the pre-strip 1s baseline, just
       not as deliberate as the desktop cinematic pace. */
    --dur-strip: 1s;
  }
}

/* --- Reset --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--grey-150);
  font: 600 var(--fs-ui)/1.2 var(--font-ui);
  letter-spacing: -.02em;
  text-transform: uppercase;
  overflow-x: hidden;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; letter-spacing: inherit; text-transform: inherit;
  color: inherit; background: none; border: 0; border-radius: 0; padding: 0; cursor: pointer; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, p { margin: 0; }
:focus-visible { outline: 1px solid var(--white); outline-offset: 3px; }
::selection { background: var(--white); color: var(--bg); }

/* --- Type levels --------------------------------------------------------- */
.display-lg { font-family: var(--font-display); font-size: var(--fs-display-lg);
  font-weight: 600; line-height: 1.0; letter-spacing: -.015em; text-transform: uppercase; }
.display-sm { font-family: var(--font-display); font-size: var(--fs-display-sm);
  font-weight: 800; line-height: 1.0; letter-spacing: -.03em; text-transform: uppercase; }
.hud   { font-size: var(--fs-hud);   line-height: 1.2; }
.micro { font-size: var(--fs-micro); line-height: 1.2; color: var(--grey-300); }
/* Section headings carry NO size step: 15px, weight 700, white. */
.eyebrow { font-size: var(--fs-ui); font-weight: 700; color: var(--white); }
.body-copy { color: var(--cream); text-transform: none; letter-spacing: -.02em; line-height: 1.5; }

/* --- Text-roll hover (signature micro-interaction) ----------------------- */
/* The container is exactly one line tall; the duplicate sits below and rolls up. */
.roll { display: inline-block; overflow: hidden; vertical-align: bottom;
  height: 1.2em; line-height: 1.2; }
.roll > span { display: block; transition: transform var(--dur-light) var(--ease-light); }
.roll > span > span { display: block; height: 1.2em; line-height: 1.2; }
.roll:hover > span, a:hover .roll > span, button:hover .roll > span { transform: translateY(-50%); }

/* --- The 40px frame / corner-anchored chrome ----------------------------- */
.frame-top {
  position: fixed; inset: var(--frame) var(--frame) auto var(--frame);
  z-index: 60; display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--s-4); pointer-events: none;
}
.frame-top > * { pointer-events: auto; }
/* Past the hero the chrome needs its own ground, or scrolling copy runs under
   it. Flat fill plus a hairline - no gradient, no shadow, no bar-as-card. */
.frame-top::before {
  content: ""; position: fixed; left: 0; right: 0; top: 0; z-index: -1;
  height: calc(var(--frame) * 2 + 62px);
  background: var(--bg); border-bottom: 1px solid var(--scrim-25);
  opacity: 0; transition: opacity var(--dur-light) var(--ease-light);
}
body[data-scrolled="true"] .frame-top::before { opacity: 1; }
.wordmark { font-family: var(--font-display); font-size: 22px; font-weight: 800;
  letter-spacing: -.03em; color: var(--cream); line-height: 1; }
.status { display: none; }
@media (min-width: 900px) { .status { display: block; text-align: center; } }
.status .line + .line { margin-top: var(--s-1); color: var(--grey-200); }

.nav { display: none; }
.menu-btn { font-size: var(--fs-hud); color: var(--white); min-height: 44px;
  display: flex; align-items: flex-start; }
@media (min-width: 768px) {
  .nav { display: flex; flex-direction: column; align-items: flex-end; gap: var(--s-1); }
  .nav a { font-size: var(--fs-hud); color: var(--grey-150);
    transition: color var(--dur-quick) var(--ease-light); }
  .nav a[aria-current="true"], .nav a:hover { color: var(--white); }
  .menu-btn { display: none; }
}

/* Bottom frame: film-strip edge, hero stage only */
.frame-bottom {
  position: absolute; inset: auto var(--frame) var(--frame) var(--frame);
  z-index: 40; display: flex; align-items: flex-end;
  justify-content: space-between; gap: var(--s-4);
}
.ticks { flex: 1 1 auto; height: 14px; min-width: 0; overflow: hidden;
  display: flex; align-items: flex-end; gap: 6px; }
.ticks i { display: block; width: 1px; height: 5px; background: var(--scrim-25); flex: 0 0 1px; }
.ticks i:nth-child(5n+1) { height: 12px; }

/* --- Mobile menu sheet --------------------------------------------------- */
.sheet {
  position: fixed; inset: 0; z-index: 90; background: var(--panel);
  padding: var(--frame);
  display: flex; flex-direction: column; justify-content: space-between;
  clip-path: inset(0 0 0 100%);
  transition: clip-path var(--dur-sheet) var(--ease-heavy);
}
.sheet[data-open="true"] { clip-path: inset(0 0 0 0); }
.sheet[aria-hidden="true"] { pointer-events: none; }
.sheet-nav a { display: block; font-size: var(--fs-menu); line-height: 1;
  padding: var(--s-4) 0; min-height: 44px; color: var(--grey-150); }
.sheet-nav a[aria-current="true"] { color: var(--white); }
.sheet-close { align-self: flex-end; font-size: var(--fs-menu); color: var(--white);
  min-height: 44px; min-width: 44px; }

/* --- Hero stage ---------------------------------------------------------- */
/* Top padding clears the fixed header, bottom padding the film-strip edge,
   so the stage stays exactly one viewport tall. */
.stage {
  position: relative; min-height: 100dvh; display: flex; flex-direction: column;
  justify-content: center;
  padding: calc(var(--frame) + 76px) var(--frame) calc(var(--frame) + 60px);
  overflow: hidden; isolation: isolate;
}
.stage-img { position: absolute; inset: 0; z-index: -2; }
/* A <picture> wrapper is inline with no intrinsic size of its own; without
   this, the img's percentage width/height wouldn't resolve against
   .stage-img and the cover-fill would break. Removes the wrapper from the
   box tree so the img sizes exactly as it did before. */
.stage-img picture { display: contents; }
.stage-img img { width: 100%; height: 100%; object-fit: cover; }
/* Vignette holds type legible at the edges */
.stage::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(var(--vig-radius) at 50% 45%,
      rgba(17,17,17,0) var(--vig-size), rgba(17,17,17,.82) 100%),
    var(--scrim-dark);
}
/* Absolute width, not ch: ch would be measured in the mono body face, not the
   display face, and would collapse the statement into a narrow column. */
.hero-copy { max-width: 100%; }
@media (min-width: 768px) { .hero-copy { max-width: min(880px, 66vw); } }
.hero-copy .eyebrow, .panel-copy .eyebrow { display: block; margin-bottom: var(--s-5); }
.hero-copy h1, .panel-copy h1 { color: var(--white); }

/* --- Hero filmstrip ------------------------------------------------------ */
/* The stage holds one horizontal track. Panels are narrower than the stage so
   the neighbours peek in at both edges, like frames on a contact strip. */
.stage-strip { padding-left: 0; padding-right: 0; justify-content: center; }
.strip { position: relative; width: 100%; flex: 1 1 auto; min-height: 0;
  overflow: hidden; touch-action: pan-y; cursor: grab; }
.strip[data-dragging="true"] { cursor: grabbing; }

.strip-track {
  position: absolute; inset: 0; display: flex; align-items: stretch;
  gap: var(--s-1); will-change: transform;
}
/* Stage-sized move, so it runs at the spec's stage duration, not the sheet one. */
.strip-track[data-animate="true"] {
  transition: transform var(--dur-strip) var(--ease-heavy);
}

.panel {
  position: relative; flex: 0 0 auto; overflow: hidden; background: var(--bg-deep);
  width: calc(100% - 2 * (var(--frame) + 24px));
  opacity: .28; filter: saturate(.15);
  transition: opacity var(--dur-strip) var(--ease-heavy),
              filter var(--dur-strip) var(--ease-heavy);
}
@media (min-width: 768px) {
  .panel { width: min(calc(100% - 2 * (var(--frame) + 56px)), 1040px); }
}
.panel.is-active { opacity: 1; filter: none; }

.panel-img { position: absolute; inset: 0; }
/* Same reasoning as .stage-img picture: without this, the img's percentage
   sizing wouldn't resolve against .panel-img and the fill would break. */
.panel-img picture { display: contents; }
.panel-img img { width: 100%; height: 100%; object-fit: cover; }
/* Same vignette as the stage, so type stays legible over any frame. */
.panel-title::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(var(--vig-radius) at 50% 45%,
      rgba(17,17,17,0) var(--vig-size), rgba(17,17,17,.82) 100%),
    var(--scrim-dark);
}
.panel-copy {
  position: relative; z-index: 1; height: 100%;
  display: flex; flex-direction: column; justify-content: center;
  padding: var(--s-6) var(--s-5) var(--s-8);
  max-width: 920px;
}
/* A 72px statement needs the big step of the scale around it; the phone gets
   the small one. Nothing between 40px and 80px, per DESIGN.md.
   Every value is also capped against the viewport HEIGHT: the panel clips its
   overflow, so on a flat window the eyebrow and the buttons would be cut off. */
.panel-copy .eyebrow      { margin-bottom: min(var(--s-4), 3vh); }
.panel-copy .hero-sub     { margin-top: min(var(--s-5), 3.5vh); }
.panel-copy .hero-actions { margin-top: min(var(--s-6), 4vh); }
.panel-copy h1            { font-size: min(clamp(1.375rem, 6.2vw, 72px), 9vh); }

@media (min-width: 768px) {
  /* More clearance at the foot than at the head: the buttons are the last
     thing before the image edge and need room to breathe. */
  .panel-copy               { padding: min(var(--s-8), 4.5vh) var(--s-8)
                                       min(calc(var(--s-8) * 1.6), 9vh); }
  .panel-copy .eyebrow      { margin-bottom: min(var(--s-8), 4.5vh); }
  .panel-copy .hero-sub     { margin-top: min(var(--s-8), 4.5vh); }
  .panel-copy .hero-actions { margin-top: min(var(--s-8), 4.5vh); }
  .panel-copy h1            { font-size: min(clamp(2rem, 5.2vw, 72px), 7.5vh); }
}
/* The panel is narrower than the stage, so the statement is sized against the
   panel and may hyphenate rather than run over the edge. */
.panel-copy h1 { hyphens: auto; -webkit-hyphens: auto; overflow-wrap: break-word; }

/* On a small, short phone the subline runs to nine lines and pushes the buttons
   past the clipped panel edge. There the statement and the two actions carry
   the card on their own - the same sentence still stands on the gate screen
   and above the gallery. */
@media (max-width: 767px) and (max-height: 660px) {
  .panel-copy .hero-sub { display: none; }
  .panel-copy .hero-actions { margin-top: var(--s-5); }
}


/* Photo panels: caption is a corner meta line inside the frame, on a scrim. */
.panel-photo { cursor: pointer; }
.panel-cap {
  position: absolute; left: 0; bottom: 0; z-index: 1;
  padding: var(--s-2) var(--s-3);
  background: var(--sheet-scrim);
  font-size: var(--fs-micro); color: var(--cream);
}
.panel-num { position: absolute; top: 0; left: 0; z-index: 1;
  padding: var(--s-2) var(--s-3); background: var(--sheet-scrim);
  font-size: var(--fs-micro); color: var(--grey-200); }

/* Drag hint, fades out once the strip has been used */
.strip-hint { position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--frame) + 74px); z-index: 30; color: var(--grey-300);
  transition: opacity var(--dur-light) var(--ease-light); }
.strip-hint .keys { color: var(--grey-200); }
/* Beats the later `body[data-entered] .late` rule, which shares its specificity. */
body[data-strip-used="true"] .strip-hint.late { opacity: 0; }
@media (max-width: 767px) { .strip-hint .keys, .strip-hint .sep { display: none; } }

/* Bottom frame in strip mode */
.stage-strip .frame-bottom { align-items: center; }
.strip-meta { min-width: 0; }
.strip-meta .line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.strip-meta #stripTitle { color: var(--white); }
.strip-meta #stripPlace { margin-top: var(--s-1); color: var(--grey-200); }

.strip-dots { display: flex; align-items: center; gap: 6px; flex: 0 1 auto;
  justify-content: center; flex-wrap: wrap; }
.strip-dots button {
  width: 14px; height: 24px; display: flex; align-items: center; justify-content: center;
}
.strip-dots button::before {
  content: ""; display: block; width: 1px; height: 8px; background: var(--scrim-25);
  transition: height var(--dur-quick) var(--ease-light),
              background-color var(--dur-quick) var(--ease-light);
}
.strip-dots button:hover::before { background: var(--scrim-35); }
.strip-dots button[aria-selected="true"]::before { height: 16px; background: var(--white); }
@media (max-width: 559px) { .strip-dots { display: none; } }

.strip-tools { display: flex; align-items: center; gap: var(--s-4); flex: 0 0 auto; }
/* On a phone the bottom rail is tight: the step controls earn their place,
   the grain toggle does not. */
@media (max-width: 559px) { .strip-tools #grainBtn { display: none; } }
.strip-step { color: var(--grey-150); min-height: 44px; min-width: 32px; }
.strip-step:hover { color: var(--white); }
.strip-step[disabled] { color: var(--rule); cursor: default; }
.hero-sub { margin-top: var(--s-6); max-width: 46ch; color: var(--cream);
  text-transform: none; line-height: 1.5; font-size: var(--fs-ui); }
.hero-actions { margin-top: var(--s-8); display: flex; flex-wrap: wrap;
  align-items: center; gap: var(--s-6); }

/* Meta text is deliberately late: image leads, type follows */
.late { opacity: 0; transform: translateY(var(--stage-lift)); }
body[data-entered="true"] .late {
  opacity: 1; transform: none;
  transition: opacity var(--dur-meta) var(--ease-light) var(--delay-meta),
              transform var(--dur-meta) var(--ease-light) var(--delay-meta);
}
body[data-entered="true"] .late.late-2 { transition-delay: calc(var(--delay-meta) + .1s); }
body[data-entered="true"] .late.late-3 { transition-delay: calc(var(--delay-meta) + .2s); }

/* --- Buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: var(--s-3) var(--s-6);
  font-size: var(--fs-ui); border-radius: 0;
}
.btn-primary { background: var(--white); color: var(--bg); }
.btn-ghost { padding-inline: 0; color: var(--grey-150); }
.btn-ghost:hover { color: var(--white); }

/* --- Sections ------------------------------------------------------------ */
.section { padding: var(--s-section) var(--frame); }
.section-head { display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--s-4); margin-bottom: var(--s-8); }
.rule { height: 1px; background: var(--scrim-25); border: 0; margin: 0; }

/* Dense multi-column text block, collapses below 768px */
.cols { display: grid; gap: var(--s-8); }
@media (min-width: 768px) { .cols-3 { grid-template-columns: 4fr 3fr 3fr; } }
@media (min-width: 768px) { .cols-2 { grid-template-columns: 5fr 4fr; } }
.col > .eyebrow { display: block; margin-bottom: var(--s-4); }
.col li { padding: var(--s-1) 0; color: var(--grey-150); }
.col li b { color: var(--white); font-weight: 600; }

/* --- Gallery ------------------------------------------------------------- */
.filters { display: flex; flex-wrap: wrap; gap: var(--s-5); }
.filters button { font-size: var(--fs-hud); color: var(--grey-150); min-height: 44px;
  transition: color var(--dur-quick) var(--ease-light); }
.filters button[aria-pressed="true"] { color: var(--white); }
.filters button:hover { color: var(--white); }

/* Multi-column, not grid: portraits and landscapes keep their full frame and
   the rows never go ragged. Nothing is cropped in the contact sheet. */
.grid { column-count: 1; column-gap: var(--s-1); }
@media (min-width: 560px)  { .grid { column-count: 2; } }
@media (min-width: 1000px) { .grid { column-count: 3; } }

.tile { position: relative; display: block; width: 100%; background: var(--bg-deep);
  overflow: hidden; cursor: pointer;
  break-inside: avoid; -webkit-column-break-inside: avoid;
  margin: 0 0 var(--s-1); }
.tile img { width: 100%; height: auto; transition: opacity var(--dur-light) var(--ease-light); }
.tile:hover img { opacity: .82; }
/* Caption sits below the frame as a stacked meta cluster, 4px apart - never
   as white type on an unknown photograph, and never in a box. */
.tile figcaption { padding-top: var(--s-2); font-size: var(--fs-hud); }
.tile figcaption .t { display: flex; gap: var(--s-2); color: var(--grey-150);
  transition: color var(--dur-quick) var(--ease-light); }
.tile figcaption .num { color: var(--grey-300); }
.tile figcaption .place { display: block; margin-top: var(--s-1); color: var(--grey-300); }
.tile:hover figcaption .t, .tile:focus-visible figcaption .t { color: var(--white); }
.tile.is-hidden { display: none; }

.gallery-empty { font-size: var(--fs-ui); color: var(--grey-300); }

/* --- Lightbox ------------------------------------------------------------ */
.lightbox {
  position: fixed; inset: 0; z-index: 100; background: var(--sheet-scrim);
  display: flex; flex-direction: column; padding: var(--frame);
  opacity: 0; visibility: hidden;
  transition: opacity var(--dur-quick) var(--ease-light), visibility 0s linear var(--dur-quick);
}
.lightbox[data-open="true"] { opacity: 1; visibility: visible; transition-delay: 0s; }
/* While the image view is open the page chrome steps aside, so the lightbox
   meta owns the corners instead of colliding with the header. */
body[data-lb="open"] .frame-top { opacity: 0; pointer-events: none;
  transition: opacity var(--dur-quick) var(--ease-light); }
.lb-stage { flex: 1 1 auto; min-height: 0; display: flex; align-items: center;
  justify-content: center; padding: var(--s-6) 0; }
.lb-stage img {
  max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain;
  transition: opacity var(--dur-heavy) var(--ease-heavy);
}
.lb-stage img[data-swap="true"] { opacity: 0; }
.lb-bar { display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between; gap: var(--s-4); }
.lb-meta .line + .line { margin-top: var(--s-1); color: var(--grey-200); }
.lb-title { color: var(--white); }
.lb-actions { display: flex; align-items: center; gap: var(--s-6); }
.lb-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-4); }
.lb-count { font-size: var(--fs-hud); color: var(--grey-200); }
.lb-close { font-size: var(--fs-hud); color: var(--white); min-height: 44px; min-width: 44px;
  display: flex; align-items: flex-start; justify-content: flex-end; }
.lb-nav { display: flex; gap: var(--s-5); }
.lb-nav button { font-size: var(--fs-hud); color: var(--grey-150); min-height: 44px; }
.lb-nav button:hover { color: var(--white); }

/* --- Portrait / about ---------------------------------------------------- */
.about { display: grid; gap: var(--s-8); align-items: start; }
@media (min-width: 768px) { .about { grid-template-columns: 4fr 6fr; } }
.portrait figcaption { margin-top: var(--s-3); font-size: var(--fs-hud); color: var(--grey-200); }
.steps { display: grid; gap: var(--s-6); margin-top: var(--s-8); }
@media (min-width: 768px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.step { padding-top: var(--s-4); border-top: 1px solid var(--scrim-25); }
.step .num { display: block; font-size: var(--fs-hud); color: var(--white); margin-bottom: var(--s-2); }

/* --- Form ---------------------------------------------------------------- */
.form { display: grid; gap: var(--s-7); max-width: 60ch; }
.field { display: block; }
.field > span { display: block; font-size: var(--fs-hud); color: var(--grey-150);
  margin-bottom: var(--s-2); }
.field input, .field select, .field textarea {
  width: 100%; background: none; color: var(--cream);
  font: 600 var(--fs-ui)/1.2 var(--font-ui); letter-spacing: -.02em;
  text-transform: none;
  border: 0; border-bottom: 1px solid var(--scrim-25); border-radius: 0;
  padding: var(--s-3) 0; min-height: 44px;
  transition: border-color var(--dur-quick) var(--ease-light);
}
.field textarea { min-height: 120px; resize: vertical; }
.field select { text-transform: uppercase; }
.field select option { background: var(--panel); color: var(--cream); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-bottom-color: var(--white);
}
.field input::placeholder, .field textarea::placeholder { color: var(--grey-300); }
/* Errors carry no colour: the word does the signalling */
.field-error { display: none; margin-top: var(--s-2); font-size: var(--fs-micro); color: var(--cream); }
.field[data-invalid="true"] .field-error { display: block; }
.field[data-invalid="true"] input,
.field[data-invalid="true"] select,
.field[data-invalid="true"] textarea { border-bottom-color: var(--white); }
.consent { display: flex; gap: var(--s-3); align-items: flex-start; }
.consent input { width: 14px; height: 14px; min-height: 0; flex: 0 0 14px;
  margin-top: 2px; accent-color: var(--white); border-bottom: 0; }
.consent span { font-size: var(--fs-micro); color: var(--grey-150); text-transform: none;
  line-height: 1.5; }
.form-note { font-size: var(--fs-micro); color: var(--grey-300); text-transform: none; line-height: 1.5; }
.form-status { font-size: var(--fs-ui); color: var(--white); }

.contact-direct { margin-top: var(--s-8); }
.contact-direct .eyebrow { display: block; margin-bottom: var(--s-4); }
.contact-direct li { padding: var(--s-1) 0; }
.contact-direct a { color: var(--grey-150); }
.contact-direct a:hover { color: var(--white); }
.placeholder { color: var(--grey-300); }

/* --- Footer -------------------------------------------------------------- */
.footer { padding: var(--s-8) var(--frame) var(--frame); color: var(--cream-dim); }
.footer-grid { display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: var(--s-5); font-size: var(--fs-hud); }
.footer-links { display: flex; flex-wrap: wrap; gap: var(--s-5); }
.footer-links a { color: var(--grey-150); }
.footer-links a:hover { color: var(--white); }

/* --- Film grain (real toggle, off by default) ---------------------------- */
.grain { position: fixed; inset: 0; z-index: 70; pointer-events: none; display: none;
  opacity: .05; mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}
body[data-grain="on"] .grain { display: block; }

/* --- Gate screen --------------------------------------------------------- */
.gate {
  position: fixed; inset: 0; z-index: 200; background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--s-6); padding: var(--frame); text-align: center;
  transition: opacity var(--dur-sheet) var(--ease-heavy), visibility 0s linear var(--dur-sheet);
}
.gate[data-done="true"] { opacity: 0; visibility: hidden; pointer-events: none; }
.gate-mark { color: var(--cream); }
.gate-copy { max-width: 42ch; font-size: var(--fs-micro); color: var(--grey-300);
  line-height: 1.6; }
.gate-pct { font-size: var(--fs-hud); color: var(--white); font-variant-numeric: tabular-nums; }
.gate-progress { width: min(260px, 60vw); height: 1px; background: var(--rule); }
.gate-progress i { display: block; height: 1px; width: 0; background: var(--white);
  transition: width var(--dur-quick) linear; }
.gate-actions { display: flex; flex-direction: column; align-items: center; gap: var(--s-4); }
.gate-skip { font-size: var(--fs-micro); color: var(--grey-300); min-height: 44px; }
.gate-skip:hover { color: var(--grey-150); }

/* --- Legal pages --------------------------------------------------------- */
.legal { max-width: 74ch; margin-inline: auto; padding: calc(var(--frame) * 3) var(--frame) var(--s-section); }
.legal h1 { color: var(--white); margin-bottom: var(--s-8); }
.legal h2 { font-size: var(--fs-ui); font-weight: 700; color: var(--white);
  margin: var(--s-8) 0 var(--s-4); }
.legal p, .legal li { font-size: var(--fs-ui); color: var(--cream);
  text-transform: none; line-height: 1.6; letter-spacing: -.02em; }
.legal p + p { margin-top: var(--s-4); }
.legal ul { margin: var(--s-4) 0; }
.legal li { padding: var(--s-1) 0; }
.legal a { color: var(--white); }
.back-link { display: inline-flex; min-height: 44px; align-items: center;
  font-size: var(--fs-hud); color: var(--grey-150); }
.back-link:hover { color: var(--white); }

/* --- Utility ------------------------------------------------------------- */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.no-js-only { display: none; }

/* --- Reduced motion: collapse the heavy 1.6s to quick crossfades --------- */
@media (prefers-reduced-motion: reduce) {
  :root { --dur-heavy: .25s; --dur-sheet: .25s; --dur-strip: .25s;
          --dur-meta: .01s; --delay-meta: 0s; --stage-lift: 0px; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
  .roll > span { transition: none; }
  .roll:hover > span { transform: none; }
}
