/* Design of Man — theme layer over scrollcraft.css.
   Six colour roles and two faces. Everything below the token block is this
   page's own markup; nothing here restyles .sc-stage, .sc-copy or a
   [data-sc-*] selector, because those are the engine's mechanism. */

:root {
  /* Cold silver on off-black with one warm ember. The cream/brass palette the
     old build used is the exact combination that makes every craft studio look
     like the same studio. */
  --sc-canvas:     #0b0c0e;
  --sc-surface:    #14161a;
  --sc-ink:        #edeff2;
  --sc-ink-soft:   #99a0aa;
  --sc-accent:     #e5763d;
  --sc-accent-ink: #0b0c0e;

  --sc-font-display: "Instrument Serif", Georgia, serif;
  --sc-font-text:    "DM Sans", system-ui, sans-serif;

  --sc-measure: 46ch; /* Corrected for DM Sans: its "0" glyph (the ch unit basis) is ~1.47x its
     average lowercase-letter width, so a naive 64ch here rendered lines at
     ~94 real characters -- far past the 75ch ceiling. 46ch targets ~68 real
     characters, the readable band. */

  /* The bezel the site is trapped inside from the peak onward. */
  --frame: clamp(10px, 1.6vw, 22px);

  /* The fixed header's own height. `/` scrolls the film behind it, but an
     interior page has to reserve the space or the h1 starts underneath it. */
  --bar-h: 4.5rem;
}

/* Instrument Serif has no bold, so weight cannot carry hierarchy here; size
   and tracking do. Its cap height also runs tall, hence the tighter leading. */
.sc-display { font-weight: 400; line-height: 0.98; }
.sc-display em { font-style: italic; color: var(--sc-accent); }

.skip-link {
  position: absolute; left: var(--sc-4); top: var(--sc-4); z-index: 200;
  padding: var(--sc-2) var(--sc-4); background: var(--sc-accent);
  color: var(--sc-accent-ink); border-radius: var(--sc-r-sm);
  transform: translateY(-160%); transition: transform var(--sc-d-base) var(--sc-ease-out);
}
.skip-link:focus-visible { transform: none; }

/* ------------------------------------------------------------- chrome -- */
.bar {
  position: fixed; inset: 0 0 auto; z-index: var(--sc-z-chrome);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sc-5);
  padding: var(--sc-4) max(var(--sc-gutter), calc(var(--frame) + var(--sc-4)));
}
/* The bar sits over the film, over the peak and over body copy in turn. A
   blend mode cannot serve all three, and heading-over-nav is unreadable, so
   the chrome carries its own ground. */
.bar::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(to bottom,
    color-mix(in oklab, var(--sc-canvas) 86%, transparent) 0%,
    color-mix(in oklab, var(--sc-canvas) 58%, transparent) 52%,
    transparent 100%);
}
.bar a { text-decoration: none; }
.mark { display: inline-flex; align-items: center; gap: var(--sc-3);
  font-family: var(--sc-font-display); font-size: var(--sc-t-lg); letter-spacing: var(--sc-track-snug); }
.mark svg { width: 46px; height: auto; }
.bar nav { display: flex; gap: var(--sc-4); font-size: var(--sc-t-sm); }
/* WCAG 2.2 SC 2.5.8: every target at least 24x24. These measured 19-23px tall,
   which is the kind of miss that only shows up on a phone. Padding buys the
   height without moving the type, and the negative margin keeps the optical
   alignment of the bar unchanged. */
.bar nav a, .foot nav a {
  color: var(--sc-ink-soft);
  display: inline-flex; align-items: center;
  min-height: 24px; padding-inline: var(--sc-2); margin-inline: calc(var(--sc-2) * -1);
}
.mark { min-height: 24px; }
.bar nav a[aria-current], .bar nav a:hover, .foot nav a:hover { color: var(--sc-ink); }
@media (max-width: 640px) {
  .bar { padding-inline: var(--sc-4); gap: var(--sc-3); }
  .bar nav { gap: var(--sc-2); }
  /* The wordmark wraps to two lines under ~430px and collides with the links.
     The glyph alone carries it at that size. */
  .bar .mark span { display: none; }
}

/* ------------------------------------------------------ act 1+2 · film -- */
/* The engine's --lead scrim is tuned for display type. This page puts body
   copy in the same corner over a snow-bright plate, which measures 3.3:1, so
   the density is pushed down and further up the frame to cover the paragraph
   too. Page-owned element, not an override of .sc-scrim. */
.film__scrim {
  position: absolute; inset: 0; z-index: 10; pointer-events: none;
  /* Two shapes, both chosen against where things actually are in frame.
     The copy sits bottom-left and runs to about mid-width; in the close shot the
     laptop occupies y 27%-71% and is centred. So: a band across the bottom that
     stops below the machine, plus an ellipse in the copy's own corner for the
     display line above the band. Kept OUT of the copy element -- a pad inside
     the cue fades with the text while the plate behind it does not, which
     measured 1.27:1 at the worst frame. */
  background:
    radial-gradient(ellipse 108% 92% at -12% 108%,
      color-mix(in oklab, var(--sc-canvas) 98%, transparent) 0%,
      color-mix(in oklab, var(--sc-canvas) 95%, transparent) 40%,
      color-mix(in oklab, var(--sc-canvas) 92%, transparent) 60%,
      color-mix(in oklab, var(--sc-canvas) 66%, transparent) 78%,
      color-mix(in oklab, var(--sc-canvas) 14%, transparent) 90%,
      transparent 100%),
    linear-gradient(to top,
      color-mix(in oklab, var(--sc-canvas) 95%, transparent) 0%,
      color-mix(in oklab, var(--sc-canvas) 82%, transparent) 15%,
      color-mix(in oklab, var(--sc-canvas) 44%, transparent) 27%,
      transparent 38%);
}

/* On a narrow viewport the engine spans the copy the full width, so a
   corner-weighted scrim leaves the right-hand end of every line over open
   plate -- it measured 2.26:1 there. Below 860px the density goes full width
   instead. The laptop is not in frame while these two cues are up, so this
   costs the shot nothing. */
@media (max-width: 860px) {
  .film__scrim {
    background: linear-gradient(to top,
      color-mix(in oklab, var(--sc-canvas) 97%, transparent) 0%,
      color-mix(in oklab, var(--sc-canvas) 90%, transparent) 26%,
      color-mix(in oklab, var(--sc-canvas) 62%, transparent) 44%,
      color-mix(in oklab, var(--sc-canvas) 22%, transparent) 60%,
      transparent 74%);
  }
}

.film .sc-copy {
  max-width: min(46rem, 82vw);
  /* Type over moving media cannot rely on a scrim alone: the plate swings from
     wet black rock to a red tunic to blown-out sky underneath the same word.
     The accent italic measured 2.41:1 against the tunic. A shadow travels with
     the glyphs, so it holds the ratio wherever the footage puts them. */
  text-shadow: 0 1px 2px color-mix(in oklab, var(--sc-canvas) 62%, transparent),
               0 3px 22px color-mix(in oklab, var(--sc-canvas) 72%, transparent);
}
.film h1, .film .beat { margin: 0 0 var(--sc-4); }
.film p { color: var(--sc-ink); max-width: 42ch; }

/* --------------------------------------------------- act 3 · the glass --
   The peak. A fixed layer, not an act stage: the still it opens on is the
   film's own last frame, so it can cover the moment the scrub act's sticky
   stage unsticks and slides away. Without it the payoff has a seam in it. */
.glass {
  position: fixed; inset: 0; z-index: 40;
  opacity: 0; visibility: hidden; pointer-events: none;
  background: var(--sc-canvas);
}
.glass.is-live { opacity: 1; visibility: visible; }
.glass { overflow: hidden; }
.glass__still { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; will-change: transform; }

/* The payoff layer. Nothing is drawn on the laptop while the film runs -- the
   white screen is the footage's own. This sits over the push-in and carries the
   two things that happen once the screen has swallowed the viewport: the mark,
   then the site.

   --mark : 0 -> 1  the wordmark comes up on the white
   --boot : 0 -> 1  the white gives way to the site */
.panel {
  position: absolute; inset: 0;
  overflow: hidden;
  display: grid; place-items: center;
  --mark: 0; --boot: 0;
  /* Transparent while the white screen behind it is doing the work; the site's
     own ground arrives only at boot. */
  background: color-mix(in srgb, var(--sc-canvas) calc(var(--boot) * 100%), transparent);
}

/* The mark, on the white. Wide tracking and a pair of hairlines: the closest
   this typeface gets to something struck rather than printed. */
.panel__boot {
  position: absolute; inset: 0; z-index: 2;
  display: grid; place-content: center; justify-items: center;
  gap: clamp(0.9rem, 2.4vmin, 1.8rem);
  color: #14161a;
  opacity: calc(var(--mark) * (1 - clamp(0, var(--boot) / 0.45, 1)));
}
.panel__mark { width: clamp(96px, 14vmin, 210px); height: auto; stroke: currentColor; }
.panel__word {
  font-family: var(--sc-font-display);
  font-size: clamp(1.15rem, 3.1vmin, 2.1rem);
  letter-spacing: 0.58em; text-transform: uppercase;
  padding-left: 0.58em; color: #14161a; white-space: nowrap;
}
/* The runic divider, which is also the loading bar. The three glyphs sit at a
   faint 0.18 from the first frame so the thing reads as a rule with a mark in
   it, then each ignites in turn as --mark crosses its third. One element doing
   both jobs beats a divider with a progress bar underneath it. */
.panel__rune { display: block; width: clamp(150px, 26vmin, 340px); height: auto; }
.panel__rule { opacity: 0.26; }
.panel__rune g { opacity: calc(0.18 + 0.82 * var(--lit, 0)); }
.panel__rune g:nth-of-type(1) { --lit: clamp(0, var(--mark) / 0.34, 1); }
.panel__rune g:nth-of-type(2) { --lit: clamp(0, (var(--mark) - 0.33) / 0.34, 1); }
.panel__rune g:nth-of-type(3) { --lit: clamp(0, (var(--mark) - 0.66) / 0.34, 1); }
/* The last one to light is the one that carries the accent, so the sequence
   finishes on the brand colour rather than on more grey. */
.panel__rune g:nth-of-type(3) { stroke: color-mix(in oklab, var(--sc-accent) calc(var(--lit) * 100%), currentColor); }

.panel__inner {
  position: relative; z-index: 3;
  padding: clamp(1.5rem, 6vmin, 5rem); text-align: center;
  display: grid; gap: clamp(0.75rem, 2.2vmin, 1.75rem); justify-items: center;
  max-width: 100vw;
  opacity: clamp(0, (var(--boot) - 0.5) / 0.5, 1);
}
.panel__inner h2 { font-family: var(--sc-font-display); font-weight: 400;
  font-size: var(--sc-t-3xl); line-height: 0.98; letter-spacing: var(--sc-track-tight);
  margin: 0; text-wrap: balance; }
.panel__inner h2 em { font-style: italic; color: var(--sc-accent); }
.panel__inner p { margin: 0; color: var(--sc-ink-soft); max-width: 46ch;
  font-size: var(--sc-t-base); }

/* The frame that never breaks: once the site has taken the screen, a hairline
   of the machine stays at the viewport edge for the rest of the page. */
.bezel {
  position: fixed; inset: 0; z-index: 50; pointer-events: none;
  opacity: 0;
  border: var(--frame) solid #060708;
  box-shadow:
    inset 0 0 0 1px color-mix(in oklab, var(--sc-ink) 34%, transparent),
    inset 0 0 0 calc(var(--frame) + 1px) #060708,
    inset 0 0 0 calc(var(--frame) + 2px) color-mix(in oklab, var(--sc-ink) 10%, transparent),
    inset 0 0 90px -26px #000;
}

/* -------------------------------------------------- act 4 · what we do -- */
/* No lead-in padding: act 4 follows the peak's exit slide, which is already a
   viewport of dark. Padding on top of that turns a breath into a hole. */
.work { padding-block: var(--sc-5) var(--sc-section); }
.work h2 { margin: 0 0 var(--sc-8); }
.row {
  display: grid; grid-template-columns: 1fr auto; gap: var(--sc-3) var(--sc-6);
  align-items: baseline;
  padding: var(--sc-6) 0; border-top: 1px solid var(--sc-hairline);
}
.row:last-child { border-bottom: 1px solid var(--sc-hairline); }
.row h3 { margin: 0 0 var(--sc-2); font-family: var(--sc-font-display);
  font-weight: 400; font-size: var(--sc-t-xl); letter-spacing: var(--sc-track-snug); }
.row p { margin: 0; color: var(--sc-ink-soft); max-width: 40ch; } /* same DM Sans ch-inflation correction */
.row .tag { color: var(--sc-ink-soft); font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase; white-space: nowrap; }
@media (max-width: 640px) { .row { grid-template-columns: 1fr; } }

/* ------------------------------------------------ act 5 · the one action -- */
.close { display: grid; place-items: center; text-align: center;
  padding: var(--sc-gutter); }
.close__inner { display: grid; gap: var(--sc-6); justify-items: center; }
.close .sc-body { color: var(--sc-ink); max-width: 40ch; margin-inline: auto; }
.foot {
  position: absolute; inset: auto 0 0; padding: var(--sc-5) var(--sc-gutter);
  display: flex; flex-wrap: wrap; gap: var(--sc-4);
  align-items: center; justify-content: space-between;
  font-size: var(--sc-t-xs); color: var(--sc-ink-soft);
}
.foot nav { display: flex; gap: var(--sc-4); }

/* Act 5 pulls back out of the machine: the moor returns behind the close as
   the bezel retreats, so the page resolves by leaving rather than fading. */
 /* No position on .close: the engine sticks the stage with position:sticky and
   a `position: relative` here silently beats it, un-pinning the whole act.
   Sticky is already a containing block for the absolute children below. */
.close::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  /* The engine owns .close::after (data-sc-spotlight), so the scrim rides in
     this element's own background stack rather than a second pseudo. */
  background-image:
    linear-gradient(color-mix(in oklab, var(--sc-canvas) 88%, transparent),
                    color-mix(in oklab, var(--sc-canvas) 88%, transparent)),
    var(--moor-src);
  background-size: cover, cover;
  background-position: center, center;
  opacity: var(--moor, 0);
}


/* ══════════════════════════════════════════════════ THE SITE ══════════════
   Everything the film delivers you into. Same tokens as the gateway, so the
   boot resolves onto this ground with no second transition. */

.band { padding-block: clamp(4rem, 11vh, 9rem); }
.band--alt { background: var(--sc-surface); }
.band > .sc-wrap > h2 { margin: 0 0 var(--sc-6); }
.sc-wrap.narrow { max-width: 62rem; }
.lede { display: grid; gap: var(--sc-4); margin-bottom: var(--sc-8); }
.lede .sc-body, p.lede { max-width: 44ch; } /* same DM Sans ch-inflation correction as --sc-measure */
.note { margin-top: var(--sc-6); color: var(--sc-ink-soft); }

/* Cards are a grid of statements, not boxes with borders on every side. One
   hairline on top is enough to group them and keeps the page quiet. */
.cards { display: grid; gap: var(--sc-5); grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }
.cards.two   { grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr)); }
.cards.three { grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); }
.card { border-top: 1px solid var(--sc-hairline); padding-top: var(--sc-5); }
.card h3 { margin: 0 0 var(--sc-3); font-family: var(--sc-font-display);
  font-weight: 400; font-size: var(--sc-t-xl); letter-spacing: var(--sc-track-snug); }
.card p { margin: 0; color: var(--sc-ink-soft); max-width: 46ch; }

/* Numbered stages. The rule runs down the numerals so the sequence reads as
   one movement rather than five unrelated cards. */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.steps li { display: grid; grid-template-columns: auto 1fr; gap: var(--sc-5);
  padding: var(--sc-5) 0; border-top: 1px solid var(--sc-hairline); }
.steps li:last-child { border-bottom: 1px solid var(--sc-hairline); }
.step__n { font-family: var(--sc-font-display); font-size: var(--sc-t-lg);
  color: var(--sc-accent); line-height: 1; }
.steps h3 { margin: 0 0 var(--sc-2); font-family: var(--sc-font-display);
  font-weight: 400; font-size: var(--sc-t-xl); letter-spacing: var(--sc-track-snug); }
.steps p { margin: 0; color: var(--sc-ink-soft); max-width: 40ch; } /* same DM Sans ch-inflation correction */

.plans { align-items: start; }
.plan { display: grid; gap: var(--sc-4); }
.plan--lead { border-top-color: var(--sc-accent); }
.plan ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sc-2);
  color: var(--sc-ink-soft); font-size: var(--sc-t-sm); }
.plan li { padding-left: var(--sc-4); position: relative; }
.plan li::before { content: ""; position: absolute; left: 0; top: 0.62em;
  width: 6px; height: 1px; background: var(--sc-accent); }
.plan .btn { justify-self: start; }

.quote { font-style: normal; }
.quote p { color: var(--sc-ink); font-family: var(--sc-font-display);
  font-size: var(--sc-t-lg); line-height: 1.34; letter-spacing: var(--sc-track-snug); max-width: none; }

/* Native disclosure: keyboard, screen-reader and find-in-page all work without
   a line of script. */
.qa { border-top: 1px solid var(--sc-hairline); }
.qa:last-of-type { border-bottom: 1px solid var(--sc-hairline); }
.qa summary { cursor: pointer; list-style: none; padding: var(--sc-5) var(--sc-6) var(--sc-5) 0;
  position: relative; font-family: var(--sc-font-display); font-size: var(--sc-t-lg);
  letter-spacing: var(--sc-track-snug); min-height: 24px; }
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after { content: ""; position: absolute; right: 0; top: 50%;
  width: 11px; height: 11px; margin-top: -6px;
  border-right: 1px solid var(--sc-ink-soft); border-bottom: 1px solid var(--sc-ink-soft);
  transform: rotate(45deg); transition: transform .28s var(--sc-ease-out); }
.qa[open] summary::after { transform: rotate(-135deg); }
.qa p { margin: 0 0 var(--sc-5); color: var(--sc-ink-soft); max-width: 46ch; } /* same DM Sans ch-inflation correction */

.form { display: grid; gap: var(--sc-4); max-width: 40rem; }
.field { display: grid; gap: var(--sc-2); }
.field label { font-size: var(--sc-t-sm); color: var(--sc-ink-soft); }
.field .opt { opacity: .6; }
.field input, .field select, .field textarea {
  font: inherit; color: var(--sc-ink); background: var(--sc-canvas);
  border: 1px solid var(--sc-hairline); border-radius: 2px;
  padding: 0.8rem 0.9rem; min-height: 44px; width: 100%;
}
.field textarea { min-height: 8rem; resize: vertical; }
.field :is(input, select, textarea):focus-visible {
  outline: 2px solid var(--sc-accent); outline-offset: 2px; border-color: transparent; }
.form__note { margin: 0; font-size: var(--sc-t-sm); color: var(--sc-ink-soft); max-width: var(--sc-measure); } /* was uncapped: ran to ~88 real chars, bounded only by .form's width */
.form__note a { color: var(--sc-ink); }

/* The one button. It was never defined -- .btn--quiet modified a class that did
   not exist -- so every CTA on the page rendered as plain text or a default
   browser button. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--sc-2);
  font: inherit; font-size: var(--sc-t-sm); letter-spacing: var(--sc-track-wide);
  text-transform: uppercase; text-decoration: none; cursor: pointer;
  color: var(--sc-accent-ink); background: var(--sc-accent);
  border: 0; border-radius: 2px;
  padding: 0.85rem 1.6rem; min-height: 44px;
  transition: background 220ms var(--sc-ease-out), color 220ms var(--sc-ease-out);
}
.btn:hover { background: color-mix(in oklab, var(--sc-accent) 84%, white); }
.btn:focus-visible { outline: 2px solid var(--sc-ink); outline-offset: 3px; }
.btn--quiet { background: transparent; color: var(--sc-ink);
  box-shadow: inset 0 0 0 1px var(--sc-hairline-strong); }
.btn--quiet:hover { background: color-mix(in oklab, var(--sc-ink) 8%, transparent); }
/* A grid child stretches to the column by default, which turned the form's
   submit into a full-width slab. */
.form .btn { justify-self: start; }

@media (max-width: 640px) {
  .steps li { grid-template-columns: 1fr; gap: var(--sc-2); }
  .band { padding-block: clamp(3rem, 8vh, 5rem); }
}

/* ─────────────────────────────────────────────────────── interior pages ──
   Everything below serves the pages that are NOT the film. They share the
   header, the footer and the token set with `/`, and load the same engine,
   but they declare no [data-sc-act], so scrollcraft only runs its reveal
   observer over them. No page owns a second palette or a third font. */

/* The header is fixed over the film on `/`, where the moor scrolls behind it.
   On a document page there is nothing behind it, so it needs its own ground
   and the content below needs to clear it. */
.has-bar .bar { background: color-mix(in srgb, var(--sc-canvas) 88%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.has-bar main { padding-top: var(--bar-h); }

/* PAGE HERO. One statement, one paragraph, nothing else. The rule underneath
   is the only ornament, and it doubles as the seam to the first band. */
.phero { padding-block: clamp(4.5rem, 14vh, 10rem) clamp(3rem, 8vh, 6rem);
  border-bottom: 1px solid var(--sc-hairline); }
.phero h1 { margin: 0 0 var(--sc-6); max-width: 18ch; }
.phero .sc-body { font-size: var(--sc-t-lg); color: var(--sc-ink); max-width: 38ch; } /* same DM Sans ch-inflation correction; larger --sc-t-lg type reads well slightly tighter too */
.phero__meta { display: flex; flex-wrap: wrap; gap: var(--sc-3) var(--sc-5);
  margin-top: var(--sc-7); font-size: var(--sc-t-sm); color: var(--sc-ink-soft);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase; }
.phero__cta { display: flex; flex-wrap: wrap; gap: var(--sc-4); margin-top: var(--sc-7); }

/* Back link on a leaf page. Inline-link sized, so SC 2.5.8's inline exception
   applies, but it still gets a comfortable box. */
.back { display: inline-flex; align-items: center; gap: var(--sc-2);
  min-height: 24px; margin-bottom: var(--sc-5); color: var(--sc-ink-soft);
  font-size: var(--sc-t-sm); letter-spacing: var(--sc-track-wide);
  text-transform: uppercase; text-decoration: none; }
.back:hover { color: var(--sc-ink); }

/* SPLIT. A heading held on the left while its argument runs down the right.
   Collapses to one column before the measure gets too narrow to read. */
.split { display: grid; gap: var(--sc-6) var(--sc-8);
  grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); align-items: start; }
.split > :first-child h2 { margin: 0; }
.split p + p { margin-top: var(--sc-4); }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }

/* PULL QUOTE. The studio's own voice, not a client's, so it is set in the
   display face at band scale rather than in the quote card. */
.pull { margin: 0; padding-block: clamp(3rem, 9vh, 7rem);
  border-block: 1px solid var(--sc-hairline); }
.pull p { margin: 0; font-family: var(--sc-font-display); font-weight: 400;
  font-size: var(--sc-t-2xl); line-height: 1.12; color: var(--sc-ink);
  letter-spacing: var(--sc-track-snug); max-width: 24ch; }
.pull em { font-style: italic; color: var(--sc-accent); }
.pull footer { margin-top: var(--sc-5); font-size: var(--sc-t-sm);
  color: var(--sc-ink-soft); letter-spacing: var(--sc-track-wide); }

/* DEFINITION ROWS for contact details. <dl> because that is what it is. */
.rows { margin: 0; display: grid; gap: 0; }
.rows > div { display: grid; grid-template-columns: minmax(0, 9rem) minmax(0, 1fr);
  gap: var(--sc-4); padding-block: var(--sc-4);
  border-top: 1px solid var(--sc-hairline); }
.rows > div:last-child { border-bottom: 1px solid var(--sc-hairline); }
.rows dt { margin: 0; color: var(--sc-ink-soft); font-size: var(--sc-t-sm);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase; }
.rows dd { margin: 0; color: var(--sc-ink); }
.rows a { color: var(--sc-ink); text-underline-offset: 3px; }
@media (max-width: 560px) { .rows > div { grid-template-columns: 1fr; gap: var(--sc-1); } }

/* NEXT. The last thing on every interior page: one onward door, never a
   dead end. Full-bleed hairline box so it reads as a destination. */
.next { display: block; text-decoration: none; color: inherit;
  border-top: 1px solid var(--sc-hairline); padding-block: clamp(3rem, 8vh, 6rem); }
.next .sc-wrap { display: grid; gap: var(--sc-4); }
.next span { font-size: var(--sc-t-sm); color: var(--sc-ink-soft);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase; }
.next strong { font-family: var(--sc-font-display); font-weight: 400;
  font-size: var(--sc-t-2xl); line-height: 1.05; letter-spacing: var(--sc-track-snug); }
.next:hover strong { color: var(--sc-accent); }
.next:focus-visible { outline: 2px solid var(--sc-ink); outline-offset: -4px; }

/* SITE FOOTER. `/` ends inside the pinned close, which carries its own .foot.
   Every other page needs a real one. */
.site-foot { border-top: 1px solid var(--sc-hairline); padding-block: var(--sc-7); }
.site-foot .sc-wrap { display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--sc-5); }
.site-foot nav { display: flex; flex-wrap: wrap; gap: var(--sc-2); }
.site-foot small { color: var(--sc-ink-soft); font-size: var(--sc-t-xs); }
.site-foot .mark { color: var(--sc-ink); text-decoration: none; }

/* PROJECTS. Image on one side, the argument on the other, alternating. */
.proj { display: grid; gap: var(--sc-6) var(--sc-8);
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  align-items: center; padding-block: clamp(3rem, 8vh, 6rem);
  border-top: 1px solid var(--sc-hairline); }
.proj:last-of-type { border-bottom: 1px solid var(--sc-hairline); }
.proj--flip > :first-child { order: 2; }
@media (max-width: 900px) {
  .proj { grid-template-columns: 1fr; }
  .proj--flip > :first-child { order: 0; }
}
.proj__kind { font-size: var(--sc-t-xs); color: var(--sc-ink-soft);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase; }
.proj h3 { margin: var(--sc-2) 0 var(--sc-3); font-family: var(--sc-font-display);
  font-weight: 400; font-size: var(--sc-t-xl); letter-spacing: var(--sc-track-snug); }
.proj p { margin: 0; color: var(--sc-ink-soft); max-width: 36ch; } /* same DM Sans ch-inflation correction */
.proj__scope { display: flex; flex-wrap: wrap; gap: var(--sc-2);
  margin-top: var(--sc-5); font-size: var(--sc-t-xs); color: var(--sc-ink-soft); }
.proj__scope span { border: 1px solid var(--sc-hairline); border-radius: 2px;
  padding: 0.3rem 0.6rem; }
.proj__links { display: flex; flex-wrap: wrap; gap: var(--sc-5); margin-top: var(--sc-5); }
.proj__links a { display: inline-flex; align-items: center; min-height: 24px;
  color: var(--sc-accent); font-size: var(--sc-t-sm);
  letter-spacing: var(--sc-track-wide); text-underline-offset: 4px; }

/* BEFORE / AFTER. A range input drives the reveal, so the control is a real
   focusable slider with arrow keys for free rather than a div that only
   answers to a mouse. The visual handle is the input's own thumb. */
/* --ratio is the aspect of the SHORTEST screenshot in the pair. Set it that way
   and `cover` scales every frame by width and crops the bottom, so both shots
   sit at one magnification and neither leaves a strip of the other showing
   through underneath it. A 16/9 default covers the single-image case. */
.shot { position: relative; overflow: hidden; border-radius: 2px;
  border: 1px solid var(--sc-hairline); background: var(--sc-surface);
  aspect-ratio: var(--ratio, 16 / 9); }
.shot img { display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: top center; }
.ba { --split: 50%; position: relative; }
.ba__pane { position: absolute; inset: 0; }
.ba__pane--before { clip-path: inset(0 calc(100% - var(--split)) 0 0); }
.ba__line { position: absolute; top: 0; bottom: 0; left: var(--split); width: 1px;
  background: var(--sc-ink); opacity: .85; pointer-events: none; }
.ba__tag { position: absolute; bottom: var(--sc-3); font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  background: color-mix(in srgb, var(--sc-canvas) 82%, transparent);
  color: var(--sc-ink); padding: 0.25rem 0.5rem; border-radius: 2px;
  pointer-events: none; }
.ba__tag--before { left: var(--sc-3); }
.ba__tag--after  { right: var(--sc-3); }
.ba__range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0;
  appearance: none; background: transparent; cursor: ew-resize; }
.ba__range:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 2px; }
.ba__range::-webkit-slider-thumb { appearance: none; width: 30px; height: 30px;
  border-radius: 50%; background: var(--sc-ink); border: 3px solid var(--sc-canvas);
  cursor: ew-resize; }
.ba__range::-moz-range-thumb { width: 30px; height: 30px; border: 3px solid var(--sc-canvas);
  border-radius: 50%; background: var(--sc-ink); cursor: ew-resize; }
.ba__range::-moz-range-track { background: transparent; }
.ba__hint { margin-top: var(--sc-3); font-size: var(--sc-t-xs); color: var(--sc-ink-soft);
  letter-spacing: var(--sc-track-wide); max-width: var(--sc-measure); } /* was uncapped: ran to 199 real chars on wide viewports */

/* METRICS. Numbers get the display face because they are the argument. */
.metrics { display: grid; gap: var(--sc-5);
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); margin-top: var(--sc-6); }
.metric { border-top: 1px solid var(--sc-hairline); padding-top: var(--sc-3); }
.metric b { display: block; font-family: var(--sc-font-display); font-weight: 400;
  font-size: var(--sc-t-xl); letter-spacing: var(--sc-track-snug); color: var(--sc-ink); }
.metric span { display: block; margin-top: var(--sc-1); font-size: var(--sc-t-xs);
  color: var(--sc-ink-soft); letter-spacing: var(--sc-track-wide);
  text-transform: uppercase; }

/* GALLERY. Captioned stills, two up. */
.gallery { display: grid; gap: var(--sc-5);
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); }
.gallery figure { margin: 0; }
.gallery img { display: block; width: 100%; height: auto; border-radius: 2px;
  border: 1px solid var(--sc-hairline); }
.gallery figcaption { margin-top: var(--sc-3); font-size: var(--sc-t-sm);
  color: var(--sc-ink-soft); }

/* PAY. A single-column document with a form at the end of it. */
.doc { max-width: 46rem; }
.doc h2 { margin: 0 0 var(--sc-5); }
.doc p { color: var(--sc-ink-soft); }
.doc p + p { margin-top: var(--sc-4); }
.doc strong { color: var(--sc-ink); font-weight: 400; }
.warn { border-left: 2px solid var(--sc-accent); padding-left: var(--sc-5); }
.warn p { color: var(--sc-ink); }

/* 404. The film's own poster stands behind it so the page still feels like
   this site rather than a server default. */
.lost { min-height: calc(100svh - var(--bar-h)); display: grid; place-items: center;
  text-align: center; padding-block: var(--sc-section); }
.lost .sc-wrap { display: grid; gap: var(--sc-6); justify-items: center; }
.lost p { margin: 0 auto; }
.lost nav { display: flex; flex-wrap: wrap; gap: var(--sc-4); justify-content: center; }

/* SC 2.5.8 again. A link that is the only thing inside its paragraph or its
   <dd> is not an inline link in a sentence, so the exception does not cover it
   and a 21px line box fails. These are the four onward links on `/` and the
   phone and email on the contact pages. */
.note > a:only-child,
.rows dd > a:only-child {
  display: inline-flex; align-items: center; min-height: 24px;
}
