/* ─────────────────────────────────────────────────────────────
 * тисяча · distance travelled — mobile-first, token-driven CSS.
 * Layout from the Paul Hempstead replica; palette and type from
 * the 1000 design system. Breakpoints: 480 / 768 / 992.
 * ───────────────────────────────────────────────────────────── */

/* ─── Title face: MFred (HUX brand), titles only ─── */
@font-face {
  font-family: "MFred";
  src: url("fonts/MFred2.0-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "MFred";
  src: url("fonts/MFred2.0-Heavy.woff2") format("woff2");
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

/* ─── Design tokens ─── */
:root {
  /* Palette (1000) */
  --bg:        #f3b6c8;   /* pink-300 · the cover ground behind the wordmark */
  --text:      #191919;   /* ink · body copy, the wordmark */
  --accent:    #276988;   /* blue-600 · hover + current state, on white or cream */
  --surface:   #f3e2b6;   /* cream-200 · palette token (the editor's Surface); pages are white */
  --border:    #191919;   /* hairlines */
  --muted:     #4d4843;   /* graphite · captions, metadata */

  /* Typography (1000) */
  --font-display: "IBM Plex Mono", ui-monospace, monospace;   /* тисяча wordmark; for now, until a licensed Cyrillic display face */
  --font-title:   "MFred", var(--font-display);   /* titles only, always set in capitals */
  --font-mono:    "JetBrains Mono", ui-monospace, monospace;
  --font-sans:  system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  /* Type scale. Fixed steps per breakpoint (phone values further down),
     in rem so they follow the reader's text size. Every line height is the
     size plus 0.5rem (8px); tracking tightens as type grows and opens for
     text. Interface text (nav, captions, controls, labels) is Small. */
  --t-jumbo: 8rem;       /* 128 · тисяча on the loading screen */
  --t-h1:    4rem;       /* 64  · the Info title */
  --t-h4:    2.5rem;     /* 40  · the contact-sheet title */
  --t-h5:    2rem;       /* 32  · DISTANCE TRAVELLED under the wordmark */
  --t-h6:    1.5rem;     /* 24  · тисяча in the nav */
  --t-lead:  1.25rem;    /* 20  · the Info introduction */
  --t-body:  1rem;       /* 16  · paragraphs */
  --t-small: 0.75rem;    /* 12  · interface text; nothing smaller is used */
  --lead:    0.5rem;     /* added to each size for its line height */
  --track-display: -0.02em;
  --track-heading: -0.01em;
  --track-lead:     0.005em;
  --track-body:     0.01em;
  --track-small:    0.02em;
  /* Earlier names, now on the scale */
  --fs-body:  var(--t-body);
  --fs-link:  var(--t-small);
  --fs-enter: var(--t-small);
  --fs-title: var(--t-small);

  /* Spacing: a 4px grid, in rem. The gap after a heading grows with the
     heading: label to title, small heading to text, section heading to
     text, display heading to text. */
  --space-1:  0.25rem;   /* 4  */
  --space-2:  0.5rem;    /* 8  */
  --space-3:  0.75rem;   /* 12 */
  --space-4:  1rem;      /* 16 */
  --space-5:  1.25rem;   /* 20 */
  --space-6:  1.5rem;    /* 24 */
  --space-7:  2rem;      /* 32 */
  --space-8:  2.5rem;    /* 40 */
  --space-9:  3rem;      /* 48 */
  --space-10: 4rem;      /* 64 */
  --space-11: 6rem;      /* 96 */
  --gap-tag:     var(--space-5);    /* 20 · label → title */
  --gap-card:    var(--space-8);    /* 40 · small heading → text */
  --gap-section: var(--space-10);   /* 64 · section heading → text */
  --gap-hero:    var(--space-11);   /* 96 · display heading → text */
  /* Earlier names, now on the grid */
  --sp-1: var(--space-1);
  --sp-2: var(--space-2);
  --sp-3: var(--space-4);
  --sp-4: var(--space-6);
  --sp-5: var(--space-7);
  --sp-6: var(--space-9);

  /* Radii & container (page chrome is square, as on a drawing sheet) */
  --radius-sm: 1px;
  --radius-md: 0;
  --radius-lg: 14px;
  --container: 1440px;

  /* Motion */
  --t-fast: 0.3s ease-in-out;
  --t-med:  0.4s ease;
}

/* ─── 1000 design system layer (namespace tysyacha) ───
   Values from the design system's tokens. Its spacing scale collides with
   the site's --space-* (its space-5 is 24px, ours 20px), so space, stroke and
   radius carry a --ds- prefix; colours and type styles keep their design
   system names, which nothing here uses yet. Only the info panel's grid
   reads this layer. */
:root {
  --ds-space-1: 4px;  --ds-space-2: 8px;  --ds-space-3: 12px;
  --ds-space-4: 16px; --ds-space-5: 24px; --ds-space-6: 32px;
  --ds-space-7: 48px; --ds-space-8: 64px; --ds-space-9: 96px;
  --ds-stroke-main: 1px; --ds-stroke-thin: 0.5px; --ds-radius-0: 0;

  --paper: #ffffff;
  --ink: #191919;
  --pink-300: #f3b6c8;
  --cream-200: #f3e2b6;
  --graphite: #4d4843;
  --blue-900: #0f465c;
  --book-grey: #2b2a28;              /* the scrapbook's dark pages; not a design-system colour */
  --night-text-muted: #a8a092;       /* the design system's night theme */
  --text-muted: var(--graphite);
  --rule: var(--ink);
  --focus: var(--blue-900);

  /* Large type in MFred Heavy, the site's title face, so always in capitals. */
  --text-display: 900 64px/0.95 var(--font-title);
  --text-heading: 900 32px/1.05 var(--font-title);
  --text-body:    400 15px/22px var(--font-mono);
  --text-label:   400 14px/18px var(--font-mono);
  --text-code:    500 13px/16px var(--font-mono);

  --grid-cols: 12;
  --grid-gutter: var(--ds-space-5);
  --grid-row-gap: var(--ds-space-6);
  --grid-margin: var(--ds-space-8);
  --grid-max: 1440px; /* matches the site's existing --container */
}
/* Breakpoints (the design system has none): 1000px and 640px. Native
   @custom-media needs a build step this site doesn't have, so each one is
   written twice: here, and in one block at the end of the info panel rules. */
@media (max-width: 1000px) { :root { --grid-margin: var(--ds-space-6); } }
@media (max-width: 640px)  { :root { --grid-margin: var(--ds-space-4); } }

@media (max-width: 767px) {
  :root {
    --t-jumbo: 4.5rem;    /* 72 */
    --t-h1:    2.25rem;   /* 36 */
    --t-h4:    1.5rem;    /* 24 */
    --t-h5:    1.25rem;   /* 20 */
    --t-h6:    1.125rem;  /* 18 */
    --t-lead:  1.125rem;  /* 18 */
    --gap-tag:     var(--space-4);   /* 16 */
    --gap-card:    var(--space-6);   /* 24 */
    --gap-section: var(--space-8);   /* 40 */
    --gap-hero:    var(--space-9);   /* 48 */
  }
}

/* ─── Reset ─── */
*, *::before, *::after { box-sizing: border-box; }
html, body, figure, figcaption { margin: 0; padding: 0; }
img, svg { display: block; max-width: 100%; height: auto; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; margin: 0; padding: 0; }

:where(a, button):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ─── Page shell ─── */
body.site {
  min-height: 100vh;
  height: 100vh;
  overflow: hidden;
  background: #ffffff;
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--fs-body);
  line-height: calc(var(--t-body) + var(--lead));
  letter-spacing: var(--track-body);
  -webkit-font-smoothing: antialiased;
}

/* ─── Loading screen ─── */
.loading-screen {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: grid;
  place-items: center;
  background: var(--bg);
  color: var(--text);
  transition: opacity 0.5s ease, visibility 0.5s;
  padding: var(--sp-5);
}
.loading-screen.dismissed {
  opacity: 0;
  visibility: hidden;
}
.loading-screen-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-5);
}
.logo-wrapper {
  text-align: center;
  color: var(--text);
}
/* The name, lowercase Cyrillic, in ink on pink: one per spread. */
/* MFred has no Cyrillic, so the wordmark keeps the display face. */
.wordmark {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--t-jumbo);
  line-height: calc(var(--t-jumbo) + var(--lead));
  font-weight: 100;
  letter-spacing: var(--track-display);
}
/* The title, "distance travelled", in MFred Heavy. */
.wordmark-sub {
  margin: var(--gap-tag) 0 0;
  font-family: var(--font-title);
  font-size: var(--t-h5);
  font-weight: 900;
  line-height: calc(var(--t-h5) + var(--lead));
  letter-spacing: var(--track-heading);
  text-transform: uppercase;
}
.wordmark-meta {
  margin: var(--sp-3) 0 0;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  line-height: calc(var(--t-small) + var(--lead));
  letter-spacing: var(--track-small);
  color: var(--muted);
}
.enter-button {
  padding: var(--sp-2) var(--sp-4);
  min-height: 44px;
  border-radius: var(--radius-sm);
}
.enter-text {
  font-family: var(--font-mono);
  font-size: var(--fs-enter);
  line-height: calc(var(--t-small) + var(--lead));
  letter-spacing: var(--track-small);
  color: var(--text);
}
/* Underline, not fade: a faded label would drop below AA contrast. */
.enter-button:hover .enter-text,
.enter-button:focus-visible .enter-text {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
}

/* ─── Gallery: one frame at a time ─── */
.gallery {
  position: fixed;
  inset: 0;
  overflow: hidden;
  cursor: pointer;
  background: #ffffff;
  touch-action: pan-y;           /* horizontal swipes go to the carousel */
  --wipe: 1.1s;
  --wipe-ease: cubic-bezier(0.77, 0, 0.175, 1);
}
/* Each frame waits clipped to nothing, just to the right ("after") or left
   ("before") of centre. The current frame wipes open from the side it comes
   from and settles; the frame it replaces is pushed the other way and
   clipped in step, so it shows only where the new frame hasn't reached. */
.image-container {
  position: absolute;
  top: 50%;
  left: 50%;
  /* The frames are 35 mm landscape (2000 × 1346). */
  width: min(92vw, calc(68vh * 1000 / 673));
  aspect-ratio: 1000 / 673;
  margin: 0;
  transform: translate(-50%, -50%) translateX(3%);
  clip-path: inset(0 0 0 100%);
  transition:
    clip-path var(--wipe) var(--wipe-ease),
    transform var(--wipe) var(--wipe-ease);
  pointer-events: none;
  z-index: 1;
}
.image-container[data-pos="before"] {
  transform: translate(-50%, -50%) translateX(-3%);
  clip-path: inset(0 100% 0 0);
}
.image-container[data-pos="current"] {
  transform: translate(-50%, -50%);
  clip-path: inset(0);
  z-index: 3;
}
.image-container img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Bar under the frame: step back, caption and count, step on, view all. */
.gallery-bar {
  position: absolute;
  bottom: calc(var(--sp-6) + var(--sp-3));
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  width: max-content;
  max-width: calc(100vw - 1em);
  z-index: 4;
  cursor: default;
}
.project-title { margin: 0; text-align: center; }
.project-title-copy {
  font-family: var(--font-mono);
  font-size: var(--fs-title);
  line-height: calc(var(--t-small) + var(--lead));
  color: var(--text);
  letter-spacing: var(--track-small);
  background: rgba(255,255,255,0.6);
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--radius-sm);
}
.project-count { font-variant-numeric: tabular-nums; color: var(--muted); }
.g-step,
.g-all {
  min-width: 44px;
  min-height: 44px;
  font-family: var(--font-mono);
  color: var(--text);
  transition: color var(--t-med);
}
.g-step { font-size: var(--t-body); }
.g-all {
  margin-left: var(--sp-2);
  padding: 0 var(--sp-2);
  font-size: var(--t-small);
  letter-spacing: var(--track-small);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
}
.g-step:hover,
.g-all:hover { color: var(--accent); }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ─── All frames: the contact sheet behind "view all" ─── */
.all-panel {
  position: fixed;
  inset: 0;
  z-index: 997;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sp-5) var(--sp-4) calc(var(--sp-6) * 2);
  background: #ffffff;
  animation: all-in 0.45s ease both;
}
.all-panel[hidden] { display: none; }
.all-inner { max-width: 1400px; margin: 0 auto; }
.all-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-3);
  padding-bottom: var(--space-3);
  margin-bottom: var(--gap-card);
  border-bottom: 1px solid var(--border);
}
.all-head h2 {
  margin: 0;
  font-family: var(--font-title);
  font-weight: 900;
  font-size: var(--t-h4);
  line-height: calc(var(--t-h4) + var(--lead));
  letter-spacing: var(--track-display);
  text-transform: uppercase;
}
.all-head h2:focus { outline: none; }
.all-count { font-family: var(--font-mono); font-weight: 400; font-size: var(--t-small); letter-spacing: var(--track-small); color: var(--muted); }
.all-close {
  min-height: 44px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--text);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--t-small);
  letter-spacing: var(--track-small);
}
.all-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
  gap: var(--sp-4) var(--sp-3);
}
.all-grid li { animation: thumb-in 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both; animation-delay: calc(var(--i, 0) * 40ms); }
.all-thumb { display: block; width: 100%; text-align: left; cursor: pointer; }
.all-thumb img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1000 / 673;
  object-fit: cover;
  background: #f4f4f4;
  outline: 1px solid transparent;
  outline-offset: 3px;
  transition: opacity var(--t-med), outline-color var(--t-med);
}
.all-thumb:hover img { opacity: 0.82; }
.all-thumb[aria-current="true"] img { outline-color: var(--text); }
.all-num {
  display: block;
  margin-top: var(--sp-1);
  font-family: var(--font-mono);
  font-size: var(--t-small);
  letter-spacing: var(--track-small);
  color: var(--muted);
}
.all-thumb[aria-current="true"] .all-num { color: var(--text); }
@keyframes all-in { from { opacity: 0; } }
@keyframes thumb-in { from { opacity: 0; transform: translateY(12px); } }

/* ─── Navbar ─── */
.navbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 998;
  padding: var(--sp-3) var(--sp-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  background: transparent;
}
.svg-link {
  display: none;                 /* hidden ≤ 991 — matches source */
  color: var(--text);
}
.nav-wordmark {
  font-family: var(--font-display);
  font-size: var(--t-h6);
  font-weight: 100;
  line-height: calc(var(--t-h6) + var(--lead));
  letter-spacing: var(--track-heading);
}
.nav-menu {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  flex: 1;
}
.nav-link {
  font-family: var(--font-mono);
  font-size: var(--fs-link);
  line-height: calc(var(--t-small) + var(--lead));
  letter-spacing: var(--track-small);
  color: var(--text);
  padding: var(--sp-1) var(--sp-2);
  transition: color var(--t-med);
}
.nav-link:hover,
.nav-link:focus-visible,
.nav-link[aria-current="page"] { color: var(--accent); }

/* Over the scrolling info page the nav needs its own ground. */
body:has(.info-panel:not([hidden]), .all-panel:not([hidden])) .navbar {
  background: #fff;
  border-top: 1px solid var(--border);
}

@media (min-width: 992px) {
  .svg-link { display: inline-flex; }
  .nav-menu { flex: 0 0 auto; gap: var(--sp-5); }
}

/* ─── Info panel ─── */
/* Scrolls as a page: a stack of full-width sections. The introduction and
   the spreads sit on paper; the artefacts band is dark grey, full bleed.
   Every value below comes from the design system layer at the top of this
   file. */
.info-panel {
  --plate-gap: calc(var(--ds-space-8) * 2);   /* between pieces down the page */
  position: fixed;
  inset: 0;
  z-index: 997;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--paper);
}
.info-panel[hidden] { display: none; }
.info-panel,
.info-panel *,
.info-panel *::before,
.info-panel *::after { box-sizing: border-box; }
.info-panel :focus-visible {
  outline: calc(var(--ds-stroke-main) * 2) solid var(--focus);
  outline-offset: calc(var(--ds-stroke-main) * 2);
  border-radius: var(--ds-radius-0);
}
.info-panel h2:focus { outline: none; }

/* Sections, one wrap each; every layout row inside a wrap is a .g12. */
.info-section { padding-block: var(--ds-space-7) var(--ds-space-8); }
.info-spreads { padding-bottom: var(--ds-space-9); }   /* the space above the artefacts band */
/* The artefacts band sits on the scrapbook's dark grey, so it takes the
   design system's night values: cream text and rules, a lighter muted
   text and the pink focus ring. */
.info-artefacts {
  --text-muted: var(--night-text-muted);
  --rule: var(--cream-200);
  --focus: var(--pink-300);
  background: var(--book-grey);
  color: var(--cream-200);
  /* space-8 below the foot, and a second space-8 that the fixed nav (65px) covers */
  padding-bottom: calc(var(--ds-space-8) * 2);
}
.info-panel .wrap {
  max-width: var(--grid-max);
  margin-inline: auto;
  padding-inline: var(--grid-margin);
}
/* Dense, so a label that follows its piece in the source (and so on a phone)
   can still hang to the left of it, in the same row. */
.g12 {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  grid-auto-flow: row dense;
  column-gap: var(--grid-gutter);
  row-gap: var(--grid-row-gap);
}
/* Placement: .c-N spans N columns, .s-N starts at column N. */
.g12 > *     { grid-column: auto / span 12; min-width: 0; }
.g12 > .c-3  { grid-column-end: span 3; }
.g12 > .c-4  { grid-column-end: span 4; }
.g12 > .c-5  { grid-column-end: span 5; }
.g12 > .c-6  { grid-column-end: span 6; }
.g12 > .c-9  { grid-column-end: span 9; }
.g12 > .s-4  { grid-column-start: 4; }
.g12 > .s-7  { grid-column-start: 7; }
.g12 > .s-10 { grid-column-start: 10; }

/* Section opener: kicker on columns 1–3, heading on 4–12, under one rule. */
.ip-open {
  margin-bottom: var(--ds-space-7);
  padding-top: var(--ds-space-3);
  border-top: var(--ds-stroke-main) solid var(--rule);
}
.ip-kicker { margin: 0; font: var(--text-code); color: var(--text-muted); }
.ip-heading {
  margin: 0;
  font: var(--text-display);
  letter-spacing: var(--track-display);
  text-transform: uppercase;
}

/* Introduction: the text on columns 4–9, the facts as a label on 10–12. */
.info-text p { max-width: 42rem; margin: 0 0 var(--ds-space-4); }
.info-panel .info-lead {
  font-size: var(--t-lead);
  line-height: calc(var(--t-lead) + var(--lead));
  letter-spacing: var(--track-lead);
}
.info-facts {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-4);
  margin: 0;
}
.info-facts dt { font: var(--text-code); color: var(--text-muted); }
.info-facts dd { margin: var(--ds-space-1) 0 0; font: var(--text-label); }

/* Plates: each piece hangs on the grid with a wall label at its foot, the
   label's side alternating down the page. */
.ip-plate { margin-top: var(--plate-gap); }
.ip-label {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  align-self: end;
  gap: var(--ds-space-3);
}
.ip-title {
  margin: 0;
  font: var(--text-heading);
  letter-spacing: var(--track-heading);
  text-transform: uppercase;
}
.ip-cap,
.ip-note { margin: 0; font: var(--text-body); }
.ip-cap { margin-top: var(--ds-space-3); }
.ip-btn,
.sp-row { min-height: calc(var(--ds-space-6) + var(--ds-space-3)); }   /* 44px touch target */
.ip-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--ds-space-2) var(--ds-space-4);
  border: var(--ds-stroke-main) solid var(--rule);
  border-radius: var(--ds-radius-0);
  background: var(--paper);
  color: var(--ink);
  font: var(--text-code);
}
.ip-btn:hover { background: var(--ink); color: var(--cream-200); }

/* Spreads: the stage on columns 1–9 with its label on 10–12, and the
   contents beneath the stage. */
.sp-frame {
  margin: 0;
  aspect-ratio: 2400 / 1492;
  border: var(--ds-stroke-thin) solid var(--rule);
  background: var(--paper);
}
.sp-frame img { display: block; width: 100%; height: 100%; object-fit: contain; }
.sp-steps { display: flex; gap: var(--ds-space-2); }
.sp-step {
  min-width: calc(var(--ds-space-6) + var(--ds-space-3));
  padding-inline: var(--ds-space-3);
}
.sp-rows {
  columns: 14rem 3;
  column-gap: var(--grid-gutter);
  margin: var(--ds-space-3) 0 0;
  padding: 0;
  list-style: none;
}
.sp-rows li { break-inside: avoid; }
.sp-row {
  display: flex;
  align-items: center;
  gap: var(--ds-space-3);
  width: 100%;
  font: var(--text-code);
  color: var(--text-muted);
  text-align: left;
}
.sp-row:hover,
.sp-row[aria-current="true"] { color: var(--ink); }
.sp-row[aria-current="true"] .sp-t {
  text-decoration: underline var(--ds-stroke-main);
  text-underline-offset: 0.3em;
}
.sp-n { flex: none; min-width: 2ch; }
.sp-x { margin-left: auto; white-space: nowrap; }

/* Artefacts · anatomy: two sheets at equal height (2700 and 1170 wide on
   the same 1938 height). */
.an-sheets {
  display: grid;
  grid-template-columns: 2700fr 1170fr;
  gap: var(--ds-space-2);
  margin: 0;
}
.an-sheets img { width: 100%; height: auto; background: var(--ink); }
.an-sheets img:first-child { aspect-ratio: 2400 / 1722; }
.an-sheets img:last-child  { aspect-ratio: 1040 / 1722; }

/* Pages: a 4:5 picture under its vertical head. */
.ip-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin: 0;
}
/* Vertical page head, read bottom to top. Turned half round, so its
   padding-top is the space between the word and the picture beneath.
   The negative margin takes off the line box above MFred's cap height
   (ascent less cap height, less half the negative leading at 0.95), so
   the capitals' tops sit on the page's left edge. */
.ip-vhead {
  align-self: end;
  justify-self: start;
  margin: 0 0 0 -0.11em;
  padding-top: var(--ds-space-3);
  font: var(--text-display);
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
}
.ip-media { align-self: start; min-height: 0; aspect-ratio: 4 / 5; background: var(--paper); }
.ip-media > * { width: 100%; height: 100%; object-fit: contain; }
.ip-media > video,
.ip-reel video { background: var(--ink); }

/* Artefacts · time as shape: three pages in a row, the middle one hung
   lower. Each page is a subgrid of three rows (head, picture, caption), so
   heads of different lengths still sit on one line and the pictures align. */
.ip-trio {
  --drop: calc(var(--ds-space-9) * 2);
  row-gap: 0;
  margin-top: var(--ds-space-6);
  padding-bottom: var(--drop);
}
.ip-trio > .ip-page { grid-row: span 3; grid-template-rows: subgrid; }
.ip-trio > .ip-page:nth-child(2) { translate: 0 var(--drop); }

/* Artefacts · instagram: three reels on columns 1–9, each a page of three
   columns and two gutters. */
.rl-reels {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--grid-gutter);
}
.ip-reel { margin: 0; }
.ip-reel video { width: 100%; height: auto; aspect-ratio: 4 / 5; }

/* Foot: closes the panel. */
.ip-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--ds-space-4);
  margin-top: var(--plate-gap);
  padding-top: var(--ds-space-4);
  border-top: var(--ds-stroke-main) solid var(--rule);
  font: var(--text-code);
}

/* The two grid breakpoints (see the design system layer at the top). Below
   1000px every piece takes the full width with its label beneath. */
@media (max-width: 1000px) {
  .g12 > :is(.c-3, .c-5, .c-6, .c-9) { grid-column: 1 / -1; }
  .ip-label { align-self: start; }
  .ip-plate > .ip-page { max-width: 30rem; }
  .ip-trio { --drop: var(--ds-space-9); }
}
@media (max-width: 640px) {
  .ip-trio,
  .rl-reels {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 76%;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: var(--ds-space-3);
  }
  .ip-trio > .ip-page,
  .rl-reels > .ip-reel { grid-column: auto; scroll-snap-align: start; }
  .ip-trio > .ip-page:nth-child(2) { translate: none; }
}

/* ─── Mobile tweaks ─── */
@media (max-width: 991px) {
  .svg-link { display: none; }
  .nav-menu {
    width: 100%;
    justify-content: space-between;
  }
}
@media (max-width: 767px) {
  .image-container { width: 92vw; }
  .project-name { display: none; }   /* the count, steps and view all fit on a phone */
}
@media (max-width: 479px) {
  .navbar { padding: var(--sp-2) var(--sp-3); }
}

/* Prevent horizontal scroll at 320px */
html, body { overflow-x: hidden; }

/* ─── Reduced motion ─── */
@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ─── Editor-driven states ─── */
body.editor-on [data-editable] {
  outline: 1px dashed transparent;
  transition: outline-color 0.2s;
}
body.editor-on [data-editable]:hover {
  outline-color: var(--accent);
}
body.editor-on [data-editable]:focus {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  background: rgba(255,255,255,0.4);
}

body.editor-on .image-container { pointer-events: auto; }
body.editor-on .image-container:hover {
  outline: 2px dashed var(--accent);
  outline-offset: -4px;
}

/* Box-model inspector overlay */
body.inspect-on *:not(.editor-root, .editor-root *) {
  outline: 1px solid rgba(145,13,13,0.25) !important;
}
body.inspect-on *:not(.editor-root, .editor-root *):hover {
  outline: 2px solid var(--accent) !important;
  box-shadow: inset 0 0 0 999px rgba(145,13,13,0.08) !important;
}

/* Viewport preview frame */
body.preview-on {
  overflow: auto !important;
  background: #1a1a1a;
  display: grid;
  place-items: center;
}
body.preview-on > :not(.editor-root) {
  /* NB: positions are rewritten by JS inside #viewport-frame; this is a no-op fallback */
}
.viewport-frame {
  position: fixed;
  inset: 0;
  background: #1a1a1a;
  display: grid;
  place-items: start center;
  padding: var(--sp-5) 0;
  overflow: auto;
  z-index: 500;
}
.viewport-frame > iframe {
  border: 8px solid #000;
  border-radius: var(--radius-lg);
  background: #fff;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}

/* ─────────────────────────────────────────────────────────────
 * Editor UI
 * ───────────────────────────────────────────────────────────── */
.editor-root {
  position: fixed;
  right: var(--sp-3);
  /* Sit above the fixed navbar so it never covers the nav links */
  bottom: calc(var(--sp-3) + 60px);
  z-index: 10000;
  font-family: var(--font-sans);
  font-size: 14px;
  color: #111;
}
@media (max-width: 991px) {
  /* Below the desktop breakpoint, move the toolbar to the TOP-right so it
     doesn't fight for room with the fixed navbar and the caption at the
     bottom of the gallery. */
  .editor-root {
    bottom: auto;
    top: var(--sp-2);
    right: var(--sp-2);
  }
  .editor-toolbar { max-width: calc(100vw - 1em); gap: 4px; padding: 6px; }
  .editor-btn { padding: 6px 8px; font-size: 12px; min-height: 32px; }
  .editor-panel { max-width: calc(100vw - 1em); }
}
.editor-root * { box-sizing: border-box; }

.editor-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  background: #ffffffee;
  backdrop-filter: blur(10px);
  padding: 8px;
  border-radius: var(--radius-lg);
  box-shadow: 0 10px 30px rgba(0,0,0,0.2), 0 0 0 1px rgba(0,0,0,0.06);
  max-width: 360px;
}
.editor-btn {
  padding: 8px 12px;
  background: #fff;
  border: 1px solid #d8d8d8;
  border-radius: var(--radius-md);
  color: #111;
  font-size: 13px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  min-width: 36px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.editor-btn:hover { background: #f3f3f3; }
.editor-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.editor-btn[aria-pressed="true"] {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}

.editor-panel {
  margin-top: 8px;
  background: #ffffffee;
  backdrop-filter: blur(10px);
  border-radius: var(--radius-lg);
  box-shadow: 0 10px 30px rgba(0,0,0,0.2), 0 0 0 1px rgba(0,0,0,0.06);
  padding: 12px;
  max-width: 360px;
  max-height: 70vh;
  overflow: auto;
}
.editor-panel[hidden] { display: none; }
.editor-panel h3 {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #555;
}
.editor-row {
  display: grid;
  grid-template-columns: 80px 1fr auto;
  align-items: center;
  gap: 8px;
  margin: 6px 0;
}
.editor-row label { font-size: 12px; color: #333; }
.editor-row input[type="color"] {
  inline-size: 100%;
  block-size: 28px;
  padding: 0;
  border: 1px solid #ccc;
  border-radius: 6px;
  background: #fff;
}
.editor-swatch {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid #ccc;
}
.editor-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 8px 0;
}
.editor-preset {
  padding: 6px 10px;
  background: #fff;
  border: 1px solid #d8d8d8;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 12px;
  min-height: 32px;
}
.editor-preset:hover { background: #f3f3f3; }

.editor-warning {
  margin-top: 8px;
  padding: 8px 10px;
  background: #fff3cd;
  border: 1px solid #ffe08a;
  border-radius: var(--radius-sm);
  color: #7a5600;
  font-size: 12px;
}
.editor-warning[hidden] { display: none; }

.editor-image-ui {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  gap: 4px;
  background: #ffffffea;
  padding: 4px;
  border-radius: var(--radius-sm);
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
}
body.editor-on .image-container:hover .editor-image-ui,
body.editor-on .image-container:focus-within .editor-image-ui {
  opacity: 1;
  pointer-events: auto;
}

.editor-breakpoint-label {
  position: fixed;
  top: 10px;
  left: 10px;
  background: #000;
  color: #fff;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12px;
  z-index: 10001;
  pointer-events: none;
}
.editor-breakpoint-label[hidden] { display: none; }

.editor-dropzone {
  position: absolute;
  inset: 0;
  background: color-mix(in oklab, var(--accent) 20%, transparent);
  border: 3px dashed var(--accent);
  display: grid;
  place-items: center;
  font-family: var(--font-sans);
  color: #fff;
  font-size: 16px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
  z-index: 20;
}
.image-container.dragover .editor-dropzone { opacity: 1; }
