/* ---- design/tokens.css ---- */
/* =====================================================================
   DESIGN TOKENS: the one place to change colors, fonts, sizes, spacing
   and motion. Every other stylesheet reads these variables.
   ===================================================================== */
:root {
  /* ---- Brand colors (PROVISIONAL: sampled from the green storefront sign
          in the shop video. Replace with the owner's exact vinyl/Pantone codes.) ---- */
  --green: #1DAA47;        /* sign green: fills only; text on it = carbon (6.9:1) */
  --green-press: #17913B;
  --green-tint: #DDF1E2;
  --navy: #12335D;         /* sign lettering navy: headings + text (12.7:1 on white) */
  --navy-deep: #0C2546;
  --carbon: #121417;       /* logo black */
  --substrate: #F6F5F1;    /* page background, like vinyl backing paper */
  --liner: #E9E6DD;        /* panels */
  --tape: #EFE3C4;         /* transfer tape: hero peel + placeholder chips only */
  --white: #FFFFFF;

  --ink: var(--carbon);
  --ink-soft: #464B52;     /* secondary text, 8:1 on substrate */
  --line: var(--carbon);
  --line-soft: #CFCAC0;
  --focus: var(--navy);
  --danger: #A3261B;       /* error text, 6.7:1 on substrate */

  /* ---- Type. Default = the current face (Big Shoulders + Overpass) until Brandon picks.
          The candidates (anton, tanker, kanit, racing) override below. Pick in content/site.json → typePairing. ---- */
  --font-display: 'Big Shoulders', 'Arial Narrow', sans-serif;
  --font-body: 'Overpass', Verdana, Arial, sans-serif;
  --font-label: 'Big Shoulders', 'Arial Narrow', sans-serif;
  --font-accent: var(--font-display);
  --display-style: normal;
  --display-stretch: 100%;
  --display-weight: 900;
  --display-scale: 1.24;
  /* The huge headline face, used BIG. */
  --mega-track: 0;
  --mega-lead: 0.84;
  /* How wide 'W&W SIGNS' is in this face, in ems (measured). Lets the hero name fit any screen. */
  --brand-em: 4.66;
  --label-stretch: 100%;
  --label-weight: 750;
  --label-style: normal;
  --label-scale: 1.46;
  --accent-style: normal;
  --accent-weight: 850;
  /* Giant outlined (stroke-only) words behind content */
  --outline-w: max(1.5px, 0.012em);
  /* ---- Type sizes (fluid between phone and desktop) ---- */
  --size-hero: calc(var(--display-scale) * clamp(2.45rem, 1.3rem + 4.9vw, 5.1rem));
  --size-h2: calc(var(--display-scale) * clamp(1.85rem, 1.2rem + 2.6vw, 3.2rem));
  --size-h3: calc(var(--display-scale) * clamp(1.3rem, 1.08rem + 0.95vw, 1.85rem));
  --size-body: clamp(1rem, 0.96rem + 0.2vw, 1.125rem);
  --size-lede: clamp(1.08rem, 1rem + 0.4vw, 1.3rem);
  --size-small: 0.875rem;
  --size-label: calc(var(--label-scale) * 0.78rem);

  /* ---- Tracking + leading by size: tight on big type, open on small labels ---- */
  --track-hero: -0.012em;
  --track-h2: -0.008em;
  --track-h3: -0.01em;
  --track-body: 0;
  --track-label: 0.07em;
  --lead-hero: 0.9;
  --lead-h2: 0.95;
  --lead-h3: 1.12;
  --lead-body: 1.55;

  /* ---- Space (8px rhythm) ---- */
  --s1: 0.25rem; --s2: 0.5rem; --s3: 0.75rem; --s4: 1rem; --s5: 1.5rem;
  --s6: 2rem; --s7: 3rem; --s8: 4rem; --s9: 6rem;
  --gutter: clamp(1rem, 0.55rem + 2vw, 2.5rem);
  --max: 1240px;
  --section-pad: clamp(3.5rem, 2rem + 6vw, 7.5rem);

  /* ---- Shape: square corners, hairlines, one 12° slant ---- */
  --radius: 2px;
  --hair: 1.5px;
  --slant: 11px;
  --crop: 14px;            /* crop-mark margin around photos */

  /* ---- Motion (springs for gestures live in src/client/motion.js) ---- */
  --press-scale: 0.97;
  --dur-press: 100ms;
  --dur-fade: 180ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --spring: cubic-bezier(0.2, 0.8, 0.2, 1);

  --header-h: 68px;
  --sticky-h: 0px;
  --pbar: 0px;               /* preview bar height (preview only) */
  --nav-top: calc(var(--pbar) + 12px);

  --photo-ink: #FFFFFF;      /* text on photos */
  --photo-shade: rgba(10, 12, 14, 0.62);

  /* ---- Glass (buttons + panels): see-through, softly blurred behind, light catching the edge.
          Used by .glass, .btn, .gicon, panels. Solid fallbacks below for "Reduce transparency". ---- */
  --glass-blur: 16px;
  --glass-sat: 175%;
  --glass-clear: rgba(255, 255, 255, 0.5);    /* on light backgrounds: dark text */
  --glass-clear-hi: rgba(255, 255, 255, 0.78);
  --glass-dark: rgba(20, 24, 28, 0.42);       /* on photos and dark backgrounds: light text */
  --glass-dark-hi: rgba(20, 24, 28, 0.6);
  --glass-green: rgba(29, 170, 71, 0.86);     /* the main action */
  --glass-green-hi: rgba(52, 196, 96, 0.92);
  --glass-navy: rgba(18, 51, 93, 0.78);
  --glass-rim: rgba(255, 255, 255, 0.85);     /* the bright edge where light catches it */
  --glass-shadow: 0 1px 2px rgba(10, 14, 20, 0.14), 0 10px 26px -12px rgba(10, 14, 20, 0.42);
  --glass-shadow-lg: 0 2px 6px rgba(10, 14, 20, 0.12), 0 28px 60px -24px rgba(10, 14, 20, 0.5);
  --radius-panel: 28px;
  /* A spring with a little bounce, as a CSS curve: for presses that lift. */
  --spring-pop: cubic-bezier(0.3, 1.5, 0.5, 1);
}
@supports (transition-timing-function: linear(0, 1)) {
  :root { --spring-pop: linear(0, 0.18 7%, 0.6 17%, 0.95 27%, 1.08 36%, 1.1 42%, 1.07 52%, 1.01 66%, 0.99 78%, 1); }
}

/* A critically damped spring (no overshoot), as a CSS easing curve. */
@supports (transition-timing-function: linear(0, 1)) {
  :root {
    --spring: linear(0, 0.082 5%, 0.243 10%, 0.413 15%, 0.562 20%, 0.682 25%, 0.773 30%, 0.841 35%, 0.89 40%, 0.949 50%, 0.977 60%, 0.99 70%, 0.995 80%, 1);
  }
}

/* The current face again, so a block marked data-type="b" (on /fonts) shows it inside any other pairing. */
[data-type="b"] {
  --font-display: 'Big Shoulders', 'Arial Narrow', sans-serif;
  --font-body: 'Overpass', Verdana, Arial, sans-serif;
  --font-label: 'Big Shoulders', 'Arial Narrow', sans-serif;
  --display-style: normal; --display-weight: 900; --display-scale: 1.24; --mega-lead: 0.84; --mega-track: 0;
  --label-style: normal; --label-weight: 750; --label-scale: 1.46; --accent-style: normal; --accent-weight: 850;
  --brand-em: 4.66;
}

/* ===== Display candidates (Brandon picks one on /fonts). Body for all of them: Public Sans. ===== */
/* Anton: heavy condensed poster face, close to the reference's weight. Google Fonts, SIL OFL. */
[data-type="anton"] {
  --font-display: 'Anton', 'Arial Narrow', sans-serif;
  --font-body: 'Public Sans', Arial, sans-serif;
  --font-label: 'Anton', 'Arial Narrow', sans-serif;
  --display-weight: 400; --display-scale: 1.12; --mega-lead: 0.9; --mega-track: 0;
  --label-weight: 400; --label-scale: 1.38; --accent-weight: 400;
  --brand-em: 4.31; /* measured */
}
/* Tanker: heavy condensed, rounded corners, all caps. Fontshare, ITF Free Font License. */
[data-type="tanker"] {
  --font-display: 'Tanker', 'Arial Narrow', sans-serif;
  --font-body: 'Public Sans', Arial, sans-serif;
  --font-label: 'Tanker', 'Arial Narrow', sans-serif;
  --display-weight: 400; --display-scale: 1.1; --mega-lead: 0.88; --mega-track: 0.005em;
  --label-weight: 400; --label-scale: 1.38; --accent-weight: 400;
  --brand-em: 4.04; /* measured */
}
/* Kanit Black Italic: heavy and slanted like the W&W logo / vehicle graphics. Google Fonts, SIL OFL. */
[data-type="kanit"] {
  --font-display: 'Kanit', Arial, sans-serif;
  --font-body: 'Public Sans', Arial, sans-serif;
  --font-label: 'Kanit', Arial, sans-serif;
  --display-style: italic; --display-weight: 900; --display-scale: 0.92; --mega-lead: 0.92; --mega-track: -0.02em;
  --label-style: italic; --label-weight: 800; --label-scale: 1.24; --accent-style: italic; --accent-weight: 900;
  --brand-em: 5.4; /* measured 5.35 + the italic's lean */
}
/* Racing Sans One: a slanted racing face (one weight). Google Fonts, SIL OFL. */
[data-type="racing"] {
  --font-display: 'Racing Sans One', Arial, sans-serif;
  --font-body: 'Public Sans', Arial, sans-serif;
  --font-label: 'Public Sans', Arial, sans-serif;
  --display-weight: 400; --display-scale: 0.98; --mega-lead: 0.92; --mega-track: -0.01em;
  --label-weight: 800; --label-scale: 1.24; --accent-weight: 400;
  --brand-em: 5.45; /* measured */
}


/* ---- design/fonts.css ---- */
/* GENERATED by tools/fonts.mjs. Do not edit by hand; edit the FAMILIES list and re-run. */
/* Licenses: public/fonts/licenses/. All allow commercial use and self-hosting. */

/* anton */
@font-face {
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/anton-normal-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* tanker */
@font-face {
  font-family: 'Tanker';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/tanker-normal-400.woff2') format('woff2');
}

/* kanit */
@font-face {
  font-family: 'Kanit';
  font-style: italic;
  font-weight: 800;
  font-display: swap;
  src: url('/fonts/kanit-italic-800.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* kanit */
@font-face {
  font-family: 'Kanit';
  font-style: italic;
  font-weight: 900;
  font-display: swap;
  src: url('/fonts/kanit-italic-900.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* kanit */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url('/fonts/kanit-normal-900.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* racing */
@font-face {
  font-family: 'Racing Sans One';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/racing-sans-one-normal-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* body (new) */
@font-face {
  font-family: 'Public Sans';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/public-sans-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* body (new) */
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/public-sans-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* b (current) */
@font-face {
  font-family: 'Big Shoulders';
  font-style: normal;
  font-weight: 500 900;
  font-display: swap;
  src: url('/fonts/big-shoulders-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* b (current body) */
@font-face {
  font-family: 'Overpass';
  font-style: italic;
  font-weight: 300 800;
  font-display: swap;
  src: url('/fonts/overpass-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* b (current body) */
@font-face {
  font-family: 'Overpass';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('/fonts/overpass-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* ---- src/styles/00-base.css ---- */
/* Base: reset, body text, links, focus, helpers, preview markers. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: calc(var(--nav-top) + 64px); }
body {
  margin: 0;
  background: var(--substrate);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: var(--lead-body);
  letter-spacing: var(--track-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}
img, video, svg, picture { display: block; max-width: 100%; }
img { height: auto; }
h1, h2, h3, h4, p, ul, ol, dl, figure, blockquote { margin: 0; }
ul, ol { padding: 0; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { cursor: pointer; }
a { color: var(--navy); text-decoration-thickness: 1.5px; text-underline-offset: 0.18em; }
a:hover { text-decoration-thickness: 2.5px; }
address { font-style: normal; }
code { font-family: ui-monospace, Consolas, monospace; font-size: 0.9em; background: var(--liner); padding: 0.05em 0.3em; }
::selection { background: var(--green); color: var(--carbon); }

/* Visible focus everywhere: a navy ring with a green halo, like a registration outline. */
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; box-shadow: 0 0 0 7px rgba(29, 170, 71, 0.35); }
:focus:not(:focus-visible) { outline: none; }
main:focus { outline: none; }

.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: var(--gutter); top: -100px; z-index: 100; background: var(--carbon); color: var(--substrate); padding: 12px 16px; font-weight: 700; }
.skip-link:focus { top: 12px; }
[hidden] { display: none !important; }

/* Display type: the sign-trade voice. Used by every big heading. */
.display, h1, .section-title, .final-cta__title {
  font-family: var(--font-display);
  font-style: var(--display-style);
  font-stretch: var(--display-stretch);
  font-weight: var(--display-weight);
  color: var(--navy);
  text-wrap: balance;
}
.label, .eyebrow {
  font-family: var(--font-label);
  font-stretch: var(--label-stretch);
  font-weight: var(--label-weight);
  font-size: var(--size-label);
  letter-spacing: var(--track-label);
  line-height: 1.3;
  text-transform: uppercase;
}
p { text-wrap: pretty; }
.hint { font-size: var(--size-small); color: var(--ink-soft); line-height: 1.45; }

/* ---- Preview markers (preview mode only) ---- */
.uv { text-decoration: underline dotted var(--navy); text-decoration-thickness: 2px; text-underline-offset: 0.2em; }
.uv-mark { display: inline-block; margin-left: 0.15em; font-family: var(--font-body); font-style: normal; font-weight: 700; font-size: 0.62em; vertical-align: super; line-height: 0; color: var(--navy); cursor: help; }
.ph {
  display: inline-block; padding: 0.05em 0.45em; background: var(--tape); border: 1.5px dashed var(--carbon);
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-weight: 700; font-style: normal;
  font-size: 0.78em; letter-spacing: 0.04em; color: var(--carbon); line-height: 1.5; vertical-align: 0.06em; white-space: nowrap;
}
h1 .ph, h2 .ph, h3 .ph, .stub__big .ph { font-size: max(0.32em, 0.8rem); vertical-align: middle; }
.missing { background: #ffd7d2; color: var(--danger); font-weight: 700; padding: 0 0.3em; }
.draft-note { background: var(--tape); border-left: 4px solid var(--carbon); padding: 10px 14px; margin: var(--s4) 0; font-size: var(--size-small); }
.demo-note { font-size: var(--size-small); color: var(--ink-soft); border-left: 3px solid var(--green); padding-left: 10px; }

/* Preview bar: one thin fixed strip at the very top (preview only). */
:root:has(.preview-bar) { --pbar: 30px; }
body:has(.preview-bar) { padding-top: var(--pbar); }
.preview-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60; height: var(--pbar);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  padding: 0 var(--gutter); background: var(--carbon); color: var(--substrate);
  font-size: 0.74rem; line-height: 1;
}
.preview-bar > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.preview-bar__tools {
  flex: none; min-height: 24px; padding: 2px 10px; border: 1.5px solid var(--substrate); background: transparent; color: var(--substrate);
  font-family: var(--font-label); font-weight: 700; font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
}
.preview-bar__tools:active { transform: scale(var(--press-scale)); }

/* "Show where text lives" (Preview tools) */
html.show-keys [data-k], html.show-keys [data-fact] { outline: 1.5px dashed #c2410c; outline-offset: 2px; cursor: copy; }
html.show-keys .ph, html.show-keys .uv { outline-color: var(--navy); }

/* Page to page: every page cross-fades into the next (browsers that support it). Every page opts in
   (layout.mjs → page), so a fade never starts on one page and gets cancelled by the next.
   Motion off or reduced motion: no fade. */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.32s; }
html.motion-off::view-transition-old(root), html.motion-off::view-transition-new(root) { animation: none; }
@media (prefers-reduced-motion: reduce) { ::view-transition-old(root), ::view-transition-new(root) { animation: none; } }


/* ---- src/styles/10-layout.css ---- */
/* Layout: sections, section headings, eyebrows with registration marks. */
.section {
  max-width: var(--max);
  margin-inline: auto;
  padding: var(--section-pad) var(--gutter) 0;
}
.section-head { max-width: 46rem; margin-bottom: clamp(1.75rem, 1rem + 2.5vw, 3rem); }
.section-title {
  font-size: var(--size-h2);
  line-height: var(--lead-h2);
  letter-spacing: var(--track-h2);
  margin-top: var(--s3);
}
.section-intro { margin-top: var(--s4); font-size: var(--size-lede); color: var(--ink-soft); max-width: 38rem; }

.eyebrow { display: flex; align-items: center; gap: 0.6em; color: var(--navy); }
.eyebrow__num { color: var(--carbon); padding-right: 0.6em; border-right: var(--hair) solid var(--line); }
/* Registration mark: the circle-and-cross printers use to line up colors. */
.reg {
  flex: none; width: 15px; height: 15px; border: 1.5px solid currentColor; border-radius: 50%;
  background:
    linear-gradient(currentColor, currentColor) center / 1.5px 100% no-repeat,
    linear-gradient(currentColor, currentColor) center / 100% 1.5px no-repeat;
}


/* ---- src/styles/20-components.css ---- */
/* Components: glass buttons + controls, giant type, outlined ghost words, tabs, photos, form fields. */

/* ---- Glass ----
   The material for every button, small control and floating panel (tokens: design/tokens.css → Glass).
   See-through with the background softly blurred behind it, a bright edge where light catches it,
   a soft inner highlight, a little depth. On desktop the highlight follows the cursor (main.js sets --mx/--my).
   Tints: default clear (on light backgrounds) · .is-dark / on photos · green for the main action.
   With "Reduce transparency" (or no blur support) it turns solid; see the end of this block. */
.glass, .btn, .gicon, .sqbtn, .tab-bar, .sticker {
  --g-tint: var(--glass-clear);
  --g-tint-hi: var(--glass-clear-hi);
  position: relative; isolation: isolate;
  background:
    linear-gradient(165deg, rgba(255, 255, 255, 0.34), rgba(255, 255, 255, 0.06) 42%, rgba(255, 255, 255, 0) 60%, rgba(255, 255, 255, 0.12)),
    var(--g-tint);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  box-shadow:
    inset 0 1px 0.5px var(--glass-rim),
    inset 0 -1px 1px rgba(255, 255, 255, 0.26),
    inset 0 0 0 1px rgba(255, 255, 255, 0.24),
    var(--glass-shadow);
}
/* The soft highlight inside; it drifts toward the cursor. */
.glass::before, .btn::before, .gicon::before, .sqbtn::before, .sticker::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: radial-gradient(130% 90% at var(--mx, 50%) var(--my, 0%), rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 58%);
  opacity: 0.55; transition: opacity var(--dur-fade) ease;
}
.btn:hover::before, .gicon:hover::before, .sqbtn:hover::before, .sticker:hover::before { opacity: 0.9; }
.is-dark, .btn--ink, .btn--on-photo, .btn--dark { --g-tint: var(--glass-dark); --g-tint-hi: var(--glass-dark-hi); color: var(--photo-ink); }
.is-green, .btn--primary, .btn--block { --g-tint: var(--glass-green); --g-tint-hi: var(--glass-green-hi); color: var(--carbon); }
.is-navy { --g-tint: var(--glass-navy); --g-tint-hi: var(--glass-navy); color: var(--photo-ink); }

/* ---- Buttons: glass capsules ----
   .btn (clear) · .btn--primary / .btn--block (green: the main action) · .btn--secondary / .btn--line (clear)
   .btn--ink / .btn--on-photo / .btn--dark (dark glass, on photos or color) · sizes --sm / --lg
   .gicon / .sqbtn: round icon buttons · .sticker: a big round green button */
.btn {
  --h: 50px;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.55em;
  min-height: var(--h); padding: 0 1.45em;
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-style: var(--label-style); font-weight: 750;
  font-size: calc(var(--label-scale) * 0.92rem); letter-spacing: 0.055em; text-transform: uppercase; line-height: 1.1;
  text-decoration: none; text-align: center; white-space: nowrap;
  border: 0; border-radius: 999px; color: var(--carbon);
  transition: transform 420ms var(--spring-pop), filter var(--dur-fade) ease;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation; user-select: none;
}
.btn:hover { text-decoration: none; filter: brightness(1.05) saturate(1.05); }
/* Presses react the instant a finger or click goes down: the glass lifts and brightens. */
.btn:active, .btn.is-pressed { transform: scale(1.045); --g-tint: var(--g-tint-hi); transition-duration: 160ms; }
.btn--primary, .btn--block { font-weight: 800; }
/* Text color per tint (after .btn so it wins). */
.btn.btn--ink, .btn.btn--on-photo, .btn.btn--dark { color: var(--photo-ink); text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35); }
.btn.btn--primary, .btn.btn--block { color: var(--carbon); }
.btn--lg { --h: 58px; font-size: calc(var(--label-scale) * 1rem); padding-inline: 1.7em; }
.btn--sm { --h: 44px; font-size: calc(var(--label-scale) * 0.8rem); padding-inline: 1.15em; }
.btn--block.btn--lg { --h: 64px; font-size: calc(var(--label-scale) * 1.08rem); }
.btn__detail { font-family: var(--font-body); font-stretch: 100%; font-style: normal; text-transform: none; letter-spacing: 0; font-weight: 700; }
.btn.is-disabled { opacity: 0.6; pointer-events: none; }
.btn[disabled] { opacity: 0.65; cursor: progress; }
.btn .i { width: 1.25em; height: 1.25em; flex: none; }
.btn:focus-visible, .gicon:focus-visible, .sqbtn:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; box-shadow: 0 0 0 7px rgba(29, 170, 71, 0.35), var(--glass-shadow); }

.gicon, .sqbtn {
  display: inline-grid; place-items: center; width: 52px; height: 52px; padding: 0; flex: none;
  border: 0; border-radius: 50%; color: var(--carbon);
  transition: transform 420ms var(--spring-pop);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.gicon:active, .sqbtn:active { transform: scale(1.08); --g-tint: var(--g-tint-hi); transition-duration: 160ms; }
.gicon .i, .sqbtn .i { width: 22px; height: 22px; }
.i { display: inline-block; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vertical-align: middle; }

/* A big round green glass button (the statement's "Next: Get a quote"). */
.sticker {
  display: grid; place-content: center; gap: 0.15em;
  width: var(--size, 9.5rem); aspect-ratio: 1; padding: 1rem; border-radius: 50%;
  color: var(--carbon); text-align: center; text-decoration: none;
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.2rem); line-height: 0.92; text-transform: uppercase;
  transition: transform 460ms var(--spring-pop);
  -webkit-tap-highlight-color: transparent;
}
.sticker { --g-tint: var(--glass-green); --g-tint-hi: var(--glass-green-hi); }
.sticker:hover { text-decoration: none; transform: scale(1.05); }
.sticker:active { transform: scale(1.09); --g-tint: var(--g-tint-hi); }
.sticker small { font-family: var(--font-body); font-style: normal; font-weight: 700; font-size: 0.82rem; text-transform: none; letter-spacing: 0; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 0.45em; min-height: 44px;
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-weight: 750; font-size: calc(var(--label-scale) * 0.9rem);
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--carbon); text-decoration: none;
}
.link-arrow::after { content: ''; width: 1.6em; height: 1.5px; background: currentColor; transition: width var(--dur-fade) var(--ease-out); }
.link-arrow:hover::after { width: 2.4em; }
.link-arrow--back { flex-direction: row-reverse; }

/* ---- Filter tabs: one glass bar; the chosen tab is a green glass capsule inside it ---- */
.tabs { display: flex; }
.tab-bar { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 5px; border-radius: 999px; max-width: 100%; }
.tab {
  display: inline-flex; align-items: center; min-height: 42px; padding: 0 15px; border-radius: 999px;
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-style: var(--label-style); font-weight: 750;
  font-size: calc(var(--label-scale) * 0.84rem); letter-spacing: 0.05em; line-height: 1; text-transform: uppercase; white-space: nowrap;
  color: var(--carbon); text-decoration: none;
  transition: background-color var(--dur-fade) ease, transform 380ms var(--spring-pop), box-shadow var(--dur-fade) ease;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.tab:hover { background: rgba(255, 255, 255, 0.55); text-decoration: none; }
.tab:active { transform: scale(1.06); }
.tab[aria-pressed="true"] {
  background: linear-gradient(170deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0) 55%), var(--glass-green);
  box-shadow: inset 0 1px 0.5px var(--glass-rim), inset 0 0 0 1px rgba(255, 255, 255, 0.25), 0 4px 12px -6px rgba(10, 60, 25, 0.6);
}

/* Solid fallbacks: "Reduce transparency", "Increase contrast", or no blur support. */
@media (prefers-reduced-transparency: reduce) {
  .glass, .btn, .gicon, .sqbtn, .tab-bar, .sticker { -webkit-backdrop-filter: none; backdrop-filter: none; --g-tint: #FFFFFF; }
  .is-dark, .btn--ink, .btn--on-photo, .btn--dark { --g-tint: #1B1F24; }
  .is-green, .btn--primary, .btn--block, .sticker { --g-tint: var(--green); }
  .is-navy { --g-tint: var(--navy); }
}
@media (prefers-contrast: more) {
  .glass, .btn, .gicon, .sqbtn, .tab-bar, .sticker { -webkit-backdrop-filter: none; backdrop-filter: none; --g-tint: #FFFFFF; box-shadow: inset 0 0 0 2px var(--carbon); }
  .is-dark, .btn--ink, .btn--on-photo, .btn--dark { --g-tint: #121417; box-shadow: inset 0 0 0 2px #fff; }
  .is-green, .btn--primary, .btn--block, .sticker { --g-tint: var(--green); }
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass, .btn, .gicon, .sqbtn, .tab-bar { --g-tint: rgba(255, 255, 255, 0.92); }
  .is-dark, .btn--ink, .btn--on-photo, .btn--dark { --g-tint: rgba(20, 24, 28, 0.88); }
}

/* Preview tools only (not part of the site's look). */
.chip {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 1em;
  border: var(--hair) solid var(--carbon); background: var(--substrate); color: var(--carbon);
  font-family: var(--font-body); font-weight: 700; font-size: 0.8rem; text-decoration: none;
}
.chip[aria-pressed="true"] { background: var(--carbon); color: var(--substrate); }

/* ---- Giant type ----
   .mega: the display face used huge, tight and in capitals.
   .fitline: one line sized by src/client/fit.js to fill its box (data-fit = share of the width).
   The font-size each section sets is the no-JavaScript size; fit.js refines it. */
.mega, .intro__mega, .stack__title, .statement__text, .road__slide, .quote__big, .visit__big, .ghost {
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  line-height: var(--mega-lead); letter-spacing: var(--mega-track); text-transform: uppercase;
}
.fitline { display: inline-block; white-space: nowrap; max-width: none; }
.fitline.is-wrapped { display: block; white-space: normal; text-wrap: balance; }
html.no-js .fitline { white-space: normal; }
.fitline .uv-mark { font-size: max(0.14em, 0.8rem); }

/* Giant outlined (stroke-only) words behind content, for depth. They drift as you scroll. */
.ghost {
  position: absolute; z-index: 0; margin: 0; pointer-events: none; user-select: none;
  font-size: 26vw; line-height: 0.8; white-space: nowrap;
  color: transparent; -webkit-text-stroke: var(--outline-w) rgba(18, 51, 93, 0.2);
}
.ghost--light { -webkit-text-stroke-color: rgba(246, 245, 241, 0.28); }
@supports not (-webkit-text-stroke: 1px black) { .ghost { color: rgba(18, 51, 93, 0.06); } }

/* ---- Proof frame: photos framed by printer's crop marks (job pages). ---- */
.proof {
  --c: var(--carbon);
  position: relative;
  padding: var(--crop);
  background:
    linear-gradient(var(--c), var(--c)) left 0 top var(--crop) / 9px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) left var(--crop) top 0 / 1.5px 9px no-repeat,
    linear-gradient(var(--c), var(--c)) right 0 top var(--crop) / 9px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) right var(--crop) top 0 / 1.5px 9px no-repeat,
    linear-gradient(var(--c), var(--c)) left 0 bottom var(--crop) / 9px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) left var(--crop) bottom 0 / 1.5px 9px no-repeat,
    linear-gradient(var(--c), var(--c)) right 0 bottom var(--crop) / 9px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) right var(--crop) bottom 0 / 1.5px 9px no-repeat;
}

/* ---- Job ticket caption (job pages) ---- */
.ticket {
  display: inline-flex; gap: 0.6em; align-items: center; margin-top: var(--s2); margin-left: var(--crop);
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-weight: var(--label-weight);
  font-size: var(--size-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-soft);
}
.ticket::before { content: ''; width: 18px; height: 1.5px; background: var(--carbon); }

/* ---- Stamps (job pages) ---- */
.stamp {
  display: inline-block; padding: 4px 8px;
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-weight: 800; font-size: calc(var(--label-scale) * 0.7rem);
  letter-spacing: 0.08em; text-transform: uppercase; line-height: 1.2;
}
.stamp--new { background: var(--green); color: var(--carbon); }
.stamp--pending { background: var(--tape); color: var(--carbon); border: 1.5px dashed var(--carbon); }
.stamp--inline { margin-top: var(--s3); text-transform: none; letter-spacing: 0; font-family: var(--font-body); font-weight: 600; font-size: var(--size-small); }

/* Preview-only: a strip of transfer tape on a photo whose job still needs the owner's OK. */
.tape {
  position: absolute; z-index: 3; top: -9px; left: 50%; translate: -50% 0; rotate: -3deg;
  padding: 3px 12px; background: rgba(239, 227, 196, 0.94); color: var(--carbon);
  font: 700 0.75rem/1.3 var(--font-body); white-space: nowrap; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}

/* ---- Images with blur-up placeholders (no layout shift: width/height are set) ---- */
.pic { position: relative; display: block; overflow: hidden; background: var(--liner); }
.pic::before {
  content: ''; position: absolute; inset: -8%; background: var(--ph, none) center / cover no-repeat; filter: blur(14px);
  transform: scale(1.04); transition: opacity 400ms ease;
}
.pic img { position: relative; width: 100%; height: 100%; object-fit: cover; }
html.js .pic img.fade { opacity: 0; transition: opacity 450ms ease; }
html.js .pic img.fade.is-loaded { opacity: 1; }
.pic:has(img.is-loaded)::before { opacity: 0; }

/* ---- Open now / closed ---- */
.open-status { display: inline-flex; align-items: center; gap: 0.5em; font-weight: 700; }
.open-status__dot { width: 10px; height: 10px; border-radius: 50%; background: var(--ink-soft); flex: none; }
.open-status.is-open .open-status__dot { background: var(--green); box-shadow: 0 0 0 3px var(--green-tint); }
.open-status.is-closed .open-status__dot { background: transparent; border: 2px solid var(--ink-soft); }
.open-status--compact { font-family: var(--font-body); text-transform: none; letter-spacing: 0; font-size: var(--size-small); margin-left: 0.6em; }

/* ---- Form fields: soft white wells with rounded corners, so they sit well inside glass panels ---- */
.field { display: grid; gap: 6px; margin-bottom: var(--s5); border: 0; padding: 0; min-width: 0; }
.field > label, .field > legend { font-weight: 700; font-size: 1rem; padding: 0; margin-bottom: 6px; }
.field-row { display: grid; gap: 0 var(--s4); grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
input:not([type="radio"]):not([type="checkbox"]):not([type="file"]):not([type="range"]), select, textarea {
  width: 100%; min-height: 54px; padding: 12px 16px; font-size: max(16px, 1.02rem);
  background: rgba(255, 255, 255, 0.9); border: 1.5px solid rgba(18, 20, 23, 0.55); border-radius: 14px; color: var(--carbon);
  box-shadow: inset 0 1px 3px rgba(10, 14, 20, 0.08);
  transition: border-color var(--dur-fade) ease, background-color var(--dur-fade) ease;
}
input:not([type="radio"]):not([type="checkbox"]):not([type="file"]):not([type="range"]):hover, select:hover, textarea:hover { border-color: var(--carbon); }
textarea { min-height: 104px; resize: vertical; line-height: 1.45; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; box-shadow: none; background: #fff; }
input::placeholder, textarea::placeholder { color: #6B6F75; }
input[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--danger); box-shadow: inset 5px 0 0 var(--danger); }
.field-error { color: var(--danger); font-weight: 700; font-size: var(--size-small); }
.field-error::before { content: '! '; }

.choices { display: flex; flex-wrap: wrap; gap: 8px; }
.choice { position: relative; display: block; }
.choice input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.choice > span {
  display: flex; align-items: center; min-height: 52px; padding: 10px 18px; border-radius: 16px;
  background: rgba(255, 255, 255, 0.72); box-shadow: inset 0 0 0 1.5px rgba(18, 20, 23, 0.5), inset 0 1px 0 #fff; font-weight: 700; line-height: 1.25;
  transition: transform 380ms var(--spring-pop), background-color var(--dur-fade), box-shadow var(--dur-fade);
}
.choices--inline .choice > span { border-radius: 999px; }
.choice:hover > span { background: #fff; box-shadow: inset 0 0 0 1.5px var(--carbon), inset 0 1px 0 #fff; }
.choice input:checked + span {
  background: linear-gradient(170deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0) 55%), var(--glass-green);
  box-shadow: inset 0 1px 0.5px var(--glass-rim), inset 0 0 0 1px rgba(255, 255, 255, 0.3), 0 6px 16px -8px rgba(10, 60, 25, 0.6);
}
.choice input:focus-visible + span { outline: 3px solid var(--focus); outline-offset: 3px; }
.choice:active > span { transform: scale(1.04); }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }


/* ---- src/styles/25-texture.css ---- */
/* TEXTURE + SMALL DETAILS from a sign shop's world, so no big area is one flat color.
   All CSS (no image downloads), all faint: they sit behind the content and never fight the text.
   - Backing-paper grid: the faint printed grid on the back of vinyl rolls (off-white sections)
   - Crop + registration marks: what a printer puts at the corners of a print (partials.mjs → printMarks)
   - Color bar: the CMYK calibration strip on the edge of every print
   - Ruler: the edge of a cutting mat, with numbers (partials.mjs → ruler)
   - Halftone fade, the W&W sign's green LED glow, and a soft wrap-film sheen on dark areas */
:root {
  --grid-ink: rgba(18, 51, 93, 0.055);
  --grid-ink-strong: rgba(18, 51, 93, 0.09);
  --paper-grid:
    linear-gradient(var(--grid-ink-strong) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-ink-strong) 1px, transparent 1px),
    linear-gradient(var(--grid-ink) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-ink) 1px, transparent 1px);
  --paper-grid-size: 96px 96px, 96px 96px, 24px 24px, 24px 24px;
  --cmyk: linear-gradient(90deg, #00A3E0 0 12.5%, #E5007E 12.5% 25%, #FFE600 25% 37.5%, #1A1A1A 37.5% 50%, #3B3B3B 50% 62.5%, #7A7A7A 62.5% 75%, #B5B5B5 75% 87.5%, #E3E3E3 87.5%);
  --halftone: radial-gradient(circle, currentColor 0 1.3px, transparent 1.8px);
}

/* ---- Off-white sections: the backing-paper grid, with soft light from the top ---- */
.intro, .statement, .quote, .stack {
  background-image: radial-gradient(130% 70% at 50% 0%, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0) 70%), var(--paper-grid);
  background-size: 100% 100%, var(--paper-grid-size);
  background-position: 0 0, -1px -1px, -1px -1px, -1px -1px, -1px -1px;
}
/* The gallery is a light table: a touch darker, with the light pooled in the middle. */
.stack {
  --grid-ink: rgba(18, 51, 93, 0.06); --grid-ink-strong: rgba(18, 51, 93, 0.1);
  background-image: radial-gradient(70% 60% at 50% 55%, rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0) 75%), var(--paper-grid);
}

/* ---- Crop marks at the corners + registration targets at the sides ---- */
.marks { position: absolute; inset: clamp(10px, 2vw, 22px); z-index: 0; pointer-events: none; color: rgba(18, 51, 93, 0.38); }
.marks--light { color: rgba(246, 245, 241, 0.32); }
.marks__c { position: absolute; width: 30px; height: 30px; }
.marks__c::before, .marks__c::after { content: ''; position: absolute; background: currentColor; }
.marks__c::before { width: 20px; height: 1.5px; }
.marks__c::after { width: 1.5px; height: 20px; }
.marks__c--tl { top: 0; left: 0; } .marks__c--tl::before { top: 10px; left: -10px; } .marks__c--tl::after { left: 10px; top: -10px; }
.marks__c--tr { top: 0; right: 0; } .marks__c--tr::before { top: 10px; right: -10px; } .marks__c--tr::after { right: 10px; top: -10px; }
.marks__c--bl { bottom: 0; left: 0; } .marks__c--bl::before { bottom: 10px; left: -10px; } .marks__c--bl::after { left: 10px; bottom: -10px; }
.marks__c--br { bottom: 0; right: 0; } .marks__c--br::before { bottom: 10px; right: -10px; } .marks__c--br::after { right: 10px; bottom: -10px; }
.marks__reg {
  position: absolute; top: 50%; width: 22px; height: 22px; margin-top: -11px; border: 1.5px solid currentColor; border-radius: 50%;
  background:
    linear-gradient(currentColor, currentColor) center / 1.5px 32px no-repeat,
    linear-gradient(currentColor, currentColor) center / 32px 1.5px no-repeat;
  overflow: visible;
}
.marks__reg::after { content: ''; position: absolute; inset: 5px; border-radius: 50%; background: currentColor; opacity: 0.5; }
.marks__reg--l { left: -2px; } .marks__reg--r { right: -2px; }
@media (max-width: 699px) { .marks__reg { display: none; } .marks__c { transform: scale(0.75); } }

/* ---- Color bar ---- */
.cmyk { display: inline-block; width: 112px; height: 9px; background: var(--cmyk); border-radius: 1px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12); vertical-align: middle; }

/* ---- Ruler along a cutting mat's edge ---- */
.ruler {
  position: absolute; z-index: 0; left: 0; right: 0; top: 0; height: 30px; overflow: hidden; pointer-events: none;
  display: flex; color: rgba(255, 255, 255, 0.78);
  font: 700 10px/1 var(--font-body); letter-spacing: 0.02em;
  background:
    repeating-linear-gradient(90deg, currentColor 0 1px, transparent 1px 48px) 0 0 / 100% 14px no-repeat,
    repeating-linear-gradient(90deg, currentColor 0 1px, transparent 1px 24px) 0 0 / 100% 9px no-repeat,
    repeating-linear-gradient(90deg, currentColor 0 1px, transparent 1px 12px) 0 0 / 100% 5px no-repeat;
}
.ruler span { flex: none; width: 48px; padding: 16px 0 0 3px; }
.ruler--side { top: 30px; bottom: 0; left: 0; right: auto; width: 30px; height: auto; flex-direction: column;
  background:
    repeating-linear-gradient(currentColor 0 1px, transparent 1px 48px) 0 0 / 14px 100% no-repeat,
    repeating-linear-gradient(currentColor 0 1px, transparent 1px 24px) 0 0 / 9px 100% no-repeat,
    repeating-linear-gradient(currentColor 0 1px, transparent 1px 12px) 0 0 / 5px 100% no-repeat; }
.ruler--side span { width: auto; height: 48px; padding: 3px 0 0 16px; }

/* ---- Halftone fade (a corner of dots that thins out) ---- */
.halftone {
  position: absolute; z-index: 0; pointer-events: none; width: min(60vw, 720px); aspect-ratio: 1;
  background-image: var(--halftone); background-size: 11px 11px;
  -webkit-mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, 0.55) 45%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, 0.55) 45%, transparent 100%);
}


/* ---- src/styles/30-header.css ---- */
/* Floating nav: small, solid (no glass), rounded because it floats.
   Logo left · 4 links · Get a quote pill · Motion on/off pill. */
.site-header {
  position: fixed; z-index: 50; top: var(--nav-top); left: var(--gutter); right: var(--gutter);
  pointer-events: none;
}
/* The bar is light glass (the material is in 20-components.css): the page shows softly through it. */
.site-header__inner {
  pointer-events: auto;
  max-width: 1320px; margin: 0 auto; height: 52px;
  display: flex; align-items: center; gap: 10px; padding: 0 8px 0 10px;
  border-radius: 18px;
  --g-tint: var(--glass-clear-hi);
}
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--carbon); min-width: 0; margin-right: auto; }
.brand__badge { width: 36px; height: 36px; border-radius: 50%; flex: none; }
.brand__name {
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch);
  font-weight: var(--display-weight); font-size: calc(var(--display-scale) * 1.2rem); line-height: 1; letter-spacing: 0.01em;
  text-transform: uppercase; white-space: nowrap;
}

.site-nav__list { list-style: none; display: flex; gap: 4px; }
.site-nav__list a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px; border-radius: 10px;
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-weight: 700; font-size: calc(var(--label-scale) * 0.78rem);
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--carbon); text-decoration: none; white-space: nowrap;
  transition: background-color var(--dur-fade) ease;
}
.site-nav__list a:hover { background: var(--liner); }
.site-nav__toggle { display: none; }

/* Pills: glass capsules inside the glass bar (solid enough not to stack two see-through layers). */
.pill {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 40px; padding: 0 16px;
  border-radius: 999px; border: 0; color: var(--carbon);
  background: linear-gradient(170deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.55));
  box-shadow: inset 0 1px 0.5px #fff, inset 0 0 0 1px rgba(18, 20, 23, 0.16), 0 3px 10px -6px rgba(10, 14, 20, 0.45);
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-weight: 800; font-size: calc(var(--label-scale) * 0.76rem);
  letter-spacing: 0.06em; text-transform: uppercase; text-decoration: none; white-space: nowrap;
  transition: transform 400ms var(--spring-pop), filter var(--dur-fade) ease;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.pill:hover { filter: brightness(1.04); }
.pill:active { transform: scale(1.06); transition-duration: 160ms; }
.pill--quote {
  background: linear-gradient(170deg, rgba(255, 255, 255, 0.38), rgba(255, 255, 255, 0) 55%), var(--glass-green);
  box-shadow: inset 0 1px 0.5px var(--glass-rim), inset 0 0 0 1px rgba(255, 255, 255, 0.25), 0 4px 14px -6px rgba(10, 60, 25, 0.6);
}
.pill--motion { order: 10; }
.pill__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px var(--green-tint); }
.pill--motion[aria-pressed="false"] .pill__dot { background: transparent; border: 2px solid var(--ink-soft); box-shadow: none; }
.site-header .pill { min-height: 40px; }
@media (pointer: coarse) { .site-header .pill { min-height: 44px; } }

/* Small laptops (900–1079px): the labels are big enough that everything won't fit in one bar, so the Motion
   pill shows just its dot (as on phones; its name stays in the tooltip and for screen readers) and the
   links sit a little closer. */
@media (min-width: 900px) and (max-width: 1079px) {
  .pill--motion { width: 40px; padding: 0; }
  .pill--motion [data-motion-label] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .site-nav__list a { padding: 0 9px; }
}

@media (max-width: 899px) {
  .site-header { left: 10px; right: 10px; }
  .site-header__inner { height: 56px; gap: 6px; padding: 0 6px 0 8px; }
  .brand__name { font-size: calc(var(--display-scale) * 1.05rem); }
  .pill { padding: 0 12px; }
  .pill--motion { order: 0; width: 44px; padding: 0; }
  .pill--motion [data-motion-label] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .site-nav { order: 11; }
  .site-nav__toggle {
    display: grid; place-items: center; width: 44px; height: 44px; border: 0; border-radius: 999px; padding: 0;
    background: linear-gradient(170deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.55));
    box-shadow: inset 0 1px 0.5px #fff, inset 0 0 0 1px rgba(18, 20, 23, 0.16), 0 3px 10px -6px rgba(10, 14, 20, 0.45);
  }
  .site-nav__toggle:active { transform: scale(1.06); }
  .site-nav__toggle-bars, .site-nav__toggle-bars::before, .site-nav__toggle-bars::after {
    display: block; width: 16px; height: 2px; background: var(--carbon); content: ''; position: relative; transition: transform 200ms var(--spring);
  }
  .site-nav__toggle-bars::before { position: absolute; top: -5px; }
  .site-nav__toggle-bars::after { position: absolute; top: 5px; }
  .site-nav__toggle[aria-expanded="true"] .site-nav__toggle-bars { background: transparent; }
  .site-nav__toggle[aria-expanded="true"] .site-nav__toggle-bars::before { transform: translateY(5px) rotate(45deg); }
  .site-nav__toggle[aria-expanded="true"] .site-nav__toggle-bars::after { transform: translateY(-5px) rotate(-45deg); }
  html.js .site-nav__list {
    position: absolute; left: 0; right: 0; top: calc(100% + 8px);
    display: grid; gap: 0; padding: 8px; border-radius: 22px;
    background: linear-gradient(165deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 50%), var(--glass-clear-hi);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat)); backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    box-shadow: inset 0 1px 0.5px var(--glass-rim), inset 0 0 0 1px rgba(255, 255, 255, 0.3), var(--glass-shadow-lg);
    transform-origin: top right; transition: transform 260ms var(--spring), opacity 160ms ease, visibility 0s 260ms;
    transform: translateY(-6px) scale(0.98); opacity: 0; visibility: hidden;
  }
  html.js .site-nav.is-open .site-nav__list { transform: none; opacity: 1; visibility: visible; transition: transform 260ms var(--spring), opacity 160ms ease; }
  .site-nav__list a { min-height: 52px; width: 100%; font-size: 1rem; border-radius: 14px; }
  html.no-js .site-nav__toggle { display: none; }
  html.no-js .site-header { position: absolute; }
  html.no-js .site-header__inner { flex-wrap: wrap; height: auto; padding-block: 6px; }
  html.no-js .site-nav { order: 12; flex-basis: 100%; }
}
/* Phones: badge only, so the quote pill, Motion pill and menu always fit. */
@media (max-width: 519px) {
  .brand__name { display: none; }
}

/* Pages without a full-screen hero leave room for the floating nav. */
body:not(.has-hero):not(.is-admin) main { padding-top: calc(var(--nav-top) + 52px); }


/* ---- src/styles/40-hero.css ---- */
/* HERO · the scroll walk-in (board 1–3): the last 4 seconds of your shop video, frame by frame, ending on the logo.
   Motion on:  the section is several screens tall; the stage stays pinned (CSS sticky) while
               src/client/walkin.js draws frames on the canvas. Scroll speed is native.
   Motion off / reduced motion / no JS: one screen, a still of the video's last frame (the logo). */
.walkin {
  position: relative;
  height: calc(var(--screens-d, 2.4) * 100svh);
  background: var(--carbon);
}
@media (orientation: portrait) { .walkin { height: calc(var(--screens-m, 2.2) * 100svh); } }
html.motion-off .walkin, html.no-js .walkin { height: auto; }

.walkin__stage {
  position: sticky; top: var(--pbar);
  height: calc(100lvh - var(--pbar));
  overflow: hidden; isolation: isolate; color: var(--photo-ink);
}
html.motion-off .walkin__stage, html.no-js .walkin__stage {
  position: relative; top: 0; height: calc(100svh - var(--pbar)); min-height: 540px;
}

.walkin__poster, .walkin__canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.walkin__poster img { width: 100%; height: 100%; object-fit: cover; }
/* Motion on: the first frame shows instantly, then the canvas takes over.
   Motion off / no JS: the last frame (the logo) instead. */
.walkin__poster--end { display: none; }
html.motion-off .walkin__poster--start, html.no-js .walkin__poster--start { display: none; }
html.motion-off .walkin__poster--end, html.no-js .walkin__poster--end { display: block; }
html.motion-off .walkin__canvas, html.no-js .walkin__canvas { display: none; }
.walkin__canvas { opacity: 0; transition: opacity 200ms linear; }
.walkin.is-live .walkin__canvas { opacity: 1; }

/* Legibility for the text at the bottom and the nav at the top. */
.walkin__shade {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to top, rgba(10, 12, 14, 0.8) 0%, rgba(10, 12, 14, 0.36) 28%, rgba(10, 12, 14, 0) 50%),
    linear-gradient(to bottom, rgba(10, 12, 14, 0.36) 0%, rgba(10, 12, 14, 0) 18%);
}

/* ---- Bottom-left: always visible, from the first frame ---- */
.walkin__info {
  position: absolute; z-index: 2;
  left: var(--gutter); right: var(--gutter);
  bottom: calc(100lvh - 100svh + clamp(20px, 4.5vh, 52px));
  max-width: 1000px;
}
.walkin__h1 { margin: 0; color: var(--photo-ink); }
.walkin__brand {
  display: block;
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  /* Sized to fit: about 44% of the width on desktop, the full width on phones. */
  font-size: min(calc(44vw / var(--brand-em)), 12svh);
  line-height: var(--mega-lead); letter-spacing: var(--mega-track); text-transform: uppercase; white-space: nowrap;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.35);
}
.walkin__tag {
  display: block; margin-top: 0.6rem;
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-weight: 750;
  font-size: calc(var(--label-scale) * clamp(0.82rem, 0.74rem + 0.4vw, 1.08rem));
  letter-spacing: 0.1em; text-transform: uppercase; color: rgba(255, 255, 255, 0.94);
}
.walkin__meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; margin-top: 10px;
  font-size: var(--size-small); color: rgba(255, 255, 255, 0.86);
}
.walkin__meta a { color: var(--photo-ink); }
.walkin__meta .open-status { color: var(--photo-ink); }
.walkin__meta .open-status.is-closed .open-status__dot { border-color: rgba(255, 255, 255, 0.8); }
.walkin__meta .uv { text-decoration-color: rgba(255, 255, 255, 0.7); }
.walkin__meta .uv-mark, .walkin__brand .uv-mark { color: var(--photo-ink); }
.walkin__actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
/* The hero's buttons are glass (20-components.css): green for Get a quote, dark glass for Call. */
.walkin :focus-visible { outline-color: var(--white); }

.walkin__hint {
  position: absolute; z-index: 2; right: var(--gutter); bottom: clamp(96px, 14vh, 140px); /* above the chat button */
  display: flex; align-items: center; gap: 12px;
  font-family: var(--font-label); font-weight: 700; font-size: calc(var(--label-scale) * 0.61rem); letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
}
.walkin__hint::after { content: ''; width: 1.5px; height: 44px; background: linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0)); }
html.motion-off .walkin__hint, html.no-js .walkin__hint { display: none; }

@media (max-width: 699px) {
  .walkin__brand { font-size: min(calc((100vw - 2 * var(--gutter)) / var(--brand-em)), 11svh); }
  .walkin__actions .btn { flex: 1 1 auto; }
  .walkin__actions .btn__detail { display: none; }
  .walkin__hint { display: none; }
}


/* ---- src/styles/45-intro.css ---- */
/* SECTION 3 · INTRO: giant headline + work cards (board 4). Motion: src/client/scenes/intro.js
   Desktop, Motion on: the cards are dealt out of a pile as you scroll in, then drift toward the cursor.
   Phones, Motion on: the cards sit in a fan that opens as you scroll and turns when you drag it.
   Motion off / no JS: the cards sit in a neat row under the headline. */
.intro { position: relative; background-color: var(--substrate); overflow: clip; }
.intro__stage {
  position: relative; min-height: 100svh;
  display: flex; flex-direction: column;
  padding: calc(var(--nav-top) + 72px) var(--gutter) clamp(1.75rem, 5vh, 3.5rem);
}
.intro__ghost { left: -1.5vw; bottom: -2.5vw; font-size: 25vw; }

.intro__mega {
  position: relative; z-index: 1; margin: 0;
  font-size: calc(58vw / var(--brand-em)); color: var(--navy); /* about right before fit.js sizes it */
}
.intro__mega .fitline {
  /* A quiet brand gradient across the letters: navy into sign green. */
  background: linear-gradient(98deg, var(--navy) 0%, var(--navy) 52%, var(--navy-deep) 70%, #17913B 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  padding-right: 0.04em; /* the italic faces lean past their box */
}
.intro__mega .uv-mark { color: var(--navy); }

/* ---- the cards: photo prints with a white border ----
   --lift (0-1) deepens the shadow; --shx/--sho move and show the glossy sheen; --dim darkens cards that
   step back while another is picked up. All set by scenes/intro.js. */
.wcard { -webkit-user-select: none; user-select: none; -webkit-user-drag: none; -webkit-touch-callout: none;
  --lift: 0; --sho: 0; --shx: 120%; --dim: 0;
  position: relative; display: block; margin: 0;
  padding: 5px; border-radius: 12px; background: var(--white);
  box-shadow: 0 1px 2px rgba(12, 18, 28, 0.12),
    0 calc(22px + var(--lift) * 26px) calc(40px + var(--lift) * 34px) calc(-22px + var(--lift) * -4px) rgba(12, 18, 28, calc(0.55 + var(--lift) * 0.12));
  color: inherit; text-decoration: none;
  -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; user-select: none;
}
.wcard__pic { aspect-ratio: 4 / 3; border-radius: 8px; }
.wcard__pic picture, .print__pic picture { width: 100%; height: 100%; }
.wcard--tall .wcard__pic { aspect-ratio: 3 / 4; }
.wcard img { -webkit-user-drag: none; }
a.wcard:focus-visible { outline-offset: 4px; }
/* glossy sheen that slides across the print as you move over it */
.wcard::after {
  content: ''; position: absolute; inset: 5px; border-radius: 8px; pointer-events: none; z-index: 2;
  background: linear-gradient(112deg, rgba(255, 255, 255, 0) 32%, rgba(255, 255, 255, 0.5) 47%, rgba(255, 255, 255, 0.12) 53%, rgba(255, 255, 255, 0) 64%);
  background-size: 260% 100%; background-position: var(--shx) 0;
  opacity: var(--sho); mix-blend-mode: soft-light;
}
.wcard::before { content: ''; position: absolute; inset: 0; border-radius: inherit; z-index: 3; pointer-events: none; background: rgba(18, 20, 23, 0.22); opacity: var(--dim); }

/* Neat row (Motion off, no JS, and the first paint before the scene starts). */
.intro__cards {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(46%, 190px), 1fr)); gap: 18px; align-items: start;
  margin: clamp(1.5rem, 4vh, 2.5rem) 0;
}
.intro__cards .wcard { transform: rotate(calc(var(--r) * 0.35deg)); }

/* "Tidy up": shows once a card has been moved (desktop). */
.intro__tidy { position: absolute; z-index: 4; right: calc(var(--gutter) + 96px); bottom: clamp(1.75rem, 5vh, 3.5rem); }

/* Desktop, Motion on: cards scattered over the right of the headline (spots in sections/intro.mjs). */
@media (min-width: 700px) {
  html.motion-on .intro__cards { position: absolute; inset: 0; margin: 0; display: block; pointer-events: none; }
  html.motion-on .intro__cards .wcard {
    position: absolute; left: calc(var(--x) * 1%); top: calc(var(--y) * 1%);
    width: calc(var(--w) * 1vw); pointer-events: auto; cursor: grab; touch-action: pan-y;
    transform: translate(-50%, -50%) rotate(calc(var(--r) * 1deg));
    will-change: transform;
  }
  html.motion-on .intro__cards .wcard.is-grabbed { cursor: grabbing; }
  /* Portrait photos run narrower so every card is about the same size. */
  html.motion-on .intro__cards .wcard--tall { width: calc(var(--w) * 0.74vw); }
  html.motion-on .intro__foot { margin-top: auto; }
}

/* Phones, Motion on: a messy stack of prints. Swipe the top one away to see the next. */
@media (max-width: 699px) {
  html.motion-on .intro__cards { display: block; height: 92vw; margin: 4vw 0 8vw; touch-action: pan-y; }
  html.motion-on .intro__cards .wcard {
    position: absolute; left: 50%; top: 50%; width: 62vw;
    transform: translate(-50%, -50%) rotate(calc((var(--i) - 2) * 4deg));
    will-change: transform;
  }
  html.motion-on .intro__cards .wcard--tall { width: 50vw; }
  .intro__mega { font-size: 24vw; }
  .intro__tidy { display: none; }
}
/* ---- paragraph + button, bottom left ---- */
.intro__foot { position: relative; z-index: 3; max-width: 27rem; display: grid; gap: 18px; justify-items: start; }
.intro__body { font-size: var(--size-lede); line-height: 1.45; color: var(--carbon); }
.intro__hint { font-size: var(--size-small); color: var(--ink-soft); }
.intro__hint-touch { display: none; }
@media (hover: none), (pointer: coarse) {
  .intro__hint-mouse { display: none; }
  .intro__hint-touch { display: inline; }
}
html.motion-off .intro__hint, html.no-js .intro__hint { display: none; }

/* Grabbing a print: no text selection, no browser image-drag, the grab cursor. */
.wcard img { -webkit-user-drag: none; user-select: none; pointer-events: none; }
@media (hover: hover) and (pointer: fine) { html.motion-on .intro__cards .wcard { cursor: grab; } html.motion-on .intro__cards .wcard.is-grabbed { cursor: grabbing; } }


/* ---- src/styles/50-road.css ---- */
/* SECTIONS 4 + 5 · ROAD: a phone frame showing the shop grows until it IS the screen (board 5),
   then one huge line slides sideways over the photo as you scroll (board 6). Motion: scenes/road.js
   Motion on: the section is ~4 screens tall and the stage stays pinned (CSS sticky); scroll speed is native.
   First the story beside the phone: headline + button (left), three step cards (right) that fly into the phone.
   Motion off / no JS: one screen: the photo, full bleed, with the line on it. */
.road { position: relative; background: var(--carbon); color: var(--photo-ink); }
html.motion-on .road { height: 380svh; }

.road__stage { position: relative; height: calc(100svh - var(--pbar)); min-height: 540px; overflow: hidden; isolation: isolate; }
html.motion-on .road__stage { position: sticky; top: var(--pbar); height: calc(100lvh - var(--pbar)); min-height: 0; }

/* The phone's screen (portrait, centered). The photo is clipped to it, then the clip opens to full bleed. */
.road { --ph: min(74svh, 660px); --pw: calc(var(--ph) * 0.48); --pr: 34px; }

.road__photo { position: absolute; inset: 0; }
.road__photo picture, .road__photo img { width: 100%; height: 100%; }
.road__photo img { object-fit: cover; }
.road__dim { position: absolute; inset: 0; background: rgba(10, 12, 14, 0.5); }
html.motion-on .road__photo {
  clip-path: inset(calc((100% - var(--ph)) / 2) calc((100% - var(--pw)) / 2) round var(--pr));
  will-change: clip-path;
}
html.motion-on .road__photo img { transform: scale(1.18); will-change: transform; }
html.motion-on .road__dim { opacity: 0; }

/* The phone's screen: a proof sheet of one real W&W job from every side, on backing paper
   (copy: road.chart; the views are renders made from photos of the job, and the note says so). The tiles
   are 4:3 like the renders, so every truck shows whole. Sized to the screen and drawn in screen units
   (cqw), so it reads the same on a desktop phone (~320px) and a phone's phone (~200px). Fades as the
   phone opens (scenes/road.js). */
.road__chart { display: none; }
html.motion-on .road__chart {
  position: absolute; left: 50%; top: 50%; z-index: 1; width: var(--pw); height: var(--ph); translate: -50% -50%;
  display: block; container-type: size;
  background-color: var(--substrate); background-image: var(--paper-grid); background-size: var(--paper-grid-size);
  color: var(--navy); will-change: opacity;
}
/* Spacing lives on the inner box: its cqw units measure the screen (the chart is the container). */
.road__chart-in { display: flex; flex-direction: column; justify-content: center; gap: 4cqw; height: 100%; padding: 17cqw 6cqw 7cqw; }
.road__chart-head { display: grid; gap: 1.2cqw; margin: 0; }
.road__chart-title {
  font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight); font-stretch: var(--display-stretch);
  font-size: 15cqw; line-height: 0.88; text-transform: uppercase; letter-spacing: -0.01em;
}
.road__chart-sub, .road__chart-note { font-family: var(--font-label); font-weight: var(--label-weight); font-stretch: var(--label-stretch); text-transform: uppercase; letter-spacing: 0.04em; color: var(--carbon); }
.road__chart-sub { font-size: 5.2cqw; }
.road__chart-grid { flex: none; display: grid; grid-template-columns: 1fr 1fr; gap: 2.6cqw; margin: 0; padding: 0; list-style: none; }
.road__chart-tile { position: relative; overflow: hidden; aspect-ratio: 4 / 3; border-radius: 2.6cqw; background: #E2E5EA; box-shadow: 0 0 0 1px rgba(18, 20, 23, 0.1); }
.road__chart-tile .pic, .road__chart-tile picture { position: absolute; inset: 0; }
html.motion-on .road__chart-tile img { width: 100%; height: 100%; object-fit: cover; transform: none; }
.road__chart-label {
  position: absolute; left: 1.8cqw; bottom: 1.8cqw; padding: 0.8cqw 2cqw; border-radius: 99px;
  background: rgba(255, 255, 255, 0.92); color: var(--carbon);
  font-family: var(--font-label); font-weight: var(--label-weight); font-stretch: var(--label-stretch); font-size: 4.2cqw; line-height: 1.15; text-transform: uppercase;
}
.road__chart-note { display: flex; align-items: center; gap: 2cqw; margin: 0; font-size: 4.4cqw; }

/* Behind the phone: the shop itself, dark and out of focus like a camera's background, lit by the
   green glow of the W&W sign. (A small image, blurred once; it doesn't move, so it costs nothing to scroll.) */
.road__backdrop { position: absolute; inset: -6%; display: none; }
.road__backdrop img { width: 100%; height: 100%; object-fit: cover; filter: blur(26px) brightness(0.42) saturate(1.2); transform: scale(1.06); }
.road__glow {
  position: absolute; inset: 0; display: none; pointer-events: none;
  background:
    radial-gradient(48% 38% at 50% 92%, rgba(29, 170, 71, 0.32), rgba(29, 170, 71, 0) 70%),
    radial-gradient(90% 70% at 50% 50%, rgba(0, 0, 0, 0) 40%, rgba(5, 7, 8, 0.65) 100%);
}
html.motion-on .road__backdrop, html.motion-on .road__glow { display: block; }

/* The phone itself: a black bezel and the camera island. Only with Motion on. */
.road__phone { display: none; }
html.motion-on .road__phone {
  display: block; position: absolute; z-index: 2; left: 50%; top: 50%;
  width: calc(var(--pw) + 22px); height: calc(var(--ph) + 22px);
  translate: -50% -50%;
  border: 11px solid #0B0C0E; border-radius: calc(var(--pr) + 11px);
  /* a thin metal band, light catching its top edge, and the sign's green glow under it */
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 0 2px rgba(120, 128, 136, 0.35),
    0 50px 90px -30px rgba(0, 0, 0, 0.8), 0 30px 120px -40px rgba(29, 170, 71, 0.45);
  pointer-events: none; will-change: transform, opacity;
}
/* The glass glare that slides across the screen as the phone tilts toward the cursor (desktop). */
.road__glare {
  position: absolute; inset: 0; border-radius: var(--pr); pointer-events: none; opacity: var(--go, 0);
  background: linear-gradient(112deg, rgba(255, 255, 255, 0) calc(var(--gx, 50%) - 24%), rgba(255, 255, 255, 0.17) var(--gx, 50%), rgba(255, 255, 255, 0) calc(var(--gx, 50%) + 20%));
  mix-blend-mode: screen;
}

/* ---- The story beside the phone (Motion on only; Motion off keeps the one-screen photo + line). ---- */
.road__story { display: none; }
html.motion-on .road__story { display: block; position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.road__pitch {
  position: absolute; left: calc(var(--gutter) + 1vw); top: 50%; translate: 0 -50%;
  width: min(36vw, calc(50% - var(--pw) / 2 - 7vw)); color: var(--photo-ink); will-change: transform, opacity;
}
.road__title {
  margin: 0 0 18px; font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch);
  font-weight: var(--display-weight); font-size: calc(var(--display-scale) * clamp(2.4rem, 0.9rem + 3vw, 4.4rem));
  line-height: var(--mega-lead); letter-spacing: var(--mega-track); text-transform: uppercase; text-wrap: balance;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.45);
}
.road__body { margin: 0 0 26px; max-width: 34ch; font-size: 1.12rem; line-height: 1.5; color: rgba(255, 255, 255, 0.84); text-shadow: 0 1px 14px rgba(0, 0, 0, 0.5); }
.road__cta { pointer-events: auto; }
.road__steps {
  position: absolute; right: calc(var(--gutter) + 1vw); top: 50%; translate: 0 -50%; margin: 0; padding: 0; list-style: none;
  width: min(25vw, calc(50% - var(--pw) / 2 - 7vw)); display: grid; gap: 14px;
}
.road__step {
  display: flex; gap: 14px; align-items: center; padding: 14px 18px 14px 14px; border-radius: 24px;
  color: var(--photo-ink); margin-left: calc(var(--i) * 22px); will-change: transform, opacity;
}
.road__step-icon { flex: none; display: grid; place-items: center; width: 46px; height: 46px; border-radius: 13px; background: var(--green); color: var(--carbon); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35); }
.road__step-icon .i { width: 25px; height: 25px; }
.road__step-text { min-width: 0; }
.road__step-text b { display: block; font-size: 1.06rem; font-weight: 800; line-height: 1.2; }
.road__step-text small { display: block; margin-top: 2px; font-size: 0.9rem; line-height: 1.35; color: rgba(255, 255, 255, 0.76); }

/* Narrower screens: the headline sits just above the phone, the steps are small chips just below it. */
@media (max-width: 999px) {
  html.motion-on .road { --ph: min(50svh, 520px); }
  .road__pitch { left: var(--gutter); right: var(--gutter); top: auto; bottom: calc(50% + var(--ph) / 2 + 30px); translate: none; width: auto; text-align: center; }
  .road__title { margin: 0; font-size: calc(var(--display-scale) * clamp(1.6rem, 6.4vw, 2.6rem)); }
  .road__body, .road__cta { display: none; }
  .road__steps { left: var(--gutter); right: var(--gutter); top: calc(50% + var(--ph) / 2 + 26px); translate: none; width: auto; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
  .road__step { margin: 0; gap: 8px; padding: 6px 13px 6px 6px; border-radius: 999px; }
  .road__step-icon { width: 26px; height: 26px; border-radius: 50%; }
  .road__step-icon .i { width: 15px; height: 15px; }
  .road__step-text b { font-size: 0.8rem; white-space: nowrap; }
  .road__step-text small { display: none; }
}

/* Whole pixels for the phone and its screen (browsers with CSS round()): a screen sitting on a half pixel is
   resampled, which softens the photos and text on it. */
@supports (width: round(down, 10.5px, 2px)) {
  .road { --pw: round(down, calc(var(--ph) * 0.48), 2px); }
  html.motion-on .road__chart {
    height: round(down, var(--ph), 2px); translate: none;
    left: round(down, calc(50% - var(--pw) / 2), 1px); top: round(down, calc(50% - var(--ph) / 2), 1px);
  }
  html.motion-on .road__phone {
    height: calc(round(down, var(--ph), 2px) + 22px); translate: none;
    left: round(down, calc(50% - var(--pw) / 2 - 11px), 1px); top: round(down, calc(50% - var(--ph) / 2 - 11px), 1px);
  }
}

.road__notch { position: absolute; top: 9px; left: 50%; width: 30%; height: 22px; translate: -50% 0; border-radius: 11px; background: #0B0C0E; }

/* The sliding line: two copies back to back so it never runs out. */
.road__slide {
  position: absolute; z-index: 3; left: 0; top: 50%; translate: 0 -50%;
  display: flex; margin: 0; white-space: nowrap;
  font-size: 17vw; color: var(--photo-ink);
  text-shadow: 0 4px 40px rgba(0, 0, 0, 0.35);
}
.road__slide span { padding-right: 0.28em; }
html.motion-on .road__slide { will-change: transform, opacity; opacity: 0; }
html.motion-off .road__slide, html.no-js .road__slide {
  right: 0; padding: 0 var(--gutter); white-space: normal; font-size: clamp(2.6rem, 9vw, 9rem); text-wrap: balance;
}
html.motion-off .road__slide span + span, html.no-js .road__slide span + span { display: none; }

.road__ghost { z-index: 1; top: calc(var(--nav-top) + 70px); left: 0; font-size: 19vw; }
html.motion-on .road__ghost { opacity: 0; }

@media (max-width: 699px) {
  .road { --ph: min(66svh, 560px); --pr: 28px; }
  html.motion-on .road { height: 330svh; }
  .road__slide { font-size: 26vw; }
}
@media (orientation: landscape) and (max-height: 520px) {
  .road, html.motion-on .road { --ph: 80svh; }
  html.motion-on .road__story { display: none; } /* no room beside a sideways phone */
}


/* ---- src/styles/55-stack.css ---- */
/* SECTION 6 · STACK: the gallery as a 3D stack of photo prints (board 7). Motion: scenes/stack.js
   Motion on: pinned for a while; scrolling deals the top prints off the stack, and you can drag,
   swipe, use the arrows or the arrow keys to cycle them (springs + momentum). The front print opens the viewer.
   Motion off / no JS: the same prints in a neat grid, each a link to its job page. */
.stack { position: relative; background-color: var(--liner); }
html.motion-on .stack { height: 240svh; }

.stack__stage {
  position: relative; overflow: clip;
  padding: calc(var(--nav-top) + 76px) var(--gutter) clamp(2.5rem, 6vh, 4rem);
}
html.motion-on .stack__stage {
  position: sticky; top: var(--pbar); height: calc(100lvh - var(--pbar));
  display: flex; flex-direction: column; padding-bottom: 20px;
}
.stack__ghost { right: -4vw; bottom: -4vw; font-size: 36vw; }

.stack__title { position: relative; z-index: 1; margin: 0; font-size: calc(43vw / var(--brand-em)); color: var(--carbon); }
.stack .tabs { position: relative; z-index: 4; margin-top: 14px; align-self: flex-start; }

/* ---- a print: white border, the photo, a handwritten-style caption strip ---- */
.print {
  position: relative; display: block;
  padding: 9px 9px 0; border-radius: 10px; background: var(--white);
  box-shadow: 0 1px 2px rgba(12, 18, 28, 0.1), 0 26px 50px -26px rgba(12, 18, 28, 0.6);
  color: var(--carbon); text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.print:hover { text-decoration: none; }
.print__photo { display: block; position: relative; aspect-ratio: 4 / 3; overflow: hidden; border-radius: 5px; background: var(--liner); }
.print__pic { width: 100%; height: 100%; }
.print__caption { position: relative; display: grid; gap: 2px; padding: 10px 58px 13px 4px; }
/* the color-calibration strip printed on the edge of every print */
.print__caption::after { content: ''; position: absolute; right: 4px; bottom: 14px; width: 46px; height: 6px; border-radius: 1px; background: var(--cmyk); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); }
.print__title {
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.15rem); line-height: 1; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.print__meta { font-size: 0.86rem; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.print__new {
  position: absolute; z-index: 2; top: -14px; right: -12px; rotate: 10deg;
  display: grid; place-items: center; width: 62px; aspect-ratio: 1; border-radius: 50%;
  background: var(--green); box-shadow: 0 0 0 4px var(--white);
  font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 0.95rem); text-transform: uppercase;
}

/* "Photo needed": an intentional stand-in, never fake work. */
.print__needed {
  position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 10px; padding: 16px; text-align: center;
  background: repeating-linear-gradient(-12deg, transparent 0 20px, rgba(18, 20, 23, 0.05) 20px 21.5px), var(--liner);
}
.print__needed-cat {
  font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.6rem); line-height: 0.95; text-transform: uppercase; color: var(--navy);
}
.print__needed-stamp { padding: 3px 10px; border: 2px solid var(--carbon); font-weight: 700; font-size: 0.82rem; rotate: -3deg; }

/* Before/after demo tile (placeholder until real before photos exist). */
.print__ba { position: absolute; inset: 0; display: grid; grid-template-columns: 1fr 1fr; }
.print__ba span {
  display: grid; place-items: center;
  font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.3rem); text-transform: uppercase;
}
.print__ba span:first-child { background: var(--liner); color: var(--ink-soft); }
.print__ba span:last-child { background: var(--navy); color: var(--white); }

/* ---- neat grid (Motion off, no JS) ---- */
.deck { position: relative; z-index: 2; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); gap: 26px; margin-top: clamp(1.5rem, 4vh, 2.5rem); }
.deck .print { transform: rotate(calc(var(--tilt) * 0.4)); }
.deck:focus-visible { outline-offset: 8px; }

/* ---- 3D stack (Motion on) ---- */
/* The deck fills the space left under the title and chips (its prints are absolutely placed, so the
   deck itself has no height unless every wrapper passes the space down). Wide screens: grid below. */
html.motion-on .stack__body, html.motion-on .stack__deckcol { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
html.motion-on .deck {
  display: block; flex: 1 1 auto; min-height: 0; margin: -1.6vw 0 0;
  perspective: 1600px; touch-action: pan-y; cursor: grab; user-select: none;
  --cw: clamp(230px, min(31vw, (100svh - 360px) * 1.08), 540px);
}
html.motion-on .deck.is-dragging { cursor: grabbing; }
html.motion-on .deck .print {
  position: absolute; left: 50%; top: 50%; width: var(--cw);
  translate: -50% -50%; transform: none;
  will-change: transform, opacity; backface-visibility: hidden;
}
html.motion-on .deck .print img { -webkit-user-drag: none; pointer-events: none; }
/* Prints far back in the pile are out of the page, so 100 jobs don't load 100 photos at once (scenes/stack.js). */
html.motion-on .deck .print.is-far { display: none; }

.deck-nav { position: relative; z-index: 4; display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 14px; }
.deck-nav__count {
  min-width: 4.5ch; text-align: center;
  font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.4rem); font-variant-numeric: tabular-nums;
}
.deck-nav__hint { font-size: var(--size-small); color: var(--ink-soft); }
html.motion-off .deck-nav, html.no-js .deck-nav { display: none; }

.stack__empty { position: relative; z-index: 2; margin-top: 2rem; font-size: var(--size-lede); max-width: 32rem; }

@media (max-width: 699px) {
  html.motion-on .stack { height: 200svh; }
  html.motion-on .deck { --cw: min(72vw, (100svh - 400px) * 1.05); margin-top: 6px; }
  .deck-nav__hint { display: none; }
  /* One row of filters you can swipe sideways, so the stack keeps the screen. */
  .stack .tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; align-self: stretch; }
  .stack .tabs::-webkit-scrollbar { display: none; }
  .stack .tab { flex: none; min-height: 44px; padding: 0 13px; }
  html.motion-on .stack__stage { padding-top: calc(var(--nav-top) + 64px); padding-bottom: calc(12px + var(--sticky-h)); }
}

/* ---- desktop (≥1100px, Motion on): the stack on the left, the front job's details on the right ---- */
.stack__detail[hidden] { display: none; }
@media (min-width: 1100px) {
  html.motion-on .stack__body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(320px, 0.8fr); gap: clamp(2rem, 4vw, 4.5rem); align-items: center; }
  html.motion-on .stack__deckcol { display: flex; flex-direction: column; height: 100%; min-height: 0; }
  html.motion-on .stack__body .deck { --cw: clamp(230px, min(28vw, (100svh - 380px) * 1.08), 500px); }
  .stack__detail {
    position: relative; z-index: 3; align-self: center; max-width: 30rem; padding: clamp(1.5rem, 2.4vw, 2.2rem);
    border-radius: 26px; background: rgba(255, 255, 255, 0.78); -webkit-backdrop-filter: blur(16px) saturate(160%); backdrop-filter: blur(16px) saturate(160%);
    box-shadow: inset 0 1px 0 #fff, inset 0 0 0 1px rgba(18, 20, 23, 0.08), 0 24px 50px -30px rgba(12, 18, 28, 0.55);
  }
  .stack__detail-title {
    margin: 0.5rem 0 0.8rem; color: var(--navy); font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight);
    font-size: calc(var(--display-scale) * clamp(2rem, 1.2rem + 1.8vw, 3.2rem)); line-height: 0.95; text-transform: uppercase; text-wrap: balance;
  }
  .stack__detail-cap { margin: 0 0 0.6rem; font-size: 1.08rem; line-height: 1.5; color: var(--ink); }
  .stack__detail-meta { margin: 0 0 1.2rem; color: var(--ink-soft); font-weight: 600; }
  .stack__detail-actions { display: flex; flex-wrap: wrap; gap: 10px; }
}


/* ---- src/styles/60-statement-dots.css ---- */
/* SECTION 7 · STATEMENT: centered, huge, all caps. Words fill from pale to ink as you scroll;
   the last line lands in green (board 8). Motion: scenes/statement.js
   Motion off / no JS: shown fully filled. */
.statement { position: relative; background-color: var(--substrate); overflow-x: clip; }
html.motion-on .statement { height: 230svh; }
.statement__stage {
  position: relative; min-height: 100svh;
  display: grid; grid-template-columns: minmax(0, 1fr); align-content: center; justify-items: center; gap: clamp(1.75rem, 5vh, 3.5rem);
  padding: 16vh var(--gutter); text-align: center;
}
html.motion-on .statement__stage { position: sticky; top: var(--pbar); height: calc(100lvh - var(--pbar)); min-height: 0; padding-block: 0; }

.statement__text { position: relative; width: 100%; margin: 0; color: var(--carbon); }
.statement__line { display: block; font-size: 8.5vw; line-height: 0.9; text-wrap: balance; }
/* With JS, each line is one line, sized to fill (src/client/fit.js); very long lines wrap on phones. */
html.js .statement__line { width: max-content; max-width: none; margin-inline: auto; white-space: nowrap; }
html.js .statement__line.is-wrapped { width: auto; white-space: normal; line-height: 0.92; }
.sw { position: relative; display: inline-block; }
.sw__base { color: #D6D2C8; }
.sw__ink { position: absolute; left: 0; top: 0; color: var(--carbon); }
/* Green that still reads as large text on the backing-paper background (3.9:1). */
.statement__line--last .sw__ink { color: #17913B; }
html.motion-off .sw__base, html.no-js .sw__base { color: var(--carbon); }
html.motion-off .statement__line--last .sw__base, html.no-js .statement__line--last .sw__base { color: #17913B; }
html.motion-off .sw__ink, html.no-js .sw__ink { display: none; }
.statement__mark { position: absolute; top: 0; right: 0; }
.statement__next { --size: clamp(8.5rem, 7rem + 4vw, 10.5rem); rotate: -8deg; }
html.motion-on .statement__next { will-change: transform; }

/* SECTION 8 · DOTS: "W&W" printed in dots, like the shop's wide-format printer (board 9).
   Motion on: the section is 2+ screens tall and the stage holds still (CSS sticky) while a print head
   prints the letters in four passes as you scroll (scenes/dots.js); then the dots push away from the
   cursor or a finger and settle back. Motion off: the finished dots, still. No JS: the letters, outlined. */
.dots { position: relative; color: var(--substrate); background: radial-gradient(80% 60% at 50% 45%, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0) 70%), var(--navy); }
/* a faint print grid behind the dots */
.dots__grid { position: absolute; inset: 0; pointer-events: none; background-image: linear-gradient(rgba(246, 245, 241, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(246, 245, 241, 0.05) 1px, transparent 1px); background-size: 48px 48px; background-position: center; }
.dots__stage { position: relative; height: 100svh; min-height: 520px; max-height: 1080px; overflow: hidden; touch-action: pan-y; }
html.motion-on .dots { height: 230svh; }
html.motion-on .dots__stage { position: sticky; top: var(--pbar); height: calc(100lvh - var(--pbar)); min-height: 0; max-height: none; }
.dots__canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.dots__fallback {
  position: absolute; inset: 0; display: grid; place-items: center; margin: 0;
  font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight);
  font-size: 34vw; line-height: 1; text-transform: uppercase;
  color: transparent; -webkit-text-stroke: var(--outline-w) rgba(246, 245, 241, 0.7);
}
.dots.is-drawn .dots__fallback { visibility: hidden; }
.dots__hint {
  position: absolute; left: 50%; bottom: clamp(20px, 6vh, 56px); translate: -50% 0; margin: 0;
  font-size: var(--size-small); font-weight: 600; color: rgba(246, 245, 241, 0.78); white-space: nowrap;
}
html.motion-off .dots__hint, html.no-js .dots__hint { display: none; }
/* The hint waits until the print is done. */
html.motion-on .dots__hint { transition: opacity 0.4s ease, translate 0.5s var(--spring); }
html.motion-on .dots:not(.is-printed) .dots__hint { opacity: 0; translate: -50% 8px; }
.dots__hint::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 10px; border-radius: 50%; background: var(--green); vertical-align: 0.1em; }

@media (max-width: 699px) {
  html.motion-on .statement { height: 200svh; }
  .statement__line { font-size: 12vw; }
  .dots__stage { height: 78svh; min-height: 420px; }
  html.motion-on .dots { height: 200svh; }
}

/* The statement's photos: real prints from the shop, pinned up in the free corners of the screen
   (one per line; they slide in as the line fills; scenes/statement.js). */
.statement__text { z-index: 1; }
.statement__prints { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.sprint {
  position: absolute; margin: 0; width: clamp(150px, 15vw, 270px); padding: 8px 8px 0; background: #FFFFFF;
  rotate: var(--rot, 0deg); box-shadow: 0 1px 2px rgba(18, 20, 23, 0.12), 0 18px 34px -16px rgba(18, 20, 23, 0.45);
}
.sprint .pic { display: block; aspect-ratio: 4 / 3; overflow: hidden; background: #E9E6DE; }
.sprint .pic picture, .sprint .pic img { width: 100%; height: 100%; }
.sprint img { object-fit: cover; }
.sprint figcaption { padding: 8px 2px 10px; font: 700 0.82rem/1.1 var(--font-body); color: var(--carbon); text-align: left; }
/* Desktop: the words fill the width, so the prints line up along the bottom, either side of the sticker. */
.sprint { width: clamp(140px, 13.5vw, 240px); }
.sprint--0 { bottom: 5%; left: 4%; --rot: -6deg; }
.sprint--1 { bottom: 8%; left: calc(6% + clamp(140px, 13.5vw, 240px)); --rot: 3deg; }
.sprint--2 { bottom: 5%; right: 5%; --rot: 5deg; }
html.motion-on .sprint { opacity: 0; will-change: transform, opacity; }
@media (max-width: 899px) {
  .sprint { width: 31vw; padding: 5px 5px 0; }
  .sprint figcaption { font-size: 0.7rem; padding: 5px 1px 7px; }
  .sprint--0 { top: 9%; bottom: auto; left: 3%; }
  .sprint--1 { top: 7%; bottom: auto; left: auto; right: 3%; }
  .sprint--2 { bottom: 9%; right: auto; left: 4%; }
}
/* Motion off / no JS: the section is one screen tall, so the photos sit in a row under the words. */
html:not(.motion-on) .statement__prints { position: static; display: flex; justify-content: center; gap: clamp(12px, 3vw, 40px); flex-wrap: wrap; }
html:not(.motion-on) .sprint { position: relative; inset: auto; }


/* ---- src/styles/65-about.css ---- */
/* THE SHOP (sections/about.mjs): the owner's story, the shop's real facts and photos, real reviews.
   Backing paper with the grid; two photo prints pinned beside the text. */
.about { position: relative; padding: clamp(4rem, 9vw, 7.5rem) var(--gutter); background-color: var(--substrate); background-image: var(--paper-grid); overflow-x: clip; }
.about__grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: clamp(2rem, 6vw, 6rem); align-items: center; max-width: 1280px; margin: 0 auto; }
.about__title {
  margin: 0.5rem 0 1.4rem; color: var(--navy); font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight); font-stretch: var(--display-stretch);
  font-size: calc(var(--display-scale) * clamp(2.8rem, 1.4rem + 5vw, 6rem)); line-height: var(--mega-lead); letter-spacing: var(--mega-track); text-transform: uppercase; text-wrap: balance;
}
.about__story { max-width: 44ch; margin: 0 0 2rem; font-size: clamp(1.1rem, 1rem + 0.45vw, 1.35rem); line-height: 1.55; color: var(--ink); }
.about__story--needed { padding: 18px 20px; border: 2px dashed rgba(18, 51, 93, 0.35); border-radius: 16px; color: var(--ink-soft); font-size: 1.02rem; }
.about__facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; margin: 0; padding: 0; list-style: none; }
.about__facts li { display: grid; gap: 4px; padding: 16px 18px; border-radius: 18px; background: rgba(255, 255, 255, 0.75); box-shadow: inset 0 1px 0 #fff, inset 0 0 0 1px rgba(18, 20, 23, 0.07); }
.about__facts b { font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight); text-transform: uppercase; font-size: calc(var(--display-scale) * 1.6rem); line-height: 1; color: var(--carbon); }
.about__facts span { font-size: 0.92rem; color: var(--ink-soft); font-weight: 600; }
.about__photos { position: relative; min-height: clamp(320px, 36vw, 520px); }
.about__print { position: absolute; margin: 0; width: min(78%, 420px); padding: 10px 10px 0; background: #FFFFFF; box-shadow: 0 1px 2px rgba(18, 20, 23, 0.12), 0 22px 40px -20px rgba(18, 20, 23, 0.5); }
.about__print .pic, .about__print picture, .about__print img { display: block; width: 100%; height: 100%; }
.about__print .pic { aspect-ratio: 4 / 3; overflow: hidden; }
.about__print img { object-fit: cover; }
.about__print figcaption { padding: 9px 2px 11px; font: 700 0.85rem/1.1 var(--font-body); color: var(--carbon); }
.about__print--shop { top: 0; left: 0; rotate: -4deg; z-index: 2; }
.about__print--needed, .about__print--work { right: 0; bottom: 0; rotate: 5deg; z-index: 1; }
.about__needed { display: grid; place-items: center; aspect-ratio: 4 / 3; background: repeating-linear-gradient(-12deg, transparent 0 20px, rgba(18, 20, 23, 0.05) 20px 21.5px), var(--liner); font-family: var(--font-display); font-weight: var(--display-weight); text-transform: uppercase; font-size: calc(var(--display-scale) * 1.4rem); color: var(--navy); }
.about__reviews { max-width: 1280px; margin: clamp(3rem, 7vw, 5rem) auto 0; }
.about__h3 { margin: 0 0 1rem; font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight); text-transform: uppercase; font-size: calc(var(--display-scale) * clamp(1.8rem, 1.2rem + 2vw, 2.8rem)); line-height: 0.95; color: var(--carbon); }
.about__reviews-empty { max-width: 52ch; padding: 18px 20px; border: 2px dashed rgba(18, 51, 93, 0.35); border-radius: 16px; color: var(--ink-soft); }
@media (max-width: 899px) {
  .about__grid { grid-template-columns: 1fr; }
  .about__photos { min-height: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
  .about__print { position: relative; width: auto; inset: auto; }
}
/* facts that come from business.json keep the big type (their preview wrapper would shrink them) */
.about__facts b > span, .about__facts b [data-fact] { font: inherit; text-transform: inherit; }
.about__print--shop { width: min(70%, 400px); }
.about__print--needed, .about__print--work { width: min(58%, 330px); }
.about__needed { font-size: calc(var(--display-scale) * 1.05rem); padding: 1rem; text-align: center; }
@media (max-width: 899px) {
  .about__photos { grid-template-columns: 1fr; justify-items: center; }
  .about__print--shop { width: min(86%, 420px); }
  .about__print--needed, .about__print--work { width: min(64%, 300px); margin-top: -40px; justify-self: end; }
}

/* Live Google reviews (sections/about.mjs → reviewsBox, filled by src/client/reviews.js): the rating,
   then the reviews as paper slips pinned in a row, like the photo prints above. Swipe sideways on phones;
   on wide screens they wrap, three to a row (Google sends up to 5). */
.greviews { --gap: clamp(14px, 2vw, 24px); margin: 0 0 1.6rem; }
.greviews__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 20px; margin-bottom: 1rem; }
.greviews__score { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0; font-weight: 700; color: var(--ink-soft); }
.greviews__score b { font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight); font-size: calc(var(--display-scale) * 2.6rem); line-height: 0.8; color: var(--carbon); }
.greviews__score a { color: var(--navy); }
.greviews__score .stars { font-size: 1.5rem; }
/* Google's credit rule for text: Roboto (or the body sans), regular, 12–16px, #5E5E5E, one line, unchanged. */
.greviews__credit { padding: 10px 10px 5px; font: 400 14px/1 Roboto, var(--font-body), sans-serif; letter-spacing: normal; color: #5E5E5E; white-space: nowrap; }
.stars { position: relative; display: inline-block; align-self: flex-start; width: max-content; font-size: 1.05rem; line-height: 1; letter-spacing: 0.06em; color: rgba(18, 20, 23, 0.16); white-space: nowrap; }
.stars::before { content: '★★★★★'; }
.stars::after { content: '★★★★★'; position: absolute; inset: 0 auto 0 0; width: calc(var(--r, 0) / 5 * 100%); overflow: hidden; color: var(--green); }
.greviews__list {
  display: flex; gap: var(--gap); margin: 0 calc(-1 * var(--gutter)); padding: 14px var(--gutter) 26px; list-style: none;
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); overscroll-behavior-x: contain; scrollbar-width: thin;
}
.greviews__card {
  flex: 0 0 clamp(260px, 30%, 360px); scroll-snap-align: start; display: flex; flex-direction: column; gap: 10px; min-width: 0;
  padding: 18px 18px 16px; background: var(--white); box-shadow: 0 1px 2px rgba(18, 20, 23, 0.12), 0 18px 34px -20px rgba(18, 20, 23, 0.45);
}
.greviews__card:nth-child(3n + 1) { rotate: -1.2deg; }
.greviews__card:nth-child(3n + 2) { rotate: 0.8deg; }
.greviews__card:nth-child(3n) { rotate: -0.4deg; }
.greviews__text { display: -webkit-box; -webkit-line-clamp: 7; -webkit-box-orient: vertical; overflow: hidden; margin: 0; font-size: 1rem; line-height: 1.5; color: var(--ink); }
.greviews__more { align-self: flex-start; font-size: var(--size-small); font-weight: 700; color: var(--navy); }
.greviews__who { display: flex; align-items: center; gap: 10px; margin: auto 0 0; padding-top: 10px; border-top: 1.5px dashed var(--line-soft); }
.greviews__face { flex: none; width: 36px; height: 36px; border-radius: 50%; object-fit: cover; background: var(--liner); }
.greviews__name { display: grid; min-width: 0; font-size: 0.92rem; line-height: 1.25; }
.greviews__name a, .greviews__name b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 800; color: var(--carbon); }
.greviews__name small { color: var(--ink-soft); }
.greviews__note { max-width: 60ch; margin: 0; font-size: var(--size-small); color: var(--ink-soft); }
@media (max-width: 699px) { .greviews__card { flex-basis: 82%; } }
@media (pointer: coarse) { .greviews__list { scrollbar-width: none; } .greviews__list::-webkit-scrollbar { display: none; } }
@media (min-width: 900px) {
  .greviews__list { flex-wrap: wrap; overflow: visible; margin: 0; padding: 14px 0 26px; }
  .greviews__card { flex: 0 0 calc((100% - 2 * var(--gap)) / 3); }
}
/* Preview, before the key: empty slips showing where the reviews will sit. */
.greviews--demo .greviews__card { box-shadow: none; background: rgba(255, 255, 255, 0.55); outline: 2px dashed rgba(18, 51, 93, 0.3); outline-offset: -2px; }
.greviews__line { display: block; height: 10px; border-radius: 5px; background: rgba(18, 20, 23, 0.09); }
.greviews__line--short { width: 60%; }
.greviews__line--name { width: 45%; }
.greviews__demo { max-width: 60ch; margin: 0; padding: 14px 18px; border: 2px dashed rgba(18, 51, 93, 0.35); border-radius: 16px; font-size: var(--size-small); color: var(--ink-soft); }


/* ---- src/styles/70-quote.css ---- */
/* SECTION 9 · QUOTE: a big headline, the logo drop zone front and center, roomy steps, and the
   paper work order beside it that fills in as you answer (72-workorder.css). With JS the form is
   4 steps (src/client/quote.js); without JS it's one long form that still posts. */
.quote { position: relative; background-color: var(--substrate); overflow: clip; padding: clamp(3.5rem, 2rem + 5vw, 6.5rem) 0 clamp(4rem, 2rem + 6vw, 7.5rem); }
.quote__ghost { top: clamp(1rem, 4vw, 3rem); right: -6vw; font-size: 30vw; }
.quote__inner { position: relative; z-index: 1; max-width: 1400px; margin: 0 auto; padding: 0 var(--gutter); }
.quote__big { margin: 0; font-size: calc(80vw / var(--brand-em)); color: var(--navy); }
.quote__intro { max-width: 34rem; margin-top: clamp(0.75rem, 2vw, 1.5rem); font-size: var(--size-lede); line-height: 1.45; }
.quote__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 410px);
  gap: clamp(2rem, 1rem + 4vw, 6rem); align-items: start; margin-top: clamp(2rem, 1rem + 3vw, 3.5rem);
}
.quote__wo { position: sticky; top: calc(var(--nav-top) + 76px); }
.quote__form { padding: clamp(1.25rem, 0.75rem + 2.5vw, 2.5rem); border-radius: var(--radius-panel); --g-tint: rgba(255, 255, 255, 0.55); }
.quote > .marks { z-index: 0; }
body:not(.has-hero) .quote { padding-top: clamp(1rem, 3vw, 2rem); }

/* ---- the logo drop zone ---- */
.drop { margin-bottom: clamp(2rem, 5vw, 3rem); }
.drop__zone {
  position: relative; display: grid; justify-items: start; gap: 12px;
  padding: clamp(1.25rem, 3vw, 2rem); border-radius: 22px;
  border: 2px dashed rgba(18, 20, 23, 0.45); background: rgba(255, 255, 255, 0.6);
  cursor: pointer; transition: background-color var(--dur-fade) ease;
}
.drop__title {
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * clamp(1.6rem, 1.1rem + 2vw, 2.6rem)); line-height: 0.95; text-transform: uppercase; color: var(--navy);
  max-width: 16ch;
}
.drop__or { font-weight: 700; color: var(--ink-soft); }
.drop__hint { font-size: var(--size-small); color: var(--ink-soft); }
.drop__input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.drop__input:focus-visible + .file-list, .drop:focus-within .drop__zone { outline: 3px solid var(--focus); outline-offset: 3px; }
.drop.is-over .drop__zone { background-color: var(--green-tint); }
.drop.is-over .drop__zone::after {
  content: ''; position: absolute; inset: -2px; border: 3px solid var(--green); border-radius: 22px; pointer-events: none;
}
html.no-js .drop__btn { display: none; }
html.no-js .drop__input { position: static; width: auto; height: auto; opacity: 1; margin-top: 10px; }

.file-list { list-style: none; display: grid; gap: 8px; margin-top: 10px; }
.file-list:empty { display: none; }
.file-list li { display: grid; grid-template-columns: 52px 1fr auto; gap: 12px; align-items: center; padding: 6px; border-radius: 16px; background: rgba(255, 255, 255, 0.85); box-shadow: inset 0 0 0 1.5px rgba(18, 20, 23, 0.3); }
.file-list img, .file-list .file-icon { border-radius: 10px; }
.file-list img, .file-list .file-icon { width: 52px; height: 52px; object-fit: cover; background: var(--liner); display: grid; place-items: center; font-size: 0.72rem; font-weight: 800; }
.file-list .file-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.file-list progress { width: 100%; height: 6px; accent-color: var(--green); }
.file-list button { min-height: 44px; border: 0; border-radius: 999px; background: rgba(18, 20, 23, 0.07); padding: 0 14px; font-weight: 700; }

/* ---- steps ---- */
.quote-form { max-width: 46rem; }
.quote-form__steps { display: grid; }
.qstep { border: 0; padding: 0; margin: 0 0 clamp(2.5rem, 6vw, 4rem); min-width: 0; }
.qstep__title {
  display: flex; align-items: baseline; gap: 0.3em; padding: 0; margin-bottom: clamp(1.25rem, 3vw, 2rem);
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * clamp(1.9rem, 1.2rem + 2.6vw, 3.3rem)); line-height: 0.92; text-transform: uppercase; color: var(--navy);
}
/* The step number, outlined like the giant background words. */
.qstep__n { flex: none; font-size: 1.35em; color: transparent; -webkit-text-stroke: max(1.5px, 0.025em) var(--navy); }
.like-job { margin-bottom: var(--s5); padding: 10px 16px; border-radius: 14px; background: var(--green-tint); box-shadow: inset 4px 0 0 var(--green); font-weight: 600; }
.like-job .label { font: inherit; letter-spacing: 0; text-transform: none; }

/* Job types: big square tiles in the display face. */
.choices--types { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 13.5rem), 1fr)); gap: 10px; }
.choice--block > span {
  --cut: 14px;
  min-height: 92px; padding: 14px 18px; align-items: flex-end;
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.28rem); line-height: 0.98; text-transform: uppercase;
}
.choices--inline .choice > span { min-height: 50px; }

/* JS mode: steps stack in one grid cell so the box never jumps in height. */
html.js .quote-form.is-stepped .quote-form__steps > .qstep { grid-area: 1 / 1; margin-bottom: 0; }
/* Steps waiting off to the side for their slide-in must not widen the page (it did on phones). */
html.js .quote-form.is-stepped .quote-form__steps { overflow-x: clip; overflow-clip-margin: 12px; }
html.js .quote-form.is-stepped .qstep:not(.is-current) { visibility: hidden; pointer-events: none; }

.quote-form__progress { display: grid; gap: 10px; margin-bottom: clamp(1.25rem, 3vw, 2rem); }
.quote-form__progress-text { font-weight: 700; color: var(--ink-soft); }
.quote-form__bar { height: 8px; border-radius: 99px; background: rgba(18, 20, 23, 0.08); overflow: hidden; }
.quote-form__bar-fill { display: block; height: 100%; background: var(--green); transform-origin: left; transform: scaleX(0.25); transition: transform 420ms var(--spring); }
.quote-form__nav { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin-top: clamp(1.5rem, 4vw, 2.5rem); }
.quote-form__nav [data-quote-next], .quote-form__nav [data-quote-send] { margin-left: auto; min-width: 11rem; }
.quote-form__nav [data-quote-send] { --h: 66px; font-size: calc(var(--display-scale) * 1.3rem); }
.quote-form__privacy { margin-top: var(--s5); font-size: var(--size-small); color: var(--ink-soft); }
.quote-form .demo-note { margin-top: var(--s3); }
.quote-form__status:not(:empty) { margin-top: var(--s4); padding: 12px 16px; border-radius: 14px; box-shadow: inset 4px 0 0 var(--carbon); background: rgba(255, 255, 255, 0.7); }
.quote-form__status.is-error { box-shadow: inset 5px 0 0 var(--danger); background: #FBE9E6; }
.quote-form.is-sending { opacity: 0.75; }

.review-list { display: grid; grid-template-columns: max-content 1fr; gap: 10px 18px; padding: 18px; border-radius: 18px; background: rgba(255, 255, 255, 0.8); box-shadow: inset 0 0 0 1.5px rgba(18, 20, 23, 0.25); }
.review-list dt { font-weight: 700; color: var(--ink-soft); }
.review-list dd { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
/* Phones: each label above its answer (side by side, long labels left the answers a column 1-2 letters wide). */
@media (max-width: 559px) {
  .review-list { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .review-list dd + dt { margin-top: 10px; }
}

/* After sending: the work order carries the stamp; this panel says what happens next. */
.quote-done { display: grid; gap: 14px; justify-items: start; }
.quote-done__title {
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * clamp(2rem, 1.4rem + 2vw, 3rem)); line-height: 0.95; text-transform: uppercase; color: var(--navy);
}
.quote-done__ref { font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace; font-weight: 700; }

@media (max-width: 899px) {
  .quote__grid { grid-template-columns: 1fr; }
  .quote__wo { position: relative; top: 0; order: -1; }
  .quote-form__nav [data-quote-next], .quote-form__nav [data-quote-send] { flex: 1 1 auto; }
}


/* ---- src/styles/72-workorder.css ---- */
/* WORK ORDER: one look for the quote form and the chat, so they feel like one system.
   A sheet of tractor-feed printer paper under a printer's output slot. It fills in as people
   answer (src/client/workorder.js); when they send, it "prints": the sheet feeds out of the slot,
   then gets a SENT stamp and a reference number. */
.wo {
  --slot: 16px;
  position: relative; padding-top: calc(var(--slot) - 5px);
  /* Hide the sheet while it's up inside the printer; never clip the sides or bottom. */
  clip-path: inset(0 -80px -200vh -80px);
}
/* The printer's output slot: glossy dark glass with light on its top edge. */
.wo__slot {
  position: absolute; z-index: 2; top: 0; left: -12px; right: -12px; height: var(--slot);
  border-radius: 10px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0) 45%), linear-gradient(#2A2F35, #0E1013);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), inset 0 -5px 0 #000, 0 8px 16px -8px rgba(0, 0, 0, 0.55);
}
/* the printer's "ready" light */
.wo__slot::after { content: ''; position: absolute; top: 4px; right: 14px; width: 6px; height: 6px; border-radius: 50%; background: var(--green); box-shadow: 0 0 6px 1px rgba(29, 170, 71, 0.8); }
/* a color-calibration strip on the printer body */
.wo__slot::before { content: ''; position: absolute; top: 5px; left: 16px; width: 56px; height: 4px; border-radius: 1px; background: var(--cmyk); opacity: 0.85; }
.wo.is-printing .wo__slot::after { animation: wo-blink 0.32s steps(2, jump-none) infinite; }
@keyframes wo-blink { 50% { background: #0B3D1A; } }

.wo__paper {
  --hole: var(--substrate);
  position: relative; z-index: 1;
  padding: 20px 34px 18px;
  color: var(--carbon);
  /* tractor-feed holes down both edges, and the perforation lines inside them */
  background:
    radial-gradient(circle at 11px 14px, var(--hole) 0 3.6px, transparent 4.2px) left top / 22px 28px repeat-y,
    radial-gradient(circle at 11px 14px, var(--hole) 0 3.6px, transparent 4.2px) right top / 22px 28px repeat-y,
    repeating-linear-gradient(var(--line-soft) 0 4px, transparent 4px 8px) 22px 0 / 1px 100% no-repeat,
    repeating-linear-gradient(var(--line-soft) 0 4px, transparent 4px 8px) calc(100% - 22px) 0 / 1px 100% no-repeat,
    var(--white);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06), 0 22px 34px -26px rgba(0, 0, 0, 0.55);
}
.wo__head { display: grid; grid-template-columns: 40px 1fr auto; gap: 12px; align-items: center; padding-bottom: 12px; border-bottom: 3px solid var(--carbon); }
.wo__head img { width: 40px; height: 40px; border-radius: 50%; }
.wo__head-text { display: grid; min-width: 0; }
.wo__head-text b {
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.45rem); line-height: 0.9; text-transform: uppercase;
}
.wo__head-text > span { font-size: 0.8rem; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wo__no, .wo__row dd, .wo__art-name { font-family: ui-monospace, 'Cascadia Mono', 'SF Mono', Consolas, monospace; }
.wo__no { align-self: start; font-size: 0.78rem; font-weight: 700; white-space: nowrap; }

.wo__rows { display: grid; margin: 6px 0 0; }
.wo__row { display: grid; grid-template-columns: 6.4rem minmax(0, 1fr); gap: 10px; align-items: baseline; padding: 8px 0 6px; border-bottom: 1.5px dashed var(--line-soft); }
.wo__row dt { font-size: 0.84rem; font-weight: 700; color: var(--ink-soft); }
.wo__row dd { margin: 0; min-height: 1.35em; font-size: 0.92rem; font-weight: 600; overflow-wrap: anywhere; }
.wo__row.is-new dd { animation: wo-ink 420ms steps(14, end) both; }
@keyframes wo-ink { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

.wo__art { margin-top: 14px; }
.wo__attach {
  display: grid; gap: 2px; width: 100%; min-height: 66px; padding: 10px 16px; text-align: left; border-radius: 14px;
  border: 2px dashed rgba(18, 20, 23, 0.55); background: var(--substrate); color: var(--carbon);
  transition: background-color var(--dur-fade) ease, transform var(--dur-press) ease-out;
}
.wo__attach > span {
  font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.1rem); line-height: 1; text-transform: uppercase;
}
.wo__attach small { font-size: 0.78rem; color: var(--ink-soft); }
.wo__attach:hover { background: var(--green-tint); }
.wo__attach:active { transform: scale(var(--press-scale)); }
.wo__thumbs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.wo__thumbs:empty { display: none; }
.wo__thumb { width: 56px; height: 56px; object-fit: contain; background: var(--liner); box-shadow: inset 0 0 0 1.5px var(--line-soft); }
.wo__thumb--file { display: grid; place-items: center; font: 800 0.72rem/1 ui-monospace, Consolas, monospace; }
.wo__note { margin-top: 14px; font-size: 0.8rem; line-height: 1.4; color: var(--ink-soft); }

.wo__stamp {
  position: absolute; z-index: 3; right: 26px; top: 42%; margin: 0;
  padding: 6px 14px; border: 4px solid #17913B; color: #17913B; background: rgba(255, 255, 255, 0.86);
  font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.55rem); line-height: 1; text-transform: uppercase;
  rotate: -9deg; opacity: 0; transform: scale(1.7); pointer-events: none;
  mix-blend-mode: multiply;
}
.wo.is-sent .wo__stamp { opacity: 1; transform: scale(1); transition: transform 300ms cubic-bezier(0.3, 1.5, 0.5, 1), opacity 120ms linear; }
.wo.is-sent .wo__attach { display: none; }

/* Compact (chat): rows in two columns, only the ones with answers. */
.wo--compact { --slot: 12px; }
.wo--compact .wo__paper { padding: 12px 30px 12px; }
.wo--compact .wo__head { grid-template-columns: 30px 1fr auto; gap: 8px; padding-bottom: 8px; border-bottom-width: 2px; }
.wo--compact .wo__head img { width: 30px; height: 30px; }
.wo--compact .wo__head-text b { font-size: calc(var(--display-scale) * 1.1rem); }
.wo--compact .wo__rows { grid-template-columns: 1fr 1fr; column-gap: 14px; }
.wo--compact .wo__row { grid-template-columns: 1fr; gap: 0; padding: 5px 0 4px; }
.wo--compact .wo__row dt { font-size: 0.74rem; }
.wo--compact .wo__row dd { font-size: 0.84rem; }
.wo--compact .wo__row:not(.is-filled) { display: none; }
.wo--compact .wo__art, .wo--compact .wo__note { display: none; }
.wo--compact .wo__stamp { top: 30%; font-size: calc(var(--display-scale) * 1.15rem); padding: 4px 10px; border-width: 3px; }

@media (max-width: 899px) {
  /* On phones the work order sits above the form; only filled rows show, so it stays short. */
  .quote__wo .wo__row:not(.is-filled) { display: none; }
  .quote__wo .wo__rows:not(:has(.is-filled))::before { content: attr(data-empty); padding: 10px 0 2px; font-size: 0.86rem; color: var(--ink-soft); }
  .quote__wo .wo__note { display: none; }
}


/* ---- src/styles/80-visit-footer.css ---- */
/* VISIT: a green self-healing cutting mat (grid, ruler edges with numbers, angle guides), a huge
   headline, and three panels laid on the mat across the full width: the address, the hours, and the
   shop itself (its photo; tap for the Google map in its place).
   FOOTER: one navy sheet, "W&W" printing in dots, then the info in four columns. */
.visit {
  --mat-line: rgba(255, 255, 255, 0.14); --mat-line-strong: rgba(255, 255, 255, 0.28);
  position: relative; overflow: clip;
  padding: clamp(3.5rem, 2rem + 5vw, 7rem) var(--gutter) clamp(3rem, 2rem + 5vw, 6rem) calc(var(--gutter) + 20px);
  color: var(--carbon);
  background-color: #1A9C43;
  background-image:
    radial-gradient(120% 90% at 30% 0%, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0) 60%),
    linear-gradient(var(--mat-line-strong) 1px, transparent 1px),
    linear-gradient(90deg, var(--mat-line-strong) 1px, transparent 1px),
    linear-gradient(var(--mat-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--mat-line) 1px, transparent 1px);
  background-size: 100% 100%, 240px 240px, 240px 240px, 48px 48px, 48px 48px;
  background-position: 0 0, 29px 29px, 29px 29px, 29px 29px, 29px 29px;
}
/* Angle guides (30°, 45°, 60°) running out of the bottom-left corner, like on a real mat. */
.visit__angles {
  position: absolute; left: 30px; bottom: 0; width: min(120vh, 1100px); aspect-ratio: 1; pointer-events: none; z-index: 0;
  --l: linear-gradient(to top right, transparent calc(50% - 0.6px), rgba(255, 255, 255, 0.22) 50%, transparent calc(50% + 0.6px));
  background: var(--l) left bottom / 100% 100% no-repeat, var(--l) left bottom / 100% 57.7% no-repeat, var(--l) left bottom / 57.7% 100% no-repeat;
}
.visit .ruler { color: rgba(255, 255, 255, 0.85); }
.visit > :not(.ruler):not(.visit__angles) { position: relative; z-index: 1; }
.visit__big { margin: 0 0 0 -0.04em; font-size: calc(56vw / var(--brand-em)); color: var(--carbon); }
.visit a:not(.btn) { color: var(--carbon); }
.visit__grid {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 1.2fr); gap: clamp(1rem, 0.5rem + 2vw, 2rem);
  margin: clamp(1.75rem, 1rem + 2.5vw, 3rem) 0 0;
}
.visit__where, .visit__hours { padding: clamp(1.25rem, 1rem + 1.5vw, 2rem); border-radius: var(--radius-panel); --g-tint: rgba(255, 255, 255, 0.62); }.visit__addr {
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * clamp(1.5rem, 1.1rem + 1.6vw, 2.5rem)); line-height: 0.98; text-transform: uppercase;
}
.visit__addr .ph { font-size: 0.5em; }
.visit__actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 18px; }
.visit__contact { font-weight: 600; }
.visit .hint { color: var(--carbon); }
.visit .uv { text-decoration-color: var(--carbon); }
.visit .uv-mark { color: var(--carbon); }
.visit__open {
  margin-bottom: 14px;
  font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.35rem); line-height: 1; text-transform: uppercase;
}
.visit .open-status__dot { width: 14px; height: 14px; }
.visit .open-status.is-open .open-status__dot { background: var(--green); box-shadow: 0 0 0 4px rgba(29, 170, 71, 0.25); }
.visit .open-status.is-closed .open-status__dot { border-color: var(--carbon); }

.hours { width: 100%; border-collapse: collapse; font-size: 1rem; }
.hours th, .hours td { text-align: left; padding: 9px 0; border-bottom: 1px solid rgba(18, 20, 23, 0.22); font-weight: 500; }
.hours tr:last-child th, .hours tr:last-child td { border-bottom: 0; }
.hours th { width: 46%; }
.hours tr.is-today th, .hours tr.is-today td { font-weight: 800; }
.hours tr.is-today th::before { content: ''; display: inline-block; width: 9px; height: 9px; margin-right: 8px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px rgba(29, 170, 71, 0.25); }
/* The shop panel: its photo with the map button laid on it; tapping swaps in the Google map (main.js). */
.visit__map { position: relative; display: flex; align-items: flex-end; min-height: 340px; overflow: hidden; border-radius: var(--radius-panel); background: var(--carbon); box-shadow: 0 18px 40px -24px rgba(12, 37, 70, 0.6); }
.visit__shop, .visit__shop picture, .visit__shop img { position: absolute; inset: 0; width: 100%; height: 100%; }
.visit__shop img { object-fit: cover; }
.visit__map-cta { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin: 14px; padding: 12px 14px; border-radius: 18px; background: rgba(255, 255, 255, 0.88); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.visit__map-cta .hint { margin: 0; font-size: var(--size-small); }
.map iframe { width: 100%; aspect-ratio: 4 / 3; border: 0; background: var(--white); }
.visit__map iframe { position: absolute; inset: 0; height: 100%; aspect-ratio: auto; }
@media (max-width: 1099px) {
  .visit__grid { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
  .visit__map { grid-column: 1 / -1; min-height: 380px; }
}

/* ---- footer: one printed sheet. "W&W" printing in dots (partials.mjs → printDots, scenes/dots.js), then the
   info on the same navy. The print grid runs across the whole sheet (it slides under the letters while
   they print, like paper feeding through the printer), and the info lines up with the letters' edges. ---- */
.site-footer {
  position: relative; overflow: clip;
  color: rgba(246, 245, 241, 0.86); font-size: 1.02rem;
  background-color: var(--navy);
  background-image:
    radial-gradient(70% 45% at 50% 20%, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 70%),
    linear-gradient(rgba(246, 245, 241, 0.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(246, 245, 241, 0.055) 1px, transparent 1px);
  background-size: 100% 100%, 48px 48px, 48px 48px;
  background-position: 0 0, center top, center top;
}
.site-footer__print { background: none; }
.site-footer__print .dots__grid { display: none; } /* the sheet's own grid shows through */
.site-footer__body { position: relative; padding: clamp(1.5rem, 0.5rem + 3vw, 3.5rem) max(var(--gutter), 8vw) calc(var(--s6) + var(--sticky-h)); }
.site-footer__base .cmyk { opacity: 0.85; }
/* The print: its stage is only as tall as the letters and the print head need (scenes/dots.js measures them
   and sets --stage-h). While it prints it holds still in the middle of the screen; then the info comes up
   right under the letters, with no empty band in between. */
.site-footer__print { --sh: var(--stage-h, 56svh); }
.site-footer__print .dots__stage { height: var(--sh); min-height: 0; max-height: none; }
html.motion-on .site-footer__print { height: calc(var(--sh) + 105svh); }
html.motion-on .site-footer__print .dots__stage { top: max(var(--pbar), calc(var(--pbar) + (100lvh - var(--pbar) - var(--sh)) / 2)); height: var(--sh); }
.site-footer__print .dots__hint { bottom: 10px; }
.site-footer__print .dots__fallback { font-size: min(34vw, 40svh); }
@media (max-width: 699px) { html.motion-on .site-footer__print { height: calc(var(--sh) + 130svh); } } /* a phone's print is short: a bit more scroll so the passes don't rush */
.site-footer__inner { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2rem clamp(1.5rem, 4vw, 4rem); }
/* On wide screens the services run in two columns, so all four columns end about level. */
@media (min-width: 1500px) { .site-footer__list { grid-template-columns: repeat(2, max-content); column-gap: clamp(1.5rem, 3vw, 3.5rem); } }
.site-footer__h {
  margin-bottom: 10px; color: var(--substrate);
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * clamp(1.3rem, 1.1rem + 0.5vw, 1.7rem)); line-height: 1; text-transform: uppercase;
}
.site-footer__col > * + * { margin-top: 12px; }
.site-footer__col > .site-footer__h:not(:first-child) { margin-top: 26px; }
.site-footer a { color: var(--substrate); }
.site-footer__list { list-style: none; display: grid; gap: 6px; }
.site-footer__list a { display: inline-flex; align-items: center; min-height: 32px; }
.site-footer .uv-mark, .site-footer .uv { color: var(--substrate); text-decoration-color: var(--substrate); }
.site-footer .open-status { display: inline-flex; margin-top: 6px; color: var(--substrate); font-weight: 700; }
.site-footer .open-status.is-closed .open-status__dot { border-color: rgba(255, 255, 255, 0.8); }
.site-footer__base {
  display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: center;
  margin-top: clamp(2rem, 1rem + 3vw, 3.5rem); padding-top: 16px; border-top: 1px solid rgba(246, 245, 241, 0.2); font-size: 0.86rem;
}
.site-footer__base a { min-height: 44px; display: inline-flex; align-items: center; }

@media (max-width: 1099px) { .site-footer__inner { grid-template-columns: 1fr 1fr; } }
@media (max-width: 899px) {
  /* minmax(0, …): a plain 1fr track grew to fit the widest card, which then ran past the screen edge. */
  .visit__grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 559px) {
  .site-footer__inner { grid-template-columns: 1fr; }
  .visit__map { min-height: 280px; }
  .visit__actions .btn { flex: 1 1 auto; }
}
/* Small phones: "CALL (706) 424-7420" is wider than the card, so the word is kept for screen readers only
   (the phone icon and the number stay). */
@media (max-width: 419px) {
  .visit__call-word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}


/* ---- src/styles/85-chat.css ---- */
/* CHAT: the launcher (the round W&W badge with a glass label that slides out), the phone bar, and the
   assistant panel: a glass panel with flat brand-color bubbles, square-ish quick replies and the live work
   order at the top while it collects a quote. Glass material: 20-components.css. */

/* ---- launcher (desktop) ---- */
.launcher {
  position: fixed; z-index: 45;
  right: max(18px, env(safe-area-inset-right)); bottom: calc(18px + env(safe-area-inset-bottom));
  display: flex; align-items: center; color: var(--photo-ink); text-decoration: none;
  transition: opacity 160ms ease, transform 220ms var(--spring);
  -webkit-tap-highlight-color: transparent;
}
.launcher:hover { text-decoration: none; }
.launcher__badge {
  position: relative; z-index: 1; width: 64px; height: 64px; border-radius: 50%;
  /* a glass ring around the badge */
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.85), 0 0 0 4px rgba(18, 20, 23, 0.12), 0 12px 26px -10px rgba(0, 0, 0, 0.55);
  transition: transform 420ms var(--spring-pop);
}
.launcher__label {
  display: flex; align-items: center; height: 46px; margin-right: -22px; padding: 0 34px 0 20px; border-radius: 999px;
  white-space: nowrap; color: var(--photo-ink);
  font-family: var(--font-label); font-stretch: var(--label-stretch); font-style: var(--label-style); font-weight: 750;
  font-size: calc(var(--label-scale) * 0.84rem); letter-spacing: 0.05em; line-height: 1; text-transform: uppercase;
  /* Tucked behind the badge; slides out to the left. */
  clip-path: inset(0 0 0 100% round 999px);
  transform: translateX(26px);
  transition: clip-path 460ms var(--spring), transform 460ms var(--spring);
}
.launcher.is-out .launcher__label, .launcher:hover .launcher__label, .launcher:focus-visible .launcher__label {
  clip-path: inset(0 0 0 0 round 999px);
  transform: none;
}
.launcher:active .launcher__badge { transform: scale(1.08); transition-duration: 160ms; }
.launcher.is-hidden { opacity: 0; transform: scale(0.85); pointer-events: none; }
.launcher:focus-visible { outline: none; box-shadow: none; }
.launcher:focus-visible .launcher__badge { outline: 3px solid var(--focus); outline-offset: 3px; }

/* ---- phone bar: a floating dark glass bar ---- */
.sticky-bar { display: none; }
@media (max-width: 899px) {
  :root:has(.sticky-bar) { --sticky-h: calc(76px + env(safe-area-inset-bottom)); }
  .launcher { display: none; }
  body:not(:has(.sticky-bar)) .launcher { display: flex; }
  .launcher__label { display: none; }
  .sticky-bar {
    position: fixed; z-index: 45; left: 10px; right: 10px; bottom: calc(10px + env(safe-area-inset-bottom));
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px; padding: 5px; border-radius: 24px;
    --g-tint: rgba(20, 24, 28, 0.62);
    transition: transform 360ms var(--spring);
  }
  .sticky-bar.is-tucked { transform: translateY(140%); }
  .sticky-bar__btn {
    display: flex; align-items: center; justify-content: center; gap: 7px; min-height: 52px; padding: 0 6px; border-radius: 19px;
    font-family: var(--font-label); font-stretch: var(--label-stretch); font-style: var(--label-style); font-weight: 750;
    font-size: calc(var(--label-scale) * 0.8rem); letter-spacing: 0.04em; line-height: 1; text-transform: uppercase; white-space: nowrap;
    color: var(--photo-ink); text-decoration: none;
    transition: transform 380ms var(--spring-pop), background-color var(--dur-fade) ease;
    -webkit-tap-highlight-color: transparent;
  }
  .sticky-bar__btn:active { transform: scale(1.06); background: rgba(255, 255, 255, 0.12); transition-duration: 140ms; }
  .sticky-bar__btn--quote {
    color: var(--carbon);
    background: linear-gradient(170deg, rgba(255, 255, 255, 0.38), rgba(255, 255, 255, 0) 55%), var(--glass-green);
    box-shadow: inset 0 1px 0.5px var(--glass-rim), inset 0 0 0 1px rgba(255, 255, 255, 0.22);
  }
  .sticky-bar__btn--quote:active { background: linear-gradient(170deg, rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0) 55%), var(--glass-green-hi); }
  .sticky-bar__btn img { width: 24px; height: 24px; border-radius: 50%; flex: none; }
  .sticky-bar__btn .i { width: 18px; height: 18px; }
}

/* ---- panel ---- */
.chat-scrim { position: fixed; inset: 0; z-index: 69; background: rgba(10, 12, 14, 0.45); }
.chat {
  position: fixed; z-index: 70; display: flex; flex-direction: column; overflow: hidden;
  color: var(--carbon);
  --g-tint: rgba(246, 245, 241, 0.9);
  --glass-blur: 26px;
}
.chat:focus { outline: none; }
@media (min-width: 900px) {
  .chat {
    top: calc(var(--pbar) + 12px); right: 12px; bottom: 12px; width: min(440px, calc(100vw - 24px));
    border-radius: var(--radius-panel);
    box-shadow: inset 0 1px 0.5px var(--glass-rim), inset 0 0 0 1px rgba(255, 255, 255, 0.4), var(--glass-shadow-lg);
  }
  .chat__grab { display: none; }
}
@media (max-width: 899px) {
  .chat { left: 0; right: 0; bottom: 0; height: min(92svh, 780px); border-radius: 26px 26px 0 0; }
  .chat__grab { flex: none; height: 20px; display: grid; place-items: center; touch-action: none; }
  .chat__grab::before { content: ''; width: 44px; height: 5px; border-radius: 3px; background: rgba(18, 20, 23, 0.25); }
}

.chat__head {
  flex: none; display: grid; grid-template-columns: 46px minmax(0, 1fr) auto auto; gap: 10px; align-items: center;
  margin: 8px 8px 0; padding: 10px 8px 10px 12px; border-radius: 20px;
  color: var(--substrate); touch-action: none;
  background: linear-gradient(170deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0) 55%), var(--navy);
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.4), 0 6px 16px -10px rgba(10, 20, 40, 0.6);
}
.chat__badge { width: 46px; height: 46px; border-radius: 50%; box-shadow: 0 0 0 2px rgba(246, 245, 241, 0.9); }
.chat__title {
  margin: 0; color: var(--substrate);
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.2rem); line-height: 1; text-transform: uppercase;
}
.chat__sub { margin-top: 4px; font-size: 0.8rem; line-height: 1.3; color: rgba(246, 245, 241, 0.86); }
.chat__icon-btn {
  min-width: 44px; min-height: 44px; padding: 0 12px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.12); color: var(--substrate); border: 0;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), inset 0 0 0 1px rgba(255, 255, 255, 0.18);
  font-weight: 700; font-size: 0.8rem;
  transition: transform 380ms var(--spring-pop), background-color var(--dur-fade) ease;
}
.chat__icon-btn:hover { background: rgba(255, 255, 255, 0.24); }
.chat__icon-btn:active { transform: scale(1.08); }
.chat__icon-btn[data-close] { display: grid; place-items: center; padding: 0; width: 44px; }
.chat__icon-btn .i { width: 20px; height: 20px; }
.chat__demo { flex: none; margin: 8px 12px 0; padding: 6px 12px; border-radius: 12px; background: rgba(239, 227, 196, 0.9); font-size: 0.8rem; }
.chat__log { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 16px 14px 10px; display: flex; flex-direction: column; gap: 10px; }
.msg { max-width: 86%; padding: 10px 14px 11px; font-size: 0.98rem; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.msg--bot {
  align-self: flex-start; background: var(--navy); color: var(--white);
  border-radius: 6px 18px 18px 18px;
}
.msg--me {
  align-self: flex-end; background: var(--green); color: var(--carbon); font-weight: 600;
  border-radius: 18px 6px 18px 18px;
}
.msg--note { align-self: stretch; max-width: none; padding: 4px 0 4px 12px; box-shadow: inset 3px 0 0 var(--carbon); font-size: 0.9rem; color: var(--ink-soft); }
.msg--typing { display: inline-flex; gap: 5px; padding: 14px 16px; }
.msg--typing span { width: 7px; height: 7px; border-radius: 50%; background: var(--white); animation: chat-dot 0.9s infinite ease-in-out; }
.msg--typing span:nth-child(2) { animation-delay: 0.15s; }
.msg--typing span:nth-child(3) { animation-delay: 0.3s; }
@keyframes chat-dot { 0%, 100% { opacity: 0.35; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }

/* Quick replies: chunky capsules in the display face. Nearly solid, so glass isn't stacked on glass. */
.qr-row { display: flex; flex-wrap: wrap; gap: 8px; }
.qr {
  min-height: 46px; padding: 0 16px; border: 0; border-radius: 999px; color: var(--carbon);
  background: linear-gradient(170deg, #fff, rgba(255, 255, 255, 0.82));
  box-shadow: inset 0 1px 0 #fff, inset 0 0 0 1.5px rgba(18, 20, 23, 0.5), 0 4px 12px -8px rgba(10, 14, 20, 0.5);
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 0.98rem); line-height: 1; text-transform: uppercase;
  transition: transform 380ms var(--spring-pop), background-color var(--dur-fade) ease;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.qr:hover { background: linear-gradient(170deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 55%), var(--glass-green); }
.qr:active { transform: scale(1.06); transition-duration: 140ms; }

.msg-card { align-self: stretch; padding: 16px; border-radius: 20px; background: rgba(255, 255, 255, 0.85); box-shadow: inset 0 0 0 1px rgba(18, 20, 23, 0.14), 0 8px 20px -14px rgba(10, 14, 20, 0.5); }
.msg-card h3 {
  margin: 0 0 10px; color: var(--navy);
  font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  font-size: calc(var(--display-scale) * 1.2rem); line-height: 1; text-transform: uppercase;
}
.msg-card dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 4px 12px; font-size: 0.9rem; }
.msg-card dt { font-weight: 700; color: var(--ink-soft); }
.msg-card dd { margin: 0; overflow-wrap: anywhere; }
.msg-card p { font-size: 0.94rem; }
.msg-card .btns, .chat .btns { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
/* The quote hand-off: one tap opens the quote form (the chat answers questions; quotes happen there). */
.chat__quote-row { align-self: flex-start; margin-top: 2px; }

.chat__files { flex: none; display: flex; flex-wrap: wrap; gap: 6px; padding: 0 12px; }
.chat__files:not(:empty) { padding-block: 8px; }
.chat__file { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; padding: 0 0 0 12px; border-radius: 999px; background: rgba(255, 255, 255, 0.9); box-shadow: inset 0 0 0 1px rgba(18, 20, 23, 0.25); font-size: 0.82rem; font-weight: 600; }
.chat__file button { min-width: 36px; min-height: 36px; border: 0; background: none; font-size: 1rem; }

.chat__composer { flex: none; display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; gap: 8px; align-items: end; margin: 0 8px; padding: 8px; border-radius: 22px; background: rgba(255, 255, 255, 0.7); box-shadow: inset 0 0 0 1px rgba(18, 20, 23, 0.12); }
.chat__attach { width: 48px; height: 48px; }
.chat__composer textarea { min-height: 48px; max-height: 140px; padding: 12px 14px; resize: none; border-radius: 16px; }
.chat__send { --h: 48px; }
.chat__privacy { flex: none; margin: 0; padding: 8px 14px 12px; font-size: 0.75rem; line-height: 1.35; color: var(--ink-soft); }


/* ---- src/styles/88-viewer.css ---- */
/* Gallery VIEWER (full screen) and the BEFORE/AFTER slider. Motion is driven by src/client/viewer.js. */
.viewer { position: fixed; inset: 0; z-index: 90; color: var(--substrate); }
.viewer__scrim { position: absolute; inset: 0; background: var(--carbon); opacity: 0; }
.viewer__track { position: absolute; inset: 0; will-change: transform; }
.viewer__page {
  position: absolute; inset: 0; overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
}
.viewer__inner {
  min-height: 100%; max-width: 1180px; margin: 0 auto; padding: 64px var(--gutter) 120px;
  display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--s6); align-items: start;
}
.viewer__photos { display: grid; gap: var(--s5); }
.viewer__photo { margin: 0; }
.viewer__frame { position: relative; overflow: hidden; background: #222; touch-action: pan-y; }
.viewer__frame.is-zoomed { touch-action: none; cursor: grab; }
.viewer__frame img { width: 100%; height: auto; transform-origin: 0 0; will-change: transform; user-select: none; -webkit-user-drag: none; }
.viewer__step { margin-top: 8px; font-family: var(--font-label); font-weight: 700; font-size: calc(var(--label-scale) * 0.61rem); letter-spacing: 0.08em; text-transform: uppercase; color: #B9B5AC; }
.viewer__info { position: sticky; top: 64px; display: grid; gap: var(--s3); }
.viewer__cat { font-family: var(--font-label); font-weight: 700; font-size: var(--size-label); letter-spacing: var(--track-label); text-transform: uppercase; color: #B9B5AC; }
.viewer__title { font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: 860; font-size: var(--size-h3); line-height: 1.08; color: var(--white); }
.viewer__caption { color: #E2DFD8; }
.viewer__info .btn--secondary { background: transparent; color: var(--substrate); border-color: var(--substrate); }
.viewer__info .btn--secondary:hover { background: var(--substrate); color: var(--carbon); }
.viewer__info .stamp--pending { justify-self: start; }
.viewer__count { font-size: var(--size-small); color: #B9B5AC; }
.viewer__chrome { position: absolute; inset: 0 0 auto; display: flex; justify-content: space-between; align-items: center; padding: 10px var(--gutter); pointer-events: none; z-index: 2; }
.viewer__chrome > * { pointer-events: auto; }
.viewer__btn {
  display: grid; place-items: center; min-width: 44px; height: 44px; padding: 0 12px;
  background: var(--carbon); color: var(--substrate); border: 1.5px solid var(--substrate);
  font-family: var(--font-label); font-weight: 750; font-size: calc(var(--label-scale) * 0.63rem); letter-spacing: 0.06em; text-transform: uppercase;
}
.viewer__btn:active { transform: scale(var(--press-scale)); }
.viewer__nav { position: absolute; top: 50%; z-index: 2; translate: 0 -50%; }
.viewer__nav--prev { left: 12px; }
.viewer__nav--next { right: 12px; }
.viewer__ghost { position: fixed; left: 0; top: 0; z-index: 95; overflow: hidden; pointer-events: none; transform-origin: 0 0; will-change: transform, clip-path; }
.viewer__ghost img { width: 100%; height: 100%; object-fit: cover; }
.viewer.is-entering .viewer__page.is-current .viewer__photo:first-child .viewer__frame { visibility: hidden; }
.viewer .compare { margin-bottom: var(--s5); }
@media (max-width: 899px) {
  .viewer__inner { grid-template-columns: 1fr; padding: 60px 0 calc(110px + env(safe-area-inset-bottom)); gap: var(--s4); }
  .viewer__photos { gap: var(--s3); }
  .viewer__step { padding: 0 var(--gutter); }
  .viewer__info { position: static; padding: 0 var(--gutter); }
  .viewer__nav { display: none; }
  .viewer__cta { position: fixed; left: 0; right: 0; bottom: 0; z-index: 3; padding: 10px var(--gutter) calc(10px + env(safe-area-inset-bottom)); background: var(--carbon); border-top: 1px solid #33373D; }
  .viewer__cta .btn { width: 100%; }
}

/* ---- Before / after ---- */
.compare { position: relative; overflow: hidden; background: var(--liner); user-select: none; touch-action: pan-y; aspect-ratio: var(--ratio, 4 / 3); }
.compare__after, .compare__before { position: absolute; inset: 0; }
.compare__after .pic, .compare__before .pic { height: 100%; }
.compare__before {
  -webkit-mask-image: linear-gradient(90deg, #000 calc(var(--pos) - 4px), transparent calc(var(--pos) + 4px));
  mask-image: linear-gradient(90deg, #000 calc(var(--pos) - 4px), transparent calc(var(--pos) + 4px));
}
.compare__demo { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 6px; font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: 900; font-size: clamp(2rem, 1rem + 5vw, 4.5rem); }
.compare__demo small { font-family: var(--font-label); font-style: normal; font-weight: 700; font-size: calc(var(--label-scale) * 0.68rem); letter-spacing: 0.08em; text-transform: uppercase; }
.compare__demo--before { background: repeating-linear-gradient(-12deg, #C9C5BC 0 22px, #CFCBC2 22px 44px); color: var(--ink-soft); }
.compare__demo--after { background: var(--green); color: var(--carbon); }
.compare__line { position: absolute; top: 0; bottom: 0; left: var(--pos); width: 2px; translate: -1px 0; background: var(--white); box-shadow: 0 0 0 1px rgba(18, 20, 23, 0.4); pointer-events: none; }
.compare__grip { position: absolute; top: 50%; left: 50%; width: 44px; height: 44px; translate: -50% -50%; background: var(--carbon); border: 2px solid var(--white); }
.compare__grip::before, .compare__grip::after { content: ''; position: absolute; top: 50%; translate: 0 -50%; border: 6px solid transparent; }
.compare__grip::before { left: 5px; border-right-color: var(--white); }
.compare__grip::after { right: 5px; border-left-color: var(--white); }
.compare__tag { position: absolute; top: 10px; padding: 3px 8px; background: var(--carbon); color: var(--substrate); font-family: var(--font-label); font-weight: 750; font-size: calc(var(--label-scale) * 0.6rem); letter-spacing: 0.08em; text-transform: uppercase; pointer-events: none; }
.compare__tag--before { left: 10px; }
.compare__tag--after { right: 10px; }
.compare__range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; }
html.js .compare__range { pointer-events: none; }
.compare:has(.compare__range:focus-visible) .compare__grip { outline: 3px solid var(--green); outline-offset: 3px; }


/* ---- src/styles/90-pages.css ---- */
/* Other pages: job page, quote page, sent, 404, legal, font specimens, demo inbox. */
.job-page { max-width: 980px; margin: 0 auto; padding: var(--s6) var(--gutter) 0; }
.crumbs { font-size: var(--size-small); color: var(--ink-soft); display: flex; gap: 8px; flex-wrap: wrap; }
.crumbs a { display: inline-flex; align-items: center; min-height: 44px; }
.job-page__head { margin: var(--s4) 0 var(--s6); display: grid; gap: var(--s3); justify-items: start; }
.job-page__title { font-size: var(--size-h2); line-height: var(--lead-h2); letter-spacing: var(--track-h2); }
.job-page__caption { font-size: var(--size-lede); max-width: 40rem; }
.job-page__actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s2); }
.job-page__compare { margin-bottom: var(--s6); }
.story { display: grid; gap: var(--s5); }
.story__item { margin: 0; }
.story__item .proof { margin: 0 calc(-1 * var(--crop)); }
.job-page__pager { display: flex; justify-content: space-between; align-items: center; gap: var(--s4); margin-top: var(--s7); padding-top: var(--s4); border-top: var(--hair) solid var(--carbon); }

.sent, .not-found { min-height: 50vh; display: grid; place-items: center; }
.sent__card { max-width: 40rem; display: grid; gap: var(--s4); }
.not-found__card { max-width: 40rem; display: grid; gap: var(--s4); justify-items: start; }
.not-found__code { font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: 900; font-size: clamp(5rem, 3rem + 10vw, 10rem); line-height: 0.85; color: transparent; -webkit-text-stroke: 2px var(--navy); }

.legal { max-width: 46rem; }
.legal h2 { margin: var(--s6) 0 var(--s2); font-family: var(--font-label); font-weight: 750; font-size: calc(var(--label-scale) * 0.8rem); letter-spacing: 0.06em; text-transform: uppercase; }
.legal p { margin-top: var(--s3); }

/* /fonts: grouped specimen cards (each card switches fonts with its own CSS variables), a tools bar,
   a shortlist. Cards are glass panels on the backing-paper grid. */
.fonts-page { max-width: 1440px; }
.fonts-page__intro { display: grid; grid-template-columns: 96px minmax(0, 52rem); gap: 22px; align-items: start; margin-bottom: 2rem; }
.fonts-page__intro img { border-radius: 50%; }
.fonts-page__title { font-size: clamp(2.2rem, 1.6rem + 2.4vw, 3.6rem); line-height: 0.95; text-transform: uppercase; margin-bottom: 12px; }
.fonts-tools {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) auto; gap: 14px 28px; align-items: start;
  margin-bottom: 2.5rem; padding: 16px 20px; border-radius: 24px; --g-tint: rgba(255, 255, 255, 0.78);
}
.fonts-tools__try { display: grid; gap: 6px; font-weight: 700; }
.fonts-tools__body { border: 0; padding: 0; margin: 0; min-width: 0; }
.fonts-tools__body legend { font-weight: 700; margin-bottom: 6px; padding: 0; }
.fonts-tools__body .choices { gap: 6px; }
.fonts-tools__body .choice > span { min-height: 40px; padding: 6px 14px; font-size: 0.9rem; }
.fonts-tools__body .hint { margin: 6px 0; }
.fonts-tools__short { display: flex; gap: 10px; align-items: center; font-weight: 700; min-height: 44px; margin-top: 26px; }
.fonts-tools__short input { width: 20px; height: 20px; accent-color: var(--green); }
.fonts-group { margin-bottom: 3rem; }
.fonts-group__title { font: 800 clamp(1.4rem, 1.1rem + 1vw, 2rem)/1.1 var(--font-body); color: var(--carbon); }
.fonts-group__title span { display: inline-grid; place-items: center; min-width: 1.6em; height: 1.6em; margin-left: 6px; border-radius: 99px; background: var(--carbon); color: var(--substrate); font-size: 0.55em; vertical-align: 0.25em; }
.fonts-group__note { color: var(--ink-soft); margin: 4px 0 16px; }
.fonts-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 560px), 1fr)); gap: 18px; }
.spec {
  position: relative; display: grid; gap: 4px; align-content: start; min-width: 0; overflow: hidden;
  padding: clamp(1.1rem, 2vw, 1.75rem); border-radius: 24px; font-family: var(--font-body);
  background: rgba(255, 255, 255, 0.72); box-shadow: inset 0 1px 0 #fff, inset 0 0 0 1px rgba(18, 20, 23, 0.1), 0 14px 34px -22px rgba(10, 14, 20, 0.45);
}
.spec__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.spec__name { margin: 0; font: 800 1.05rem/1.2 var(--font-body); color: var(--carbon); }
.spec__now { padding: 2px 10px; border-radius: 99px; background: var(--green); font: 700 0.75rem/1.6 var(--font-body); }
.spec__star { margin-left: auto; width: 44px; height: 44px; border: 0; border-radius: 50%; background: rgba(18, 20, 23, 0.06); font-size: 1.35rem; line-height: 1; color: var(--carbon); }
.spec__star[aria-pressed="true"] { background: var(--glass-green); }
.spec__try, .spec__mega, .spec__outline, .spec__line {
  margin: 0; font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: var(--display-weight);
  line-height: var(--mega-lead); letter-spacing: var(--mega-track); text-transform: uppercase; color: var(--navy);
  overflow-wrap: anywhere;
}
.spec__try { font-size: calc(var(--display-scale) * clamp(2.6rem, 1.5rem + 3.6vw, 5rem)); color: var(--carbon); }
.spec__mega { margin-top: 0.1em; font-size: calc(var(--display-scale) * clamp(1.9rem, 1.2rem + 2.4vw, 3.4rem)); }
.spec__outline { margin-top: 0.1em; font-size: calc(var(--display-scale) * clamp(1.8rem, 1.1rem + 2.2vw, 3.2rem)); color: transparent; -webkit-text-stroke: max(1.5px, 0.014em) var(--navy); }
.spec__line { margin-top: 0.4em; font-size: calc(var(--display-scale) * clamp(1.05rem, 0.9rem + 0.6vw, 1.45rem)); line-height: 1.02; color: var(--carbon); }
.spec__row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 14px; }
.spec__body { margin-top: 12px; font-size: 1.02rem; line-height: 1.55; }
.spec__note { margin: 10px 0 12px; font-size: 0.9rem; color: var(--ink-soft); }
.spec__lic { font-size: 0.82rem; }
.spec > .btn { justify-self: start; }
.ptools__select { display: grid !important; gap: 4px; align-items: start !important; font-weight: 700; }
.ptools__select select { min-height: 44px; }
@media (max-width: 899px) { .fonts-tools { grid-template-columns: 1fr; } }
@media (max-width: 599px) { .fonts-page__intro { grid-template-columns: 1fr; } .fonts-page__intro img { width: 72px; height: 72px; } }

/* Demo inbox */
.outbox__leads { list-style: none; display: grid; gap: 6px; margin: var(--s3) 0 var(--s6); font-size: var(--size-small); }
.outbox__leads li { padding: 8px 10px; background: var(--white); border: 1px solid var(--line-soft); }
.outbox__item { margin-top: var(--s3); background: var(--white); border: var(--hair) solid var(--carbon); }
.outbox__item summary { padding: 12px 14px; cursor: pointer; min-height: 44px; }
.outbox__channel { display: inline-block; padding: 1px 6px; margin-right: 6px; background: var(--carbon); color: var(--substrate); font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.outbox__frame { width: 100%; height: 520px; border: 0; border-top: 1px solid var(--line-soft); background: var(--white); }
.outbox__item pre { margin: 0; padding: 14px; white-space: pre-wrap; border-top: 1px solid var(--line-soft); }

/* Preview tools panel */
.ptools {
  position: fixed; top: 44px; right: 12px; z-index: 80; width: min(340px, calc(100vw - 24px));
  padding: 14px; background: var(--white); border: var(--hair) solid var(--carbon); box-shadow: 0 12px 34px rgba(18, 20, 23, 0.25);
  display: grid; gap: 12px; font-size: var(--size-small);
}
.ptools h2 { font-family: var(--font-label); font-weight: 800; font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; }
.ptools .row { display: flex; flex-wrap: wrap; gap: 6px; }
.ptools .chip { min-height: 40px; font-size: 0.72rem; }
.ptools label { display: flex; gap: 8px; align-items: center; min-height: 40px; }
.ptools a { font-weight: 700; }
.ptools-toast { position: fixed; left: 50%; bottom: calc(var(--sticky-h) + 16px); translate: -50% 0; z-index: 81; max-width: calc(100vw - 32px); padding: 10px 14px; background: var(--carbon); color: var(--substrate); font-size: 0.85rem; }


/* ---- src/styles/92-services.css ---- */
/* SERVICE PAGES (/services, /services/<id>): the site's backing paper with its grid and printer's marks,
   a huge headline, real work as pinned prints, what's included, questions, then the quote form. */
.svc { position: relative; padding: clamp(1.5rem, 4vw, 3rem) var(--gutter) clamp(3rem, 8vw, 6rem); background-color: var(--substrate); background-image: var(--paper-grid); }
.svc__crumbs { margin-bottom: 1.4rem; }
.svc__head { max-width: 980px; }
.svc__title {
  margin: 0.4rem 0 1rem; color: var(--navy); font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight); font-stretch: var(--display-stretch);
  font-size: calc(var(--display-scale) * clamp(3rem, 1.6rem + 6vw, 7.5rem)); line-height: var(--mega-lead); letter-spacing: var(--mega-track); text-transform: uppercase; text-wrap: balance;
}
.svc__lead { max-width: 46ch; margin: 0 0 1.8rem; font-size: clamp(1.1rem, 1rem + 0.5vw, 1.4rem); line-height: 1.45; color: var(--ink); }
.svc__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.svc__h2 {
  margin: 0 0 1.2rem; font-family: var(--font-display); font-style: var(--display-style); font-weight: var(--display-weight); text-transform: uppercase;
  font-size: calc(var(--display-scale) * clamp(1.8rem, 1.2rem + 2vw, 2.8rem)); line-height: 0.95; color: var(--carbon);
}
.svc__work { margin-top: clamp(3rem, 7vw, 5.5rem); }
.svc__prints { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: clamp(18px, 3vw, 34px); }
.svc-print {
  position: relative; display: block; padding: 10px 10px 0; background: #FFFFFF; color: var(--carbon); text-decoration: none; rotate: var(--r, 0deg);
  box-shadow: 0 1px 2px rgba(18, 20, 23, 0.12), 0 18px 34px -18px rgba(18, 20, 23, 0.45);
  transition: rotate 0.35s var(--spring), translate 0.35s var(--spring), box-shadow 0.35s var(--spring);
}
a.svc-print:hover { rotate: 0deg; translate: 0 -4px; box-shadow: 0 2px 4px rgba(18, 20, 23, 0.12), 0 26px 44px -20px rgba(18, 20, 23, 0.55); }
.svc-print__photo { display: block; aspect-ratio: 4 / 3; overflow: hidden; background: #E9E6DE; }
.svc-print__photo .pic, .svc-print__photo picture, .svc-print__photo img { display: block; width: 100%; height: 100%; }
.svc-print__photo img { object-fit: cover; }
.svc-print__needed { display: grid; place-items: center; height: 100%; font: 700 0.9rem/1.2 var(--font-body); color: var(--ink-soft); background: repeating-linear-gradient(-45deg, #EFECE4 0 12px, #E7E3D9 12px 24px); }
.svc-print__cap { display: grid; gap: 2px; padding: 10px 2px 12px; }
.svc-print__cap b { font-weight: 800; }
.svc-print__cap small { color: var(--ink-soft); }
.svc__empty { color: var(--ink-soft); }
.svc__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr)); gap: clamp(1.5rem, 4vw, 3rem); margin-top: clamp(3rem, 7vw, 5rem); }
.svc__box { padding: clamp(1.3rem, 3vw, 2rem); border-radius: 24px; background: rgba(255, 255, 255, 0.72); box-shadow: inset 0 1px 0 #fff, inset 0 0 0 1px rgba(18, 20, 23, 0.08), 0 16px 34px -24px rgba(18, 20, 23, 0.5); }
.svc__includes { display: grid; gap: 12px; margin: 0; padding: 0; list-style: none; }
.svc__includes li { position: relative; padding-left: 34px; font-size: 1.08rem; line-height: 1.4; }
.svc__includes li::before { content: ''; position: absolute; left: 0; top: 0.1em; width: 22px; height: 22px; border-radius: 50%; background: var(--green) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23121417' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 12.5l4 4L18 8'/%3E%3C/svg%3E") center / 14px no-repeat; }
.svc__q { border-top: 1px solid rgba(18, 20, 23, 0.12); }
.svc__q:first-of-type { border-top: 0; }
.svc__q summary { display: flex; justify-content: space-between; gap: 16px; padding: 14px 0; font-weight: 800; font-size: 1.05rem; cursor: pointer; list-style: none; }
.svc__q summary::-webkit-details-marker { display: none; }
.svc__q summary::after { content: '+'; flex: none; font-size: 1.4rem; line-height: 1; color: var(--green-press); transition: rotate 0.25s var(--spring); }
.svc__q[open] summary::after { rotate: 45deg; }
.svc__q p { margin: 0 0 16px; line-height: 1.55; color: var(--ink); }
.svc__more { margin-top: clamp(3rem, 7vw, 5rem); }
.svc__more ul { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; padding: 0; list-style: none; }
.chip-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 18px; border-radius: 999px; background: #FFFFFF; color: var(--carbon); font-weight: 700; text-decoration: none; box-shadow: inset 0 0 0 1.5px rgba(18, 20, 23, 0.14); transition: background 0.2s, box-shadow 0.2s; }
.chip-link:hover { background: var(--green-tint); box-shadow: inset 0 0 0 1.5px var(--green); }

/* /services: the grid of services */
.svc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: clamp(16px, 2.5vw, 28px); margin: clamp(2rem, 5vw, 3.5rem) 0 0; padding: 0; list-style: none; }
.svc-card { display: grid; height: 100%; border-radius: 24px; overflow: hidden; background: #FFFFFF; color: var(--carbon); text-decoration: none; box-shadow: inset 0 0 0 1px rgba(18, 20, 23, 0.08), 0 16px 34px -24px rgba(18, 20, 23, 0.5); transition: translate 0.3s var(--spring), box-shadow 0.3s var(--spring); }
.svc-card:hover { translate: 0 -4px; box-shadow: inset 0 0 0 1px rgba(18, 20, 23, 0.1), 0 26px 44px -24px rgba(18, 20, 23, 0.6); }
.svc-card__photo { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--navy); }
.svc-card__photo .pic, .svc-card__photo picture, .svc-card__photo img { display: block; width: 100%; height: 100%; }
.svc-card__photo img { object-fit: cover; }
.svc-card__type { display: grid; place-items: center; height: 100%; padding: 1rem; color: var(--substrate); text-align: center; font-family: var(--font-display); font-weight: var(--display-weight); font-style: var(--display-style); text-transform: uppercase; font-size: calc(var(--display-scale) * 1.9rem); line-height: 0.95; background: radial-gradient(120% 90% at 50% 0%, rgba(29, 170, 71, 0.35), rgba(29, 170, 71, 0) 60%), var(--navy); }
.svc-card__body { display: grid; gap: 6px; padding: 18px 20px 20px; }
.svc-card__body b { font-size: 1.15rem; font-weight: 800; }
.svc-card__body small { color: var(--ink-soft); font-size: 0.98rem; line-height: 1.4; }
.svc-card__go { margin-top: 6px; color: var(--green-press); font-weight: 800; }
.svc__all { display: inline-block; margin-top: 1.4rem; color: var(--navy); font-weight: 800; }


/* ---- src/styles/95-admin.css ---- */
/* OWNER ADMIN (/admin): phone-first. Big targets, one job per screen. */
body.is-admin { background: var(--substrate); }
.admin { max-width: 640px; margin: 0 auto; padding: 0 var(--gutter) 120px; }
.adm-bar { position: sticky; top: 0; z-index: 10; display: flex; align-items: center; gap: 10px; padding: 10px 0; background: var(--substrate); border-bottom: var(--hair) solid var(--carbon); }
.adm-bar img { width: 40px; height: 40px; border-radius: 50%; }
.adm-bar__title { flex: 1; font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: 860; font-size: calc(var(--display-scale) * 1.15rem); color: var(--navy); line-height: 1.1; }
.adm-tabs { display: grid; grid-template-columns: 1fr 1fr; margin: 14px 0; border: var(--hair) solid var(--carbon); }
.adm-tabs button { min-height: 48px; border: 0; background: var(--substrate); font-family: var(--font-label); font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; font-size: 0.85rem; }
.adm-tabs button[aria-selected="true"] { background: var(--carbon); color: var(--substrate); }
.adm-new { width: 100%; --h: 60px; font-size: 1.05rem; margin-bottom: 14px; }
.adm-card { padding: 16px; background: var(--white); border: var(--hair) solid var(--carbon); margin-bottom: 12px; }
.adm-card h2 { font-family: var(--font-display); font-style: var(--display-style); font-stretch: var(--display-stretch); font-weight: 860; font-size: calc(var(--display-scale) * 1.4rem); color: var(--navy); line-height: 1.1; margin-bottom: 12px; }
.adm-demo { padding: 10px 12px; margin: 12px 0; background: var(--tape); border: 1.5px dashed var(--carbon); font-size: var(--size-small); }

.adm-list { list-style: none; display: grid; gap: 8px; }
.adm-job { display: grid; grid-template-columns: 28px 64px 1fr; gap: 10px; align-items: center; padding: 8px; background: var(--white); border: var(--hair) solid var(--carbon); touch-action: pan-y; }
.adm-job.is-dragging { box-shadow: 0 12px 28px rgba(18, 20, 23, 0.25); z-index: 2; position: relative; }
.adm-job.is-hidden-job { opacity: 0.6; }
.adm-job__handle { width: 28px; height: 52px; display: grid; place-items: center; cursor: grab; touch-action: none; border: 0; background: transparent; }
.adm-job__handle::before { content: ''; width: 14px; height: 14px; background: radial-gradient(circle, var(--carbon) 1.6px, transparent 1.8px) 0 0 / 7px 7px; }
.adm-job__thumb { width: 64px; height: 64px; object-fit: cover; background: var(--liner); }
.adm-job__main { min-width: 0; }
.adm-job__title { font-weight: 800; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adm-job__meta { font-size: 0.8rem; color: var(--ink-soft); }
.adm-job__flags { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 4px; }
.adm-job__actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; }
.adm-job__actions button, .adm-job__actions a { min-height: 44px; padding: 0 12px; border: 1.5px solid var(--carbon); background: var(--substrate); font-size: 0.8rem; font-weight: 700; display: inline-flex; align-items: center; text-decoration: none; color: var(--carbon); }
.adm-job__actions .danger { color: var(--danger); border-color: var(--danger); }
.adm-job__move { margin-left: auto; display: flex; gap: 6px; }

.adm-photos { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 10px 0; }
.adm-photo { position: relative; aspect-ratio: 1; background: var(--liner); }
.adm-photo img { width: 100%; height: 100%; object-fit: cover; }
.adm-photo button.remove { position: absolute; top: 4px; right: 4px; width: 36px; height: 36px; border: 0; background: var(--carbon); color: var(--white); font-size: 1.1rem; }
.adm-photo select { position: absolute; left: 4px; right: 4px; bottom: 4px; min-height: 36px; padding: 2px 6px; font-size: 0.8rem; border: 1.5px solid var(--carbon); }
.adm-photo progress { position: absolute; left: 6px; right: 6px; top: 50%; width: calc(100% - 12px); }
.adm-pick { display: grid; place-items: center; gap: 6px; min-height: 120px; border: 2px dashed var(--carbon); background: var(--white); text-align: center; font-weight: 800; cursor: pointer; position: relative; }
.adm-pick input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.adm-pick small { font-weight: 400; color: var(--ink-soft); }
.adm-row { display: flex; gap: 10px; align-items: center; min-height: 48px; }
.adm-post { position: sticky; bottom: 0; padding: 12px 0 calc(12px + env(safe-area-inset-bottom)); background: var(--substrate); display: flex; gap: 10px; }
.adm-post .btn--primary { flex: 1; --h: 56px; }
.adm-msg { padding: 10px 12px; margin: 10px 0; border-left: 4px solid var(--carbon); background: var(--liner); font-size: var(--size-small); }
.adm-msg.is-error { border-color: var(--danger); background: #FBE9E6; }
.adm-msg.is-ok { border-color: var(--green); background: var(--green-tint); }

.adm-lead { padding: 12px; background: var(--white); border: var(--hair) solid var(--carbon); }
.adm-lead summary { cursor: pointer; display: grid; gap: 2px; min-height: 44px; }
.adm-lead__who { font-weight: 800; }
.adm-lead__meta { font-size: 0.8rem; color: var(--ink-soft); }
.adm-lead dl { display: grid; grid-template-columns: max-content 1fr; gap: 4px 12px; margin: 10px 0; font-size: 0.92rem; }
.adm-lead dt { color: var(--ink-soft); }
.adm-lead dd { margin: 0; overflow-wrap: anywhere; white-space: pre-wrap; }
.adm-lead .transcript { max-height: 260px; overflow: auto; padding: 8px; background: var(--substrate); font-size: 0.85rem; }


/* ---- src/styles/99-reduced-motion.css ---- */
/* Reduced motion: no slides or springs. Gentle fades only; everything still works.
   (The head script also turns Motion off for these visitors, so the scenes don't start.) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
  .btn:active, .tab:active, .qr:active, .sqbtn:active, .sticker:hover, .sticker:active, .choice:active > span, .launcher:active .launcher__badge { transform: none; }
  .launcher__label { transition: opacity 160ms ease; transform: none; }
  .msg--typing span { animation: none; opacity: 0.6; }
  .sticky-bar { transition: none; }
  .wo.is-sent .wo__stamp { transform: none; transition: opacity 160ms ease; }
}
@media (prefers-contrast: more) {
  :root { --ink-soft: #2B2F35; --line-soft: #8A857C; }
  .ghost { -webkit-text-stroke-color: rgba(18, 51, 93, 0.4); }
  .sw__base { color: #A8A396; }
}
