/* ==========================================================================
   maxgledhill.com - business systems, automation and websites
   One stylesheet, no build step, no framework.
   Sections: fonts / tokens / base / layout / header / buttons / hero / work /
             lists / steps / about / audit panel / faqs / forms / footer /
             documents / problems / capabilities / before-after / subpages /
             shared labels
   ========================================================================== */

/* --- fonts: self-hosted, latin subset, so no third-party request is made
       from a visitor's browser (see privacy.aspx) --------------------------*/
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('../fonts/bricolage-grotesque-latin-var.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/instrument-sans-latin-var.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
/* Caveat: the hand. Trial from 3 October 2026 (see BRAND.md): the one
   phrase per heading and the ledger title are written rather than set. */
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/caveat-latin-var.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/dm-mono-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/dm-mono-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
/* stand-ins: while a webfont is still on its way the text is set in a local
   face scaled to the same average width (measured against each webfont),
   so the swap changes the letterforms and not the line breaks: the page
   does not jump when the fonts arrive */
@font-face { font-family: 'Bricolage Stand-in'; src: local('Arial'), local('Helvetica Neue'), local('Roboto'), local('Liberation Sans'); size-adjust: 92%; }
@font-face { font-family: 'Instrument Stand-in'; src: local('Arial'), local('Helvetica Neue'), local('Roboto'), local('Liberation Sans'); size-adjust: 102%; }
@font-face { font-family: 'DM Mono Stand-in'; src: local('Courier New'), local('Liberation Mono'); size-adjust: 100%; }
@font-face { font-family: 'Caveat Stand-in'; src: local('Arial'), local('Helvetica Neue'), local('Roboto'), local('Liberation Sans'); size-adjust: 72%; }

/* ------------------------------------------------------------------ tokens */
/* Two looks, one layout. Cream and gold is light mode; charcoal and gold is
   dark mode. The dark set is written twice: once for a dark system setting
   (unless the visitor has chosen light) and once for an explicit choice, so
   the header toggle wins in both directions. Gold is spent in five places
   only: the mark's spine, one phrase per heading, the leak line, the primary
   button and the audit panel edge. Everything else is ink on paper. */
:root {
  --ink: #17130e;
  --ink-70: #4e463c;
  --ink-50: #6e6357;
  --paper: #f5efe3;
  --paper-2: #fbf7ee;
  --paper-3: #efe7d6;
  --line: rgba(23, 19, 14, .13);
  --line-strong: rgba(23, 19, 14, .27);
  --accent: #c9a96a;        /* fills: buttons, rules, the leak */
  --accent-deep: #8f6e32;   /* text: links, the phrase in a heading */
  --accent-tint: rgba(201, 169, 106, .16);
  --accent-ink: #17130e;    /* text on a gold button */
  --danger: #b3261e;
  --danger-tint: rgba(179, 38, 30, .1);
  --ok: #2e6b4e;
  --ok-tint: rgba(46, 107, 78, .12);
  --panel-bg: #17130e;      /* the audit panel */
  --panel-fg: #f5efe3;
  --panel-muted: #cfc5b3;
  --panel-line: rgba(245, 239, 227, .14);
  --panel-accent: #c9a96a;

  --font-sans: 'Instrument Sans', 'Instrument Stand-in', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
  --font-display: 'Bricolage Grotesque', 'Bricolage Stand-in', 'Helvetica Neue', Arial, sans-serif;
  --font-mono: 'DM Mono', 'DM Mono Stand-in', ui-monospace, 'Cascadia Mono', Consolas, monospace;
  --font-hand: 'Caveat', 'Caveat Stand-in', 'Segoe Print', 'Bradley Hand', cursive;

  /* hero particles (main.js reads these). Light mode: matte bouncy balls.
     None of them is gold; the gold budget is unchanged. */
  --particle-mode: ball;
  --particle-opacity: .9;
  --particle-1: #e4572e;
  --particle-2: #2b6fdb;
  --particle-3: #17a398;
  --particle-4: #8e44ad;
  --particle-5: #f4b400;
  --particle-6: #e84a8a;

  --shell: 1120px;
  --radius: 6px;
  --radius-lg: 10px;
  /* layered rather than one big blur: a contact shadow, a lift, and a wide
     ambient one. Reads like an object on a surface instead of a glow. */
  --shadow: 0 1px 1px rgba(23, 19, 14, .04),
            0 4px 10px -4px rgba(23, 19, 14, .08),
            0 16px 32px -18px rgba(23, 19, 14, .16);
  --shadow-lift: 0 1px 1px rgba(23, 19, 14, .05),
                 0 8px 18px -8px rgba(23, 19, 14, .12),
                 0 34px 60px -28px rgba(23, 19, 14, .24);
  --hairline: inset 0 0 0 1px rgba(23, 19, 14, .06);
  --section-y: clamp(60px, 7.5vw, 112px);
  color-scheme: light;
}
/* Since 8 October 2026 the site is a stack of cream sheets on a desk, and
   the theme decides the desk, not the paper: day is a school desk, evening
   a wooden desk under a lamp. So the paper, ink, gold and particle tokens no
   longer change here; the desk tokens do (see "the desk", at the end), and
   the masthead takes an evening palette of its own. The forms stay light. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 16px 32px -18px rgba(0, 0, 0, .5);
    --shadow-lift: 0 1px 1px rgba(0, 0, 0, .25), 0 34px 60px -28px rgba(0, 0, 0, .6);
  }
}
:root[data-theme="dark"] {
  --shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 16px 32px -18px rgba(0, 0, 0, .5);
  --shadow-lift: 0 1px 1px rgba(0, 0, 0, .25), 0 34px 60px -28px rgba(0, 0, 0, .6);
}

/* -------------------------------------------------------------------- base */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
}
/* in-page links scroll smoothly via main.js rather than CSS scroll-behavior:
   the CSS version makes ScrollTrigger mis-measure pinned sections on refresh */

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: 100%; height: auto; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; }

/* balance stops a heading ending on one stranded word */
h1, h2, h3 { text-wrap: balance; }

h1, h2 {
  font-family: var(--font-display);
  font-weight: 750;
  font-variation-settings: 'opsz' 96;
  line-height: 1.02;
}
h1 { font-size: clamp(2.4rem, 1.4rem + 3.2vw, 4.1rem); letter-spacing: -.028em; line-height: 1; }
h2 { font-size: clamp(1.9rem, 1.4rem + 2.1vw, 3rem); letter-spacing: -.024em; }
h3 {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -.012em;
  line-height: 1.3;
}

/* one phrase per heading carries the gold; nothing else in a heading does */
h1 em, h2 em {
  font-style: normal;
  color: var(--accent-deep);
  /* handwritten: Caveat sits low and small on its em box, so it is set
     larger and tighter to match the cap height beside it */
  font-family: var(--font-hand);
  font-weight: 600;
  font-size: 1.16em;
  letter-spacing: 0;
  line-height: .85;
  font-variation-settings: normal;
}

p { margin: 0 0 1.1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a {
  color: var(--accent-deep);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-skip-ink: auto;
  transition: text-decoration-color .15s ease, color .15s ease;
}
a:hover { color: var(--ink); text-decoration-thickness: 2px; }

::selection { background: var(--accent-tint); color: var(--ink); }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

@media (prefers-reduced-motion: reduce) {
  a { transition: none; }
}

[id] { scroll-margin-top: 96px; }

.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;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  padding: 12px 20px;
  text-decoration: none;
  border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus { left: 0; color: var(--paper); }

/* ------------------------------------------------------------------ layout */
.shell {
  width: min(100% - 40px, var(--shell));
  margin-inline: auto;
}
@media (max-width: 420px) {
  .shell { width: min(100% - 32px, var(--shell)); }
}

.section { padding-block: var(--section-y); }
.section-tint { background: var(--paper-2); }
.section-line { border-top: 1px solid var(--line); }

/* every small tracked caption on the site is set in the mono, like a ledger,
   and in ink rather than gold: the gold is kept for the five places above */
.eyebrow {
  display: block;
  margin: 0 0 18px;
  font-family: var(--font-mono);
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-50);
}

.lede {
  font-size: clamp(1.1rem, 1.02rem + .38vw, 1.28rem);
  line-height: 1.55;
  color: var(--ink-70);
  max-width: 34em;
}

.prose { max-width: 40em; color: var(--ink-70); }
.prose strong { color: var(--ink); font-weight: 600; }

.section-head { max-width: 42em; margin-bottom: clamp(36px, 4vw, 60px); }
.section-head p { margin-top: 18px; }

/* a heading followed straight by copy always needs air under it */
.split-sticky h2 + .prose,
.about-grid h2 + .prose,
.work-bar h2 + .prose,
.dark-panel h2 + p { margin-top: 18px; }


/* ------------------------------------------------------------------ header */
.masthead {
  position: sticky;
  top: 0;
  z-index: 60;
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  border-bottom: 1px solid var(--line);
  backdrop-filter: saturate(140%) blur(10px);
}
.masthead-inner {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 74px;
  padding-block: 10px;
}

/* the brand: the compass arrow, then the script lettering ------------------
   The arrow is ink with a gold spine and stands alone anywhere the script
   cannot survive (favicon, avatars, anything under 24px). The script comes
   in two files: black with a gold edge for cream, solid gold for charcoal.
   Only the file for the current theme is displayed; both are lazy so the
   hidden one is never fetched. */
.wordmark {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-right: auto;
  min-width: 0;
  text-decoration: none;
  color: var(--ink);
}
.wordmark-mark {
  width: 24px;
  height: 28px;
  flex: 0 0 auto;
  color: var(--ink);
}
.wordmark-script-frame {
  --script-h: 34px;
  height: var(--script-h);
  width: calc(var(--script-h) * 3.58);
  overflow: hidden;
  flex: 0 0 auto;
}
.wordmark-script {
  display: block;
  height: var(--script-h);
  width: auto;
  max-width: none;
}
/* the light file has its cream baked in: multiply drops it onto the paper */
.wordmark-script-light { mix-blend-mode: multiply; }
/* the gold file has air around the letters, so it is framed and offset */
.wordmark-script-dark {
  display: none;
  height: calc(var(--script-h) * 2.096);
  margin: calc(var(--script-h) * -0.521) 0 0 calc(var(--script-h) * -0.082);
}
.wordmark-line {
  display: none;
  font-family: var(--font-mono);
  font-size: .66rem;
  letter-spacing: .12em;
  color: var(--ink-50);
  border-left: 1px solid var(--line);
  padding-left: 14px;
  margin-left: 2px;
  white-space: nowrap;
}
@media (min-width: 1060px) { .wordmark-line { display: block; } }
@media (max-width: 420px) {
  .wordmark-script-frame { --script-h: 28px; }
  .wordmark-mark { width: 20px; height: 24px; }
}
:root[data-theme="dark"] .wordmark-script-light { display: none; }
:root[data-theme="dark"] .wordmark-script-dark { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wordmark-script-light { display: none; }
  :root:not([data-theme="light"]) .wordmark-script-dark { display: block; }
}

/* light or dark, chosen by the visitor; the choice is kept in their browser */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-70);
  cursor: pointer;
  flex: 0 0 auto;
  transition: border-color .15s ease, color .15s ease;
}
.theme-toggle:hover { border-color: var(--ink); color: var(--ink); }
.theme-toggle svg { width: 16px; height: 16px; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-sun { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .icon-moon { display: block; }
}

.primary-nav {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2vw, 30px);
}
.primary-nav a {
  font-size: .95rem;
  color: var(--ink-70);
  text-decoration: none;
}
.primary-nav a:hover { color: var(--ink); text-decoration: underline; }
.primary-nav a.is-current { color: var(--ink); font-weight: 600; }
.primary-nav .btn { color: var(--accent-ink); }

.nav-toggle { display: none; }

@media (max-width: 860px) {
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    background: var(--paper);
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    padding: 9px 14px;
    font: inherit;
    font-size: .9rem;
    font-weight: 500;
    color: var(--ink);
    cursor: pointer;
  }
  .nav-toggle-bars { display: block; width: 16px; }
  .nav-toggle-bars span {
    display: block;
    height: 2px;
    background: var(--ink);
    border-radius: 2px;
  }
  .nav-toggle-bars span + span { margin-top: 4px; }

  .primary-nav {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow);
    padding: 8px 20px 20px;
  }
  .masthead[data-nav-open="true"] .primary-nav { display: flex; }
  .primary-nav a {
    padding: 14px 2px;
    border-bottom: 1px solid var(--line);
    font-size: 1.02rem;
  }
  .primary-nav .btn {
    margin-top: 16px;
    border-bottom: 0;
    text-align: center;
  }
}

/* ----------------------------------------------------------------- buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 24px;
  border: 1px solid transparent;
  border-radius: 999px;
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease, transform .2s ease;
}
.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 1px 1px rgba(23, 19, 14, .06), 0 6px 14px -8px rgba(143, 110, 50, .5);
}
.btn-primary:hover {
  background: color-mix(in srgb, var(--accent) 86%, var(--ink));
  border-color: transparent;
  color: var(--accent-ink);
  transform: translateY(-1px);
}
.btn:active { transform: translateY(1px); }
@media (prefers-reduced-motion: reduce) {
  .btn:active, .btn-primary:hover { transform: none; }
}
.btn-secondary {
  background: transparent;
  border-color: var(--line-strong);
  color: var(--ink);
}
.btn-secondary:hover { border-color: var(--ink); color: var(--ink); background: transparent; }
.btn-compact { padding: 10px 18px; font-size: .95rem; }
.btn[disabled] { opacity: .6; cursor: progress; }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
}

.arrow { display: inline-block; transition: transform .25s ease; }
.btn:hover .arrow { transform: translateX(4px); }
@media (prefers-reduced-motion: reduce) {
  .btn, .arrow { transition: none; }
  .btn:hover .arrow { transform: none; }
}

/* -------------------------------------------------------------------- hero */
.hero {
  position: relative;
  overflow: hidden;
  padding-top: clamp(44px, 5.5vw, 84px);
  padding-bottom: clamp(56px, 7vw, 104px);
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
/* the particle field lies over the copy and the ledger, in the gaps between
   the lines. main.js draws it:
   bouncy balls in light mode, glowing points in dark mode, and either can
   be picked up and thrown. The cursor classes are set only while the
   pointer is over empty hero space, never over text. */
.hero-particles {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: var(--particle-opacity);
  /* above the copy and the ledger, so the balls can sit between lines and
     rows; pointer events fall through to the page, and main.js picks the
     balls up from the hero's own listeners */
  z-index: 2;
  pointer-events: none;
}
.hero.is-grab { cursor: grab; }
.hero.is-grabbing { cursor: grabbing; }
.hero.is-grabbing * { user-select: none; }
.hero-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(32px, 5vw, 68px);
  align-items: start;
}
@media (max-width: 940px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr); }
}

.hero h1 { margin-bottom: 22px; }
.hero .lede { margin-bottom: 28px; }
.hero-actions { margin-bottom: 22px; }
.hero-note {
  font-size: .92rem;
  color: var(--ink-50);
  max-width: 36em;
  margin: 0;
}

/* the ledger: a typical week, one situation per row, set like a bank
   statement. It stands where a screenshot would on a web designer's site,
   on purpose. */
.ledger {
  position: relative;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift), var(--hairline);
  padding: clamp(22px, 2.8vw, 32px);
  padding-left: calc(var(--yarn-w) + 6px);
  font-family: var(--font-mono);
}
/* the yarn: Max's drawing of a wound ball and a cat's foreleg, cut out and
   recoloured through masks (gold ball, ink paw), and a strand main.js draws
   to fit the rows. The strand is the divider under every row, so the rows
   carry no border of their own, and it is drawn as a ribbon: a gold stroke
   with a paper stroke on top, like the double line in the drawing. */
.ledger {
  --yarn-w: clamp(84px, 20vw, 104px);
  --yarn-pad: clamp(22px, 2.8vw, 32px);
  overflow: hidden;
  padding-right: calc(var(--yarn-pad) + 22px);
  padding-bottom: calc(var(--yarn-pad) + 6px);
}
.yarn-ball, .yarn-paw {
  position: absolute;
  display: block;
  pointer-events: none;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}
.yarn-ball {
  left: 8px;
  top: 12px;
  width: calc(var(--yarn-w) - 14px);
  aspect-ratio: 320 / 332;
  background: var(--accent);
  -webkit-mask-image: url('../img/yarn-ball.png');
  mask-image: url('../img/yarn-ball.png');
  transform-origin: 50% 50%;
}
.yarn-paw {
  left: 6px;
  bottom: -54px;
  width: calc(var(--yarn-w) - 24px);
  aspect-ratio: 220 / 344;
  background: var(--ink);
  -webkit-mask-image: url('../img/yarn-paw.png');
  mask-image: url('../img/yarn-paw.png');
  transform-origin: 50% 100%;
}
.yarn {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
.yarn-strand {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.yarn-strand-outer { stroke: var(--accent); stroke-width: 5.5; }
.yarn-strand-inner { stroke: var(--paper-2); stroke-width: 2.2; }
.ledger-head {
  margin: 0 0 6px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-50);
}
.ledger-head { align-items: baseline; }
/* the title is written on the statement, not printed */
.ledger-head span {
  font-family: var(--font-hand);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-70);
}
.ledger-head b { font-weight: 500; color: var(--accent-deep); }
.ledger-rows { margin: 0; }
.ledger-row {
  display: grid;
  gap: 4px;
  padding: 14px 0;
  /* no rule between rows: the yarn runs under each one instead */
}
.ledger-row:first-child { padding-top: 10px; }
.ledger-row dt {
  font-size: .95rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink);
}
.ledger-row dd {
  margin: 0;
  font-size: .84rem;
  line-height: 1.5;
  color: var(--ink-70);
}
.ledger-foot {
  margin: 14px 0 0;
  padding-top: 10px;
  /* no rule here: the yarn is the divider */
  font-size: .82rem;
  color: var(--ink-50);
}
.ledger-foot strong { color: var(--ink); font-weight: 500; }

/* screenshot frames -------------------------------------------------------*/
.shot { margin: 0; }
.frame-browser {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--paper);
  box-shadow: var(--shadow-lift), var(--hairline);
  overflow: hidden;
  /* the address pill's nowrap text used to widen the whole document even
     though it was clipped; paint containment stops that leaking out */
  contain: paint;
}
.frame-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  min-height: 42px;
  background: var(--paper-3);
  border-bottom: 1px solid var(--line);
}
.frame-dots { display: inline-flex; gap: 7px; flex: 0 0 auto; }
.frame-dots i {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--line-strong);
}
.frame-url {
  display: inline-block;
  flex: 0 1 auto;
  min-width: 0;
  margin-left: 6px;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .02em;
  color: var(--ink-50);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 99px;
  padding: 3px 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-decoration: none;
  transition: border-color .15s ease, color .15s ease;
}
a.frame-url:hover { color: var(--accent-deep); border-color: var(--line-strong); text-decoration: underline; }
.frame-browser img { width: 100%; }

/* live previews ----------------------------------------------------------
   Every frame loads as a screenshot. Where a client's site allows framing,
   the frame bar carries a button that swaps the screenshot for the real
   site: an iframe rendered at the desktop or phone width the screenshot was
   taken at, then scaled down to fit the frame. The screenshot stays in
   place until the site has actually loaded, so a slow or blocked load never
   leaves an empty frame behind. */
.frame-live {
  margin-left: auto;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .01em;
  line-height: 1.2;
  color: var(--ink-70);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 99px;
  padding: 3px 10px 3px 8px;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.frame-live::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ok);
}
.frame-live:hover { border-color: var(--ink); color: var(--ink); }
.frame-live[aria-pressed="true"] { color: var(--ink); border-color: var(--line-strong); }
.frame-live[aria-pressed="true"]::before { animation: live-pulse 1.6s ease-in-out infinite; }
.frame-live.is-loading::before { background: var(--ink-50); animation: live-pulse .9s ease-in-out infinite; }
@keyframes live-pulse { 50% { opacity: .25; } }

.frame-screen {
  --live-scale: 1;
  position: relative;
  overflow: hidden;
}
.frame-screen iframe {
  position: absolute;
  top: 0; left: 0;
  border: 0;
  background: #fff;
  transform: scale(var(--live-scale));
  transform-origin: 0 0;
  opacity: 0;
  transition: opacity .35s ease;
}
.frame-screen.is-live iframe { opacity: 1; }
.frame-screen.is-live img { visibility: hidden; }
/* the phone screen keeps its rounded corners whatever is inside */
.frame-phone .frame-screen { border-radius: 23px; isolation: isolate; }

@media (prefers-reduced-motion: reduce) {
  .frame-url, .frame-live, .frame-screen iframe { transition: none; }
  .frame-live::before { animation: none !important; }
}

.shot-caption {
  margin-top: 14px;
  font-size: .88rem;
  line-height: 1.5;
  color: var(--ink-50);
  max-width: 46ch;
}
.shot-caption strong { color: var(--ink-70); font-weight: 600; }

.frame-phone {
  width: 218px;
  padding: 6px;
  background: linear-gradient(170deg, #23282f 0%, #0d1014 42%, #15191f 100%);
  border-radius: 28px;
  box-shadow: var(--shadow-lift), inset 0 0 0 1px rgba(255, 255, 255, .14);
}
.frame-phone img {
  width: 100%;
  border-radius: 23px;
}

/* -------------------------------------------------------------------- work */
/* the work slider ---------------------------------------------------------
   One project per slide. Without JavaScript the track is still a plain
   horizontally scrollable region with a visible scrollbar; the arrows and
   the project buttons are revealed only once the script has wired them up,
   so there are never dead controls on the page. */
.work-section { overflow: hidden; }

.work-bar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: clamp(32px, 4vw, 52px);
}
.work-bar h2 { margin-top: 16px; }
.work-intro { max-width: 44em; }

.slider-nav { display: flex; gap: 10px; flex: 0 0 auto; }
.slider-btn {
  width: 46px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 1.1rem;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.slider-btn:hover:not([disabled]) { border-color: var(--ink); color: var(--accent-deep); }
.slider-btn[disabled] { opacity: .35; cursor: default; }

.slider-track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
}
.slide {
  scroll-snap-align: start;
  scroll-snap-stop: always;
  min-width: 0;
}
/* hide the scrollbar only once the buttons exist to replace it */
[data-slider].is-enhanced .slider-track { scrollbar-width: none; }
[data-slider].is-enhanced .slider-track::-webkit-scrollbar { width: 0; height: 0; }

.slide-inner {
  display: grid;
  gap: clamp(28px, 4vw, 60px);
  align-items: center;
  padding-block: 4px 8px;
}
@media (min-width: 900px) {
  .slide-inner { grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr); }
}

.slide-copy h3 {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 1.3rem + 1.1vw, 2.15rem);
  line-height: 1.1;
  letter-spacing: -.02em;
  margin-bottom: 14px;
}

.slider-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: clamp(30px, 3.5vw, 46px);
}
.slider-tab {
  border: 1px solid var(--line-strong);
  border-radius: 99px;
  background: transparent;
  color: var(--ink-70);
  font: inherit;
  font-size: .93rem;
  padding: 9px 18px;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background-color .15s ease;
}
.slider-tab:hover { border-color: var(--ink); color: var(--ink); }
.slider-tab[aria-current="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

/* the two devices, sharing one baseline ---------------------------------- */
.devices {
  margin: 0;
  display: grid;
  justify-items: center;
  gap: 18px;
}
@media (min-width: 520px) {
  .devices {
    display: flex;
    align-items: flex-end;
    gap: clamp(14px, 2vw, 24px);
  }
  .devices .frame-browser { flex: 1 1 auto; min-width: 0; }
  .devices .frame-phone { flex: 0 0 clamp(94px, 12.5vw, 138px); width: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .slider-btn, .slider-tab { transition: none; }
}

.status-tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 13px 5px 10px;
  border-radius: 99px;
  background: var(--ok-tint);
  color: var(--ok);
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.status-tag::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
}

.work-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
}
.work-sector {
  font-family: var(--font-mono);
  font-size: .8rem;
  color: var(--ink-50);
}

/* the case study: problem / why it mattered / built / changed */
.case {
  margin: 30px 0 0;
  border-top: 1px solid var(--line);
}
.case-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 6px 24px;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}
@media (min-width: 620px) {
  .case-row { grid-template-columns: 140px minmax(0, 1fr); }
}
.case-row dt {
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-50);
  padding-top: 3px;
}
.case-row:last-child dt { color: var(--accent-deep); }
.case-row dd { margin: 0; color: var(--ink-70); font-size: .98rem; }
.case-row:last-child dd { color: var(--ink); }

.work-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  align-items: center;
  margin-top: 28px;
}

.aside-note {
  margin-top: clamp(40px, 5vw, 64px);
  padding: 22px 24px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--ink-70);
  font-size: .98rem;
  max-width: 62em;
}

/* --------------------------------------------------- editorial split lists */
.split {
  display: grid;
  grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
  gap: clamp(30px, 5vw, 72px);
  align-items: start;
}
@media (max-width: 860px) {
  .split { grid-template-columns: minmax(0, 1fr); }
}
@media (min-width: 861px) {
  .split-sticky { position: sticky; top: 104px; }
}
.split-cta {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 26px;
  font-weight: 500;
}

.stack-list { list-style: none; margin: 0; padding: 0; }
.stack-list > li {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 4px 18px;
  padding: 26px 0;
  border-top: 1px solid var(--line);
}
.stack-list > li:first-child { padding-top: 0; border-top: 0; }
.stack-list > li:last-child { padding-bottom: 0; }
.stack-list .num {
  grid-row: span 2;
  font-family: var(--font-mono);
  font-size: .8rem;
  letter-spacing: .1em;
  font-variant-numeric: tabular-nums;
  color: var(--accent-deep);
  padding-top: 6px;
}
.stack-list p { color: var(--ink-70); margin: 8px 0 0; font-size: 1rem; }

/* ------------------------------------------------------------------- steps */
/* three cards in a column. With the script running on a wide screen each
   one pins under the last as you scroll, so "Find the leak" is still on
   screen while "Build the fix" arrives. Without it they are a plain list. */
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 18px;
  counter-reset: step;
}
.steps > li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: 8px 24px;
  align-items: start;
  padding: clamp(24px, 3.5vw, 40px);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  transform-origin: top center;
}
.steps > li::before {
  content: counter(step);
  grid-row: span 2;
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 4vw, 3.2rem);
  font-weight: 300;
  line-height: 1;
  color: var(--accent-deep);
  font-variation-settings: 'opsz' 96;
}
.steps h3 { margin-bottom: 6px; }
.steps p { color: var(--ink-70); font-size: 1rem; max-width: 62ch; }
@media (max-width: 560px) {
  .steps > li { grid-template-columns: minmax(0, 1fr); }
  .steps > li::before { grid-row: auto; }
}

/* ------------------------------------------------------------------- about */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
}
@media (min-width: 900px) {
  .about-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); align-items: start; }
}
.about-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(24px, 3vw, 34px);
  box-shadow: var(--shadow);
}
.about-card h3 { margin-bottom: 14px; }
.about-card ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.about-card li {
  position: relative;
  padding: 10px 0 10px 26px;
  border-top: 1px solid var(--line);
  color: var(--ink-70);
  font-size: .98rem;
}
.about-card li:first-child { border-top: 0; }
.about-card li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 21px;
  width: 11px;
  height: 2px;
  border-radius: 1px;
  background: var(--accent);
}
.about-card + .about-card { margin-top: 20px; }
.about-card-cta p { color: var(--ink-70); font-size: .98rem; margin-bottom: 18px; }
.about-story h2 {
  font-size: clamp(1.4rem, 1.2rem + .8vw, 1.9rem);
  margin: 1.6em 0 .7em;
  color: var(--ink);
}
.about-story p strong { color: var(--ink); }

/* ------------------------------------------------------------- audit panel */
/* the audit offer, and the closing call on the subpages. The only block on
   the site with a gold edge, so the eye lands on it without an arrow. */
.dark-panel {
  background: var(--panel-bg);
  color: var(--panel-fg);
  border: 1px solid var(--panel-accent);
  border-radius: var(--radius-lg);
  padding: clamp(30px, 4.5vw, 58px);
  display: grid;
  gap: clamp(24px, 3vw, 48px);
}
@media (min-width: 860px) {
  .dark-panel { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); align-items: center; }
}
.dark-panel h2 { color: var(--panel-fg); }
.dark-panel h2 em { color: var(--panel-accent); }
.dark-panel .eyebrow { color: var(--panel-accent); }
.dark-panel p { color: var(--panel-muted); }
.dark-panel .btn-secondary {
  background: transparent;
  border-color: var(--panel-line);
  color: var(--panel-fg);
}
.dark-panel .btn-secondary:hover { border-color: var(--panel-fg); background: transparent; color: var(--panel-fg); }
.dark-panel-note {
  margin-top: 28px;
  padding-top: 22px;
  border-top: 1px solid var(--panel-line);
  font-size: .93rem;
  color: var(--panel-muted);
  max-width: 34em;
}
.dark-list {
  list-style: none;
  margin: 0 0 26px;
  padding: 0;
}
.dark-list li {
  position: relative;
  padding: 9px 0 9px 24px;
  border-top: 1px solid var(--panel-line);
  color: var(--panel-fg);
  font-size: .97rem;
}
.dark-list li:first-child { border-top: 0; padding-top: 0; }
.dark-list li:first-child::before { top: 10px; }
.dark-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 19px;
  width: 11px;
  height: 2px;
  border-radius: 1px;
  background: var(--panel-accent);
}

/* -------------------------------------------------------------------- faqs */
.faq-list { border-top: 1px solid var(--line); }
.faq {
  border-bottom: 1px solid var(--line);
}
.faq > summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 10px;
  margin-inline: -10px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ink);
  list-style: none;
  transition: background-color .15s ease, color .15s ease;
}
.faq > summary:hover { background: var(--accent-tint); }
@media (prefers-reduced-motion: reduce) {
  .faq > summary { transition: none; }
}
.faq > summary::-webkit-details-marker { display: none; }
.faq > summary::after {
  content: "+";
  flex: 0 0 auto;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--accent-deep);
}
.faq[open] > summary::after { content: "\2013"; }
.faq > summary:hover { color: var(--ink); }
.faq-body {
  padding: 0 2px 24px;
  max-width: 58em;
  color: var(--ink-70);
}

/* ------------------------------------------------------------------- forms */
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(32px, 4vw, 56px);
}
@media (min-width: 900px) {
  .contact-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 380px); }
}

.form-card {
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(22px, 3vw, 36px);
  box-shadow: var(--shadow);
}

.form-group {
  margin: 0 0 28px;
  padding: 0;
  border: 0;
  min-width: 0;
}
.form-group:last-of-type { margin-bottom: 30px; }
.form-group legend {
  padding: 0;
  margin-bottom: 18px;
  font-family: var(--font-mono);
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-50);
}
.field-row { display: grid; gap: 0 18px; }
@media (min-width: 620px) {
  .field-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.field { margin-bottom: 22px; }
.form-group .field:last-child { margin-bottom: 0; }
.field-short textarea { min-height: 96px; }
.field label {
  display: block;
  margin-bottom: 7px;
  font-size: .95rem;
  font-weight: 600;
}
.field .hint {
  display: block;
  margin: -2px 0 8px;
  font-size: .87rem;
  font-weight: 400;
  color: var(--ink-50);
}
.field input,
.field textarea {
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 12px 14px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field textarea { min-height: 140px; resize: vertical; }
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
}
.field input:focus-visible,
.field textarea:focus-visible { outline: none; }
.field [aria-invalid="true"] { border-color: var(--danger); }
.field-error {
  display: block;
  margin-top: 7px;
  font-size: .9rem;
  font-weight: 500;
  color: var(--danger);
}
@media (prefers-reduced-motion: reduce) {
  .field input, .field textarea { transition: none; }
}

/* honeypot: hidden from people, available to bots */
.trap {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
}

.notice {
  border-radius: var(--radius);
  padding: 16px 18px;
  margin-bottom: 26px;
  font-size: .98rem;
  border: 1px solid;
}
.notice p { margin-bottom: .6em; }
.notice p:last-child { margin-bottom: 0; }
.notice-success {
  background: var(--ok-tint);
  border-color: var(--ok);
  color: var(--ok);
}
.notice-success a { color: var(--ok); }
.notice-error {
  background: var(--danger-tint);
  border-color: var(--danger);
  color: var(--danger);
}
.notice-error a { color: var(--danger); }

.form-foot {
  margin: 18px 0 0;
  font-size: .88rem;
  color: var(--ink-50);
}

.contact-aside h3 { margin-bottom: 12px; }
.contact-aside .panel {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(22px, 3vw, 30px);
  background: var(--paper-2);
}
.contact-aside .panel + .panel { margin-top: 20px; }
.contact-aside p { color: var(--ink-70); font-size: .98rem; }
.plain-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.plain-list li {
  position: relative;
  padding: 7px 0 7px 22px;
  color: var(--ink-70);
  font-size: .96rem;
}
.plain-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 17px;
  width: 11px;
  height: 2px;
  border-radius: 1px;
  background: var(--accent);
}
.contact-email {
  font-size: 1.05rem;
  font-weight: 500;
  word-break: break-word;
}

/* ------------------------------------------------------------------ footer */
.site-footer {
  border-top: 1px solid var(--line);
  background: var(--paper-2);
  padding-block: clamp(44px, 5vw, 72px) 36px;
}
.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 32px;
}
@media (min-width: 720px) {
  .footer-grid {
    grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr);
    gap: 40px;
  }
}
.footer-meta a { color: var(--ink-50); margin-left: 6px; }
.footer-meta a:hover { color: var(--ink); }
.footer-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.2rem;
  letter-spacing: -.01em;
  margin-bottom: 10px;
}
.footer-note { color: var(--ink-50); font-size: .95rem; max-width: 32em; }
.footer-contact { margin-bottom: 0; }
.footer-sep { color: var(--line-strong); margin: 0 8px; }
.footer-heading {
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-50);
  margin-bottom: 14px;
}
.footer-nav { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.footer-nav a { color: var(--ink-70); text-decoration: none; font-size: .97rem; }
.footer-nav a:hover { color: var(--ink); text-decoration: underline; }
.footer-meta {
  grid-column: 1 / -1;
  margin: 8px 0 0;
  padding-top: 26px;
  border-top: 1px solid var(--line);
  font-size: .88rem;
  color: var(--ink-50);
}

/* -------------------------------------------------------- simple documents */
.doc {
  padding-block: clamp(48px, 6vw, 88px);
}
.doc-body { max-width: 44em; }
.doc-body h2 {
  font-size: clamp(1.3rem, 1.15rem + .7vw, 1.7rem);
  margin: 2em 0 .6em;
}
.doc-body h2:first-of-type { margin-top: 1.4em; }
.doc-body ul { padding-left: 1.2em; color: var(--ink-70); }
.doc-body li { margin-bottom: .5em; }
.doc-body p { color: var(--ink-70); }
.doc-updated { color: var(--ink-50); font-size: .92rem; }
.doc-actions { margin-top: 30px; }
.panel-note { margin-top: 10px; }

/* ---------------------------------------------------------------- problems */
/* "Sound familiar?": six leaks as cards, the usual fix underneath in smaller
   type so the pain reads first. On a wide screen with motion allowed,
   main.js adds .is-fight: the section pins, a ring appears beside the cards
   and the cards become comic captions that land as each blow lands. */
.pain-grid {
  display: grid;
  gap: 18px;
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 620px) {
  .pain-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 980px) {
  .pain-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; }
}
.pain {
  display: flex;
  flex-direction: column;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(22px, 2.6vw, 30px);
  box-shadow: var(--shadow);
}
.pain-n {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-50);
}
.pain h3 {
  font-size: 1.36rem;
  line-height: 1.2;
  letter-spacing: -.016em;
  margin-bottom: 12px;
}
.pain p { color: var(--ink-70); font-size: .98rem; }
.pain-fix {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: .93rem;
}
.pain p.pain-fix { margin-top: auto; padding-top: 16px; color: var(--ink); }
.pain-fix span {
  display: block;
  margin-bottom: 4px;
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent-deep);
}

/* the round counter under the heading, shown only while pinned */
.rail-status {
  display: none;
  align-items: center;
  gap: 18px;
  margin-top: 22px;
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-50);
}
.rail-progress {
  position: relative;
  flex: 1 1 auto;
  max-width: 320px;
  height: 2px;
  background: var(--line);
}
.rail-progress i {
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform-origin: left;
  transform: scaleX(0);
}

/* the ring is only drawn in fight mode */
.ring { display: none; }

/* ---- fight mode: pinned, the whole section fits one screen ------------- */
.is-fight.section { padding-block: clamp(28px, 3.5vw, 48px); }
.is-fight .section-head { margin-bottom: 18px; max-width: 52em; }
.is-fight .section-head h2 { font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.3rem); }
.is-fight .section-head .prose { display: none; }
.is-fight .rail-status { display: flex; margin-top: 14px; }
.is-fight .fight-stage {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: end;
}

/* the ring: everything in it is hand-drawn, so everything gets the wobble */
.is-fight .ring {
  display: block;
  position: relative;
  height: min(420px, 52vh);
  min-height: 320px;
}
.ring-floor {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 8px;
  width: 100%;
  height: 12px;
  filter: url(#sketch);
}
.ring-floor path {
  fill: none;
  stroke: var(--ink-50);
  stroke-width: 2.5;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* "Round 1", written large at the start of each round */
.round-title {
  position: absolute;
  left: 4%;
  top: 8%;
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: clamp(2.4rem, 2vw + 1.4rem, 3.4rem);
  line-height: 1;
  color: var(--ink);
  transform: rotate(-6deg);
  visibility: hidden;
  white-space: nowrap;
}

.fighter {
  position: absolute;
  bottom: 12px;
  width: clamp(140px, 15vw, 185px);
}
.fighter svg { display: block; width: 100%; height: auto; overflow: visible; filter: url(#sketch); }
/* the opponent faces left: mirrored here in CSS, outside the SVG coordinate
   space, so the joint origins in main.js stay the same for both figures */
.fighter svg.mirror { transform: scaleX(-1); }
.fighter-you { left: calc(50% - 200px); }
.fighter-foe { left: calc(50% + 15px); }
.fighter path, .fighter circle {
  fill: none;
  stroke: var(--ink);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.fighter .head circle { fill: var(--paper); }
.fighter .hand { fill: var(--ink); stroke-width: 3; }
.fighter-foe .hand { fill: var(--ink-70); }
.fighter .cap { fill: var(--ink); stroke-width: 3; }
.fighter .eye { stroke-width: 3; }
.fighter-foe path, .fighter-foe circle { stroke: var(--ink-70); }
.fighter-foe .brow, .fighter-foe .mouth { stroke-width: 3.5; }
.fighter .thin { stroke-width: 3; }
.fighter .sweat path { fill: var(--ink-50); stroke: none; }
.fighter .stars path { fill: var(--accent); stroke: none; }
.fighter .prop, .fighter .stars, .fighter .sweat { visibility: hidden; }

/* the opponent's name, written on a card above its head */
.foe-tag {
  position: absolute;
  left: calc(50% + 40px);
  top: 6%;
  padding: 6px 10px;
  font-family: var(--font-mono);
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink);
  background: var(--paper-2);
  border: 2px solid var(--ink);
  border-radius: 4px 7px 5px 8px;
  box-shadow: 3px 3px 0 var(--ink);
  visibility: hidden;
}

/* contact: radiating lines where a blow lands, dust where a body lands */
.impact {
  position: absolute;
  width: 120px;
  height: 120px;
  visibility: hidden;
  pointer-events: none;
}
.impact svg { width: 100%; height: 100%; overflow: visible; filter: url(#sketch); }
.impact svg use { stroke: var(--ink); stroke-width: 4; stroke-linecap: round; fill: none; }
.impact-hit { left: calc(50% - 150px); bottom: 150px; }
.impact-fix { left: calc(50% + 10px); bottom: 170px; }
.dust {
  position: absolute;
  left: calc(50% + 30px);
  bottom: 14px;
  width: 160px;
  height: 40px;
  pointer-events: none;
}
.dust i {
  position: absolute;
  bottom: 0;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--ink-50);
  opacity: 0;
  visibility: hidden;
}
.dust i:nth-child(1) { left: 10px; }
.dust i:nth-child(2) { left: 60px; width: 18px; height: 18px; }
.dust i:nth-child(3) { left: 115px; width: 11px; height: 11px; }

/* the blows: a starburst with the sound written across it */
.burst {
  position: absolute;
  width: 200px;
  height: 120px;
  display: grid;
  place-items: center;
  visibility: hidden;
  pointer-events: none;
}
.burst svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: url(#sketch);
}
.burst svg use { stroke: var(--ink); stroke-width: 3; stroke-linejoin: round; }
.burst-hit svg use { fill: var(--danger-tint); }
.burst-fix svg use { fill: var(--ok-tint); }
.burst-win svg use { fill: var(--paper-2); }
.burst b {
  position: relative;
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: 1.8rem;
  line-height: 1;
  color: var(--ink);
  transform: rotate(-6deg);
  text-align: center;
  padding: 0 22px;
}
.burst-fix b { transform: rotate(5deg); }
.burst-win b { font-size: 1.5rem; transform: rotate(-3deg); }
.burst-hit { left: max(0px, calc(50% - 330px)); top: 0; }
.burst-fix { left: calc(50% + 60px); top: 0; }
.burst-win { left: max(0px, calc(50% - 300px)); top: 0; width: 240px; }

/* confetti: twelve bits of paper in the hero's colours */
.confetti { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.confetti i {
  position: absolute;
  top: -20px;
  width: 9px;
  height: 14px;
  border-radius: 2px;
  visibility: hidden;
}
.confetti i:nth-child(1)  { left: 6%;  background: var(--particle-1); }
.confetti i:nth-child(2)  { left: 14%; background: var(--particle-2); }
.confetti i:nth-child(3)  { left: 22%; background: var(--particle-3); }
.confetti i:nth-child(4)  { left: 30%; background: var(--particle-4); }
.confetti i:nth-child(5)  { left: 38%; background: var(--particle-5); }
.confetti i:nth-child(6)  { left: 46%; background: var(--particle-6); }
.confetti i:nth-child(7)  { left: 54%; background: var(--particle-1); }
.confetti i:nth-child(8)  { left: 62%; background: var(--particle-2); }
.confetti i:nth-child(9)  { left: 70%; background: var(--particle-3); }
.confetti i:nth-child(10) { left: 78%; background: var(--particle-4); }
.confetti i:nth-child(11) { left: 86%; background: var(--particle-5); }
.confetti i:nth-child(12) { left: 94%; background: var(--particle-6); }

/* ---- fight mode on a phone: the ring stacks above the caption and the
   whole scene is sized to fit one pinned screen ----------------------------- */
@media (max-width: 899px) {
  .is-fight.section { padding-block: 18px 24px; }
  .is-fight .section-head { margin-bottom: 8px; }
  .is-fight .section-head .eyebrow { margin-bottom: 10px; }
  .is-fight .section-head h2 { font-size: clamp(1.2rem, 5vw, 1.6rem); }
  .is-fight .rail-status { margin-top: 10px; font-size: .64rem; gap: 12px; }
  .is-fight .fight-stage { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .is-fight .ring { height: clamp(160px, 26vh, 230px); min-height: 160px; overflow: hidden; }
  .fighter { width: clamp(100px, 30vw, 130px); bottom: 10px; }
  .fighter-you { left: calc(50% - 128px); }
  .fighter-foe { left: calc(50% + 24px); }
  .round-title { font-size: 1.7rem; top: 4%; left: 3%; }
  .foe-tag { font-size: .56rem; padding: 4px 7px; top: 5%; left: calc(50% + 26px); }
  .impact { width: 80px; height: 80px; }
  .impact-hit { left: calc(50% - 118px); bottom: 68px; }
  .impact-fix { left: calc(50% + 8px); bottom: 84px; }
  .dust { left: calc(50% + 8px); width: 120px; }
  .burst { width: 130px; height: 78px; }
  .burst b { font-size: 1.15rem; padding: 0 14px; }
  .burst-hit { left: 2px; top: -6px; }
  .burst-fix { left: auto; right: 0; top: -6px; }
  .burst-win { left: 0; top: 0; width: 180px; }
  .burst-win b { font-size: 1.1rem; }
  .confetti i { width: 7px; height: 11px; }
}

/* the cards become captions: stacked in one place, thick ink, hard shadow,
   a tail pointing into the ring */
.is-fight .rounds {
  position: relative;
  display: block;
  min-height: 320px;
  height: min(420px, 52vh);
}
.is-fight .round {
  position: absolute;
  inset: auto 0 0 0;
  margin: 0;
  background: var(--paper-2);
  border: 3px solid var(--ink);
  border-radius: 16px 20px 14px 22px / 20px 14px 22px 16px;
  box-shadow: 7px 7px 0 var(--ink);
  padding: clamp(20px, 2.2vw, 28px);
  visibility: hidden;
}
.is-fight .round::before {
  content: '';
  position: absolute;
  left: -16px;
  top: 38%;
  width: 24px;
  height: 24px;
  background: var(--paper-2);
  border-left: 3px solid var(--ink);
  border-bottom: 3px solid var(--ink);
  transform: rotate(45deg);
}
.is-fight .round h3 { font-size: clamp(1.3rem, 1rem + 1vw, 1.7rem); }
.is-fight .round .pain-n { margin-bottom: 12px; }
.is-fight .round .pain-fix { border-top-color: var(--line-strong); }
@media (max-width: 899px) {
  .is-fight .rounds { height: clamp(220px, 34vh, 300px); min-height: 0; }
  .is-fight .round { inset: 0 0 auto 0; padding: 14px 16px 16px; border-width: 2px; box-shadow: 5px 5px 0 var(--ink); }
  .is-fight .round::before { left: 26px; top: -11px; width: 18px; height: 18px; border-width: 2px; transform: rotate(135deg); }
  .is-fight .round h3 { font-size: 1.1rem; margin-bottom: 8px; }
  .is-fight .round .pain-n { margin-bottom: 8px; font-size: .62rem; }
  .is-fight .round p { font-size: .86rem; }
  .is-fight .round .pain-fix { padding-top: 10px; font-size: .84rem; }
}

/* ------------------------------------------------------------ capabilities */
.cap-grid {
  display: grid;
  gap: 0 32px;
}
@media (min-width: 620px) {
  .cap-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.cap {
  padding: 22px 0;
  border-top: 1px solid var(--line);
}
.cap:first-child { padding-top: 0; border-top: 0; }
@media (min-width: 620px) {
  .cap:nth-child(2) { padding-top: 0; border-top: 0; }
}
.cap h3 { margin-bottom: 12px; }
.cap ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.cap li {
  position: relative;
  padding: 6px 0 6px 22px;
  color: var(--ink-70);
  font-size: .97rem;
}
.cap li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 17px;
  width: 11px;
  height: 2px;
  border-radius: 1px;
  background: var(--accent);
}

/* ------------------------------------------------------------ before/after */
.shift-list {
  border-top: 1px solid var(--line);
}
.shift-row {
  display: grid;
  gap: 0;
  border-bottom: 1px solid var(--line);
}
@media (min-width: 760px) {
  .shift-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
.shift-cell {
  padding: clamp(22px, 3vw, 34px) 0;
}
@media (min-width: 760px) {
  .shift-before { padding-right: clamp(24px, 4vw, 56px); }
  .shift-after {
    padding-left: clamp(24px, 4vw, 56px);
    border-left: 1px solid var(--line);
  }
}
@media (max-width: 759px) {
  .shift-before { padding-bottom: 12px; }
  .shift-after { padding-top: 12px; }
}
.shift-label {
  display: block;
  margin-bottom: 10px;
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-50);
}
.shift-after .shift-label { color: var(--accent-deep); }
.shift-cell p {
  margin: 0;
  color: var(--ink-70);
  font-size: 1.02rem;
  max-width: 34em;
}
.shift-before p { color: var(--ink-50); }
.shift-after p {
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.22rem;
  line-height: 1.4;
  letter-spacing: -.01em;
}

/* ---------------------------------------------------------------- subpages */
.page-hero {
  padding-top: clamp(44px, 5.5vw, 84px);
  padding-bottom: clamp(36px, 4.5vw, 64px);
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.page-hero h1 { margin-bottom: 20px; max-width: 16em; }

/* what-i-fix: numbered problem entries, pain first, tools second */
.fix-list { display: grid; gap: 0; }
.fix {
  display: grid;
  gap: 14px 40px;
  padding: clamp(34px, 4.5vw, 60px) 0;
  border-top: 1px solid var(--line);
}
.fix:first-child { padding-top: 0; border-top: 0; }
@media (min-width: 860px) {
  .fix { grid-template-columns: minmax(0, 340px) minmax(0, 1fr); }
  .fix-head { position: sticky; top: 104px; }
}
.fix-num {
  display: block;
  margin-bottom: 12px;
  font-family: var(--font-mono);
  font-size: .8rem;
  letter-spacing: .1em;
  font-variant-numeric: tabular-nums;
  color: var(--accent-deep);
}
.fix-head h2 {
  font-size: clamp(1.6rem, 1.3rem + 1.2vw, 2.2rem);
}
.fix-body h3 {
  margin: 24px 0 12px;
  font-family: var(--font-mono);
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-50);
}
.fix-body ul {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 40em;
}
.fix-body li {
  position: relative;
  padding: 8px 0 8px 24px;
  border-top: 1px solid var(--line);
  color: var(--ink-70);
  font-size: .98rem;
}
.fix-body li:first-child { border-top: 0; }
.fix-body li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 19px;
  width: 11px;
  height: 2px;
  border-radius: 1px;
  background: var(--accent);
}
.fix-cta {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 22px;
  font-weight: 500;
}

/* ---------------------------------------------------------- motion (GSAP) */
/* Nothing here hides anything. The script lifts marked elements into place
   as they enter the viewport; without it, or under reduced motion, every
   element is simply where it belongs. */
.js-reveal { will-change: transform, opacity; }


/* phones: nothing may widen the page. The fight walks its opponent in from
   off stage and the pinned sections carry transforms; clip at the root so
   none of it can be scrolled into sideways (clip, not hidden, keeps
   position: sticky working) */
html, body { overflow-x: clip; }
.masthead { overflow-x: clip; }


/* ================================================================= the desk
   The site is a stack of ruled sheets lying on a desk. The desk is a fixed
   layer behind every page (body::before), drawn once and composited, never
   repainted on scroll. Its texture is a small WebP tile (assets/img/desk-*)
   rendered from the noise filters in _prototype/paper-desk.html.
   By day it is a school desk, speckled laminate in flat light, with the
   front edge along the bottom and a mug ring. By evening it is a wooden
   desk under one anglepoise lamp (body::after). The paper is cream in
   both: lit, not dyed. */
:root {
  --desk-tex: url('../img/desk-day.webp');
  --desk-base: #c8c3b5;
  /* the sheen across the laminate, the darker front edge along the bottom
     with its highlight, and a mug ring bottom left */
  --desk-light:
    radial-gradient(circle at 12% 88%, transparent 54px, rgba(120,70,30,.22) 55px, rgba(120,70,30,.30) 60px, rgba(120,70,30,.10) 64px, transparent 66px),
    linear-gradient(to top, rgba(0,0,0,.34) 0, rgba(0,0,0,.34) 14px, rgba(255,255,255,.28) 14px, rgba(255,255,255,.28) 16px, rgba(0,0,0,.08) 16px, transparent 44px),
    linear-gradient(115deg, rgba(255,255,255,.18), rgba(255,255,255,0) 40%, rgba(0,0,0,.06) 70%, rgba(0,0,0,.16));
  --lamp: none;
  --sheet: #f5efe3;
  --sheet-2: #fbf7ee;
  --sheet-3: #efe7d6;
  --sheet-back: #d9cfb8;
  --rule: rgba(43, 111, 219, .10);
  --margin: rgba(210, 80, 70, .32);
  --sheet-w: 1240px;
  --sheet-pad: clamp(44px, 5vw, 64px);
  --sheet-gap: clamp(40px, 5vw, 64px);
  --sheet-shadow: 0 30px 70px -30px rgba(23, 19, 14, .55), 0 0 0 1px rgba(23, 19, 14, .06);
  --sky: #17130e;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --desk-base: #2a1c12;
    --desk-tex:
      repeating-linear-gradient(92deg, rgba(0,0,0,.0) 0 9px, rgba(0,0,0,.10) 9px 11px, rgba(255,255,255,.025) 11px 13px, rgba(0,0,0,.0) 13px 31px),
      repeating-linear-gradient(90deg, rgba(120,70,30,.08) 0 160px, rgba(0,0,0,.14) 160px 162px),
      url('../img/desk-evening.webp');
    --desk-light:
      linear-gradient(to top, rgba(0,0,0,.5) 0, rgba(0,0,0,.5) 14px, rgba(255,230,180,.16) 14px, rgba(255,230,180,.16) 16px, rgba(0,0,0,.2) 16px, transparent 44px),
      radial-gradient(ellipse at 72% 12%, rgba(255,214,150,.42), rgba(255,190,110,.12) 28%, rgba(0,0,0,.55) 70%, rgba(0,0,0,.78) 100%);
    --lamp: block;
    --sheet-shadow: 0 40px 90px -30px rgba(0, 0, 0, .85), 0 0 0 1px rgba(0, 0, 0, .3);
    --sky: #0b0906;
  }
}
:root[data-theme="dark"] {
  --desk-base: #2a1c12;
  --desk-tex:
    repeating-linear-gradient(92deg, rgba(0,0,0,.0) 0 9px, rgba(0,0,0,.10) 9px 11px, rgba(255,255,255,.025) 11px 13px, rgba(0,0,0,.0) 13px 31px),
    repeating-linear-gradient(90deg, rgba(120,70,30,.08) 0 160px, rgba(0,0,0,.14) 160px 162px),
    url('../img/desk-evening.webp');
  --desk-light:
    linear-gradient(to top, rgba(0,0,0,.5) 0, rgba(0,0,0,.5) 14px, rgba(255,230,180,.16) 14px, rgba(255,230,180,.16) 16px, rgba(0,0,0,.2) 16px, transparent 44px),
    radial-gradient(ellipse at 72% 12%, rgba(255,214,150,.42), rgba(255,190,110,.12) 28%, rgba(0,0,0,.55) 70%, rgba(0,0,0,.78) 100%);
  --lamp: block;
  --sheet-shadow: 0 40px 90px -30px rgba(0, 0, 0, .85), 0 0 0 1px rgba(0, 0, 0, .3);
  --sky: #0b0906;
}

body { background: var(--desk-base); }
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-color: var(--desk-base);
  background-image: var(--desk-light), var(--desk-tex);
}
/* the lamp: its arm and head top right, drawn in gradients on one fixed layer */
body::after {
  content: ""; display: var(--lamp); position: fixed; z-index: 0; pointer-events: none;
  right: 9vw; top: 0; width: 160px; height: 150px;
  background:
    radial-gradient(ellipse 70px 30px at 50% 86px, #3a2a1c 60%, transparent 61%),
    linear-gradient(#1a120b, #3a2a1c) 50% 70px / 140px 42px no-repeat,
    linear-gradient(#ffe2a8, #ffe2a8) 50% 110px / 112px 5px no-repeat,
    linear-gradient(#0f0a06, #2a1d12) 50% 0 / 6px 90px no-repeat;
  filter: drop-shadow(0 12px 40px rgba(255, 210, 140, .45));
}
/* on a phone the sheet is nearly the full width and the lamp would sit on
   the page itself; the pool of light on the desk is enough there */
@media (max-width: 760px) {
  body::after { display: none; }
}

/* ---- the sheets ------------------------------------------------------- */
/* every section is its own sheet on the stack: cream, ruled, a red margin
   and three punched holes, with two more sheets peeking out beneath it.
   The rules are faint (a texture to read across, not a grid to fight), the
   body copy is not forced onto them. */
.hero, .section, .site-footer {
  position: relative;
  width: min(100% - 32px, var(--sheet-w));
  margin-inline: auto;
  margin-bottom: var(--sheet-gap);
  padding-inline: var(--sheet-pad);
  border: 0;
  border-radius: 2px;
  background-color: var(--sheet);
  background-image:
    radial-gradient(circle at 20px 96px, var(--desk-base) 8px, transparent 9px),
    radial-gradient(circle at 20px 50%, var(--desk-base) 8px, transparent 9px),
    radial-gradient(circle at 20px calc(100% - 96px), var(--desk-base) 8px, transparent 9px),
    linear-gradient(to right, transparent 44px, var(--margin) 44px, var(--margin) 45.5px, transparent 45.5px),
    repeating-linear-gradient(to bottom, transparent 0 31px, var(--rule) 31px 32px);
  background-position: 0 0, 0 0, 0 0, 0 0, 0 20px;
  background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 32px;
  box-shadow:
    6px 8px 0 -1px var(--sheet-3),
    -5px 14px 0 -2px var(--sheet-2),
    var(--sheet-shadow);
}
.hero { margin-top: 0; }
.section-tint, .section-line, .site-footer { background-color: var(--sheet); border-top: 0; }
/* the shell sits inside the sheet's own padding */
.hero .shell, .section .shell, .site-footer .shell { width: min(100%, var(--shell)); }
/* a pinned sheet keeps its width: ScrollTrigger fixes the element in place */
.pin-spacer > .section { margin-inline: auto; }
@media (max-width: 760px) {
  :root { --sheet-pad: 28px; }
  .hero, .section, .site-footer {
    width: min(100% - 16px, var(--sheet-w));
    background-image:
      radial-gradient(circle at 10px 72px, var(--desk-base) 5px, transparent 6px),
      radial-gradient(circle at 10px 50%, var(--desk-base) 5px, transparent 6px),
      radial-gradient(circle at 10px calc(100% - 72px), var(--desk-base) 5px, transparent 6px),
      linear-gradient(to right, transparent 22px, var(--margin) 22px, var(--margin) 23px, transparent 23px),
      repeating-linear-gradient(to bottom, transparent 0 31px, var(--rule) 31px 32px);
  }
}

/* ---- the masthead by evening: the site's chrome over a dark desk ---------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .masthead {
    --ink: #f2eada; --ink-70: #c9bfae; --ink-50: #a29886; --paper: #2a1c12; --line: rgba(242, 234, 218, .14);
    --accent-ink: #17130e;
    border-bottom-color: rgba(0, 0, 0, .4);
  }
}
:root[data-theme="dark"] .masthead {
  --ink: #f2eada; --ink-70: #c9bfae; --ink-50: #a29886; --paper: #2a1c12; --line: rgba(242, 234, 218, .14);
  --accent-ink: #17130e;
  border-bottom-color: rgba(0, 0, 0, .4);
}

/* ------------------------------------------------------- the paper plane run
   main.js builds all of this: a fixed stage under the masthead (shown only
   in flight), the desk as a plane in the 3D world, the stack the sheet
   lifts off, the sheet cut into pieces (clipped clones), the planets and
   the far pages. */
.plane-spacer { height: 0; }
.plane-stage {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: 50;                       /* under the masthead (60), over the page */
  background: var(--sky);
  overflow: hidden;
  display: none;                     /* main.js shows it only while the run is in flight */
  pointer-events: none;
  contain: strict;
}
.plane-stars { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.plane-view { position: absolute; inset: 0; perspective: 1400px; perspective-origin: 50% 50%; }
.plane-world { position: absolute; inset: 0; transform-style: preserve-3d; }
/* the desk plane: extended beyond the screen by whole tiles, with the
   pattern shifted back so it lines up with body::before the instant it
   appears. The far edge is just above the screen, so the sky shows beyond
   it as soon as the camera tilts up */
.plane-desk { position: absolute; left: -880px; top: -240px; right: -880px; bottom: -900px; transform-origin: 0 0;
  background-color: var(--desk-base); background-image: var(--desk-light), var(--desk-tex); background-position: 880px 240px; }
/* the rest of the stack: the next sheet, ruled like the others */
.plane-under { position: absolute; transform-origin: 0 0; border-radius: 2px;
  background-color: var(--sheet);
  background-image:
    linear-gradient(to right, transparent 44px, var(--margin) 44px, var(--margin) 45.5px, transparent 45.5px),
    repeating-linear-gradient(to bottom, transparent 0 31px, var(--rule) 31px 32px);
  background-position: 0 0, 0 20px; background-size: 100% 100%, 100% 32px;
  box-shadow: 6px 8px 0 -1px var(--sheet-3), -5px 14px 0 -2px var(--sheet-2), var(--sheet-shadow); }
/* the lifted sheet's shadow on the stack, before it folds */
.plane-shadow { position: absolute; transform-origin: 0 0; border-radius: 12px; background: rgba(23, 19, 14, .22); box-shadow: 0 0 36px 14px rgba(23, 19, 14, .22); }
.plane-set { display: none; }
.plane-set.on { display: contents; }
.plane-leaf { position: absolute; transform-style: preserve-3d; transform-origin: 0 0; }
.plane-leaf > .plane-face, .plane-leaf > .plane-back { position: absolute; inset: 0; backface-visibility: hidden; }
.plane-face { overflow: hidden; }
/* out in space the copies leave the layout tree: a cream face stands in */
.plane-leaf.is-far .plane-face { background: var(--sheet); }
.plane-leaf.is-far .plane-page { display: none; }
.plane-page { position: absolute; left: 0; top: 0; }
/* the copies are pictures of the sheet, not the sheet: they fill their
   piece exactly, carry no stack or shadow of their own, no filters and no
   animation, and nothing pinned or sticky inside them */
.plane-page > .hero, .plane-page > .section { width: 100% !important; max-width: none !important; margin: 0 !important; box-shadow: none !important; position: relative !important; top: auto !important; }
.plane-page * { filter: none !important; animation: none !important; transition: none !important; }
.plane-page img.hero-particles { object-fit: fill; }
/* the back of the paper: plainly a different surface from the printed
   side, so a folded flap reads as a fold and not as a missing corner */
.plane-back { background: var(--sheet-back); transform: translateZ(-0.4px) rotateY(180deg); }
.plane-back::after { content: ""; position: absolute; inset: 0; background:
  linear-gradient(135deg, rgba(255,255,255,.10), rgba(23,19,14,0) 35%, rgba(23,19,14,.16) 100%),
  repeating-linear-gradient(0deg, rgba(23,19,14,.025) 0 1px, transparent 1px 7px); }
/* planets: matte discs in the hero palette, lit from the upper left */
.plane-planet { position: absolute; left: 0; top: 0; border-radius: 50%;
  box-shadow: inset -0.12em -0.1em 0 rgba(23,19,14,.28), inset 0.06em 0.06em 0 rgba(255,255,255,.16); }
.plane-planet::after { content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, rgba(255,255,255,.22), rgba(255,255,255,0) 45%), radial-gradient(circle at 70% 75%, rgba(23,19,14,.22), rgba(23,19,14,0) 55%); }
.plane-planet i { position: absolute; border-radius: 50%; background: rgba(23,19,14,.14); box-shadow: inset 0.1em 0.1em 0 rgba(23,19,14,.12); }
.plane-pring { position: absolute; left: 0; top: 0; border-radius: 50%; border-style: solid; border-color: rgba(245,239,227,.55); }
.plane-pring::after { content: ""; position: absolute; inset: 10%; border-radius: 50%; border: 1px solid rgba(245,239,227,.35); }
/* other businesses' pages, drifting in the distance */
.plane-sheet { position: absolute; left: 0; top: 0; width: 240px; height: 340px; background: var(--sheet); border-radius: 2px; box-shadow: 0 0 0 1px rgba(23,19,14,.3); }
.plane-sheet::before { content: ""; position: absolute; left: 10%; right: 10%; top: 9%; height: 7%; background: rgba(23,19,14,.55); }
.plane-sheet::after { content: ""; position: absolute; left: 10%; right: 18%; top: 22%; height: 52%; background: repeating-linear-gradient(to bottom, rgba(23,19,14,.28) 0 2px, transparent 2px 9px); }
