/* Pensacola Web Studio - tokens from docs/pws/PALETTE.md, faces from docs/pws/FONTS.md */
:root {
  --paper:        #F5F4F4;
  --ink:          #08152B;
  --label:        #A2ADBE;
  --magenta-text: #9A29BD;
  --body:         #4E576B;

  --grad-cyan:    #2DB9FA;
  --grad-violet:  #9188DA;
  --grad-magenta: #A83ABA;

  --rule-aqua:    #08D6E2;
  --rule-cyan:    #13BAF7;
  --rule-magenta: #981AB8;

  --tri-navy:     #0D1A34;
  --tri-cyan:     #0CD8ED;
  --tri-violet:   #9783F6;


  /* Work section (screen 2) - docs/pws/PALETTE.md "Work section" */
  --violet-text:     #8839BB; /* OUR WORK side label */
  --card-border:     #DDDEE8; /* 1px card frame */
  --card-border-top: #CFCEDF; /* the frame's top edge reads heavier (PALETTE note 6) */
  --dot-magenta:     #BA72B6;
  --dot-grey:        #B7B7BA;
  --dot-cyan:        #3ACAE0;
  --note-cyan:       #48B5DC; /* side-note L-rule, 1.5 mockup px wide */
  --note-violet:     #9872C8;
  --note-blue:       #6B9EED;
  --note-magenta:    #C9A5D1;

  /* Pricing section (screen 3) - docs/pws/PALETTE.md "Pricing section" */
  --ink-blue:        #08183B; /* feature lines, SETUP FEE / PER MONTH */
  --price-cyan:      #1192D9; /* price divider, top */
  --price-blue:      #1357DA; /* price divider, middle */
  --price-violet:    #6837A4; /* price divider, bottom */
  --side-cyan:       #46AFF0; /* left rule, upper segment */
  --side-lavender:   #92ACE4; /* left rule, upper segment's lower end */
  --side-periwinkle: #7384EC; /* left rule, lower segment's top */
  --side-blue:       #1E97ED; /* left rule, lower segment */
  --side-blue-end:   #4288EC; /* left rule, lower segment's bottom */
  --edge-violet:     #A678CC; /* right-edge rule, middle and lower half */

  /* FAQ section (screen 4) - docs/pws/PALETTE.md "FAQ section" */
  --faq-border:       #E5E9ED; /* closed-item frame, 1.75 mockup px (fallback --card-border, dE 4.3) */
  --faq-cyan:         #47C1E4; /* open-item frame, left edge and top-left */
  --faq-lavender:     #AEABDA; /* open-item frame, top middle to top-right, right edge top */
  --faq-magenta:      #C688CC; /* open-item frame, right edge lower half and bottom-right corner */
  --faq-minus:        #0E4BDC; /* the open item's minus (fallback --price-blue, dE 3.8) */
  --faq-rule-blue:    #6B89E1; /* heading rule, blue bands (fallback --side-periwinkle, dE 3.1) */
  --faq-rule-violet:  #9653C7; /* heading rule, middle */
  --faq-rule-magenta: #AF66C8; /* heading rule, right end */

  /* Start-project modal (screen 5) - docs/pws/PALETTE.md "Start-project modal"; the YOUR BUSINESS stops are literals
     inside --modal-title-gradient (set on the panel, where --u exists) */
  --modal-navy:           #020915; /* panel field, top and centre; the panel's colour behind plate A28 */
  --modal-violet:         #0B0A21; /* panel field, right and bottom-right glow */
  --modal-ring-violet:    #6962C3; /* ring colour line, top and bottom middle */
  --modal-ring-magenta:   #9246B9; /* ring, top-right corner */
  --modal-ring-steel:     #6AA3C2; /* ring, right edge upper */
  --modal-ring-cyan:      #50D0F8; /* ring, bottom-right */
  --modal-ring-aqua:      #7CE8FB; /* ring, bottom-left */
  --modal-field-blue:     #547EA5; /* field border, left stop (M7c: lifted along its hue from the mockup's #4C759C to >= 3:1) */
  --modal-field-slate:    #5C769F; /* field border, middle stop (M7c: from #4C668E) */
  --modal-field-violet:   #746E9A; /* field border, right stop (M7c: from #615B86) */
  --modal-divider:        #293A55; /* icon divider hairline */
  --modal-placeholder:    #848CA2; /* placeholder ink, name and address. M7c (user-directed, over mockup fidelity): lifted
                                      along its hue from the mockup's #6D758A to >= 4.5:1 on the plate */
  --modal-placeholder-hi: #8D99B4; /* 'https://example.com' and 'Select timeframe', drawn lighter in the mockup (M5); M7c: from
                                      #75809A, keeping its lead over --modal-placeholder */
  --modal-ink:            #FCFDFF; /* labels, heading line 1, submit label: the rendered core reaches the mockup's (M5) */
  --modal-btn-cyan:       #7BDDF7; /* submit border, top-left */
  --modal-btn-periwinkle: #86A0EE; /* submit border, ~30% */
  --modal-btn-violet:     #A277E6; /* submit border, middle */
  --modal-btn-pink:       #DF82E0; /* submit border, right half of the top */
  --modal-btn-magenta:    #BE5EBB; /* submit border, right edge */
  --modal-btn-glow:       #2C0E48; /* submit interior glow at the right end */
  --modal-error:          #EE8F86; /* proposed, not in the mockup: invalid-field border and error text (warm, restrained) */

  /* CTA section (screen 6) - docs/pws/PALETTE.md "CTA section". Reused: heading --tri-navy, body --ink-blue; rim,
     button label and rocket --modal-ink; rule left end --tri-cyan; glow hues --side-blue-end and --modal-btn-violet */
  --cta-rule-magenta: #AB3AEA;                 /* rule, right end */
  --cta-btn-cyan:     #16C7F6;                 /* button fill, left edge (fallback --faq-cyan, dE 3.1) */
  --cta-btn-blue:     #4182FC;                 /* button fill, 30% (fallback --side-blue-end, dE 3.0) */
  --cta-btn-violet:   #7260F9;                 /* button fill, 55% */
  --cta-btn-magenta:  #C43CBA;                 /* button fill, right edge */
  --cta-glass:        rgb(250 250 251 / .66);  /* card fill over the backdrop (PALETTE note 1) */

  /* How It Works section - docs/pws/H5-palette-fonts.md. Reused: body --ink-blue, route start --side-cyan, pin end
     --grad-magenta, right crosshairs --grad-magenta, right rule --grad-violet / --edge-violet, coordinates .coords.
     The --look-*, --field-* and --about-* tokens it also reuses are scoped to their own pages, so they are copied */
  --how-title:        #061649; /* step titles (--ink-blue dE 4.1) */
  --how-route-violet: #6A5CDD; /* route dashes after pin 2, pin stroke middle */
  --how-pin-dot:      #383E9D; /* pin centre */
  --how-num-blue:     #1A6FD2; /* numeral stroke, top left (stroke-core sample, H7) */
  --how-num-indigo:   #1449C4; /* numeral stroke, middle */
  --how-num-violet:   #7A30B4; /* numeral stroke, bottom right */
  --how-coords:       #6E8AB0; /* coordinates under the arch (mockup core; the hero's --label reads too light here) */
  --how-cross-cyan:   #0AA2E6; /* left crosshairs (= --look-rule-cyan-2) */
  --how-rule-cyan:    #88BBDC; /* left side rule (= --field-cyan) */
  --how-vlabel:       #2B4474; /* vertical coordinate labels */

  --font-caps:  'Roboto Condensed', 'Arial Narrow', sans-serif;
  --font-label: 'Lekton', 'Courier New', monospace;
  --font-sub:   'Abel', 'Arial Narrow', sans-serif;
  --font-body:  'Barlow Semi Condensed', 'Arial Narrow', sans-serif;
  --font-feature: 'Barlow Condensed', 'Arial Narrow', sans-serif;

  --btn-gradient: linear-gradient(90deg, var(--grad-cyan) 0%, var(--grad-violet) 28%, var(--grad-magenta) 55%, var(--grad-magenta) 100%);
  --focus: var(--grad-violet);
}

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

/* light-only design: opt out of browser auto-dark (Chrome/Samsung Internet), which lightens text over the light plates */
html { background: var(--paper); color-scheme: only light; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; }
p, h1, h2, ul { margin: 0; }
ul { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

a:focus-visible,
button:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 4px;
  border-radius: 1px;
}

/* ---------- shared pieces ---------- */

.btn {
  display: inline-block;
  font-family: var(--font-caps);
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink);
  border: 2px solid transparent;
  background:
    linear-gradient(var(--paper), var(--paper)) padding-box,
    var(--btn-gradient) border-box;
  transition: background .2s ease, color .2s ease;
}
.btn:hover,
.btn:focus-visible {
  background:
    linear-gradient(90deg, rgb(45 185 250 / .14), rgb(145 136 218 / .14), rgb(168 58 186 / .14)) padding-box,
    linear-gradient(var(--paper), var(--paper)) padding-box,
    var(--btn-gradient) border-box;
  color: var(--magenta-text);
}

.btn-underline-header {
  background: linear-gradient(90deg,
    var(--grad-cyan) 0 6.2%, #8D4ADF 6.2% 15.5%,
    transparent 15.5% 17.7%,
    #6874E8 17.7% 53%, #A62ABB 53% 100%);
}
.btn-underline-cta {
  background: linear-gradient(90deg,
    var(--grad-cyan) 0 15.7%, transparent 15.7% 19.1%,
    var(--grad-cyan) 19.1% 53%, #8D4ADF 53%, #6A6AE0 87.8%, var(--grad-magenta) 87.8% 100%);
}

.logo-rule {
  background: linear-gradient(90deg, var(--rule-aqua) 0, var(--rule-cyan) 78.6%, var(--rule-magenta) 78.6% 100%);
}
.intro-rule {
  background: linear-gradient(90deg, #1FE4EA 0, #12BBF3 80%, var(--rule-magenta) 80% 100%);
}
.intro-line { background: linear-gradient(180deg, #7AB2EE, #C786DA); }
.side-rule  { background: linear-gradient(180deg, #60CFEC, #C47EDA); }

.nav-list a,
.footer-nav a {
  font-family: var(--font-caps);
  font-weight: 500;
  color: var(--ink);
  transition: color .2s ease;
}
.nav-list a:hover,
.nav-list a:focus-visible,
.footer-nav a:hover,
.footer-nav a:focus-visible { color: var(--magenta-text); }

.coords {
  font-family: var(--font-label);
  font-weight: 400;
  color: var(--label);
  white-space: nowrap;
}
.subhead {
  font-family: var(--font-sub);
  font-weight: 400;
  color: var(--ink);
  white-space: nowrap;
}
.location {
  font-family: var(--font-label);
  font-weight: 700;
  color: var(--magenta-text);
}
.tagline {
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--body);
}
.estd-text {
  font-family: var(--font-label);
  font-weight: 700;
  color: var(--ink);
}
.vertical-text {
  font-family: var(--font-label);
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}

.scroll-label {
  font-family: var(--font-label);
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}
.tri-bar {
  display: block;
  background: linear-gradient(90deg,
    var(--tri-navy) 0 44%, var(--tri-cyan) 44% 75.3%, var(--tri-violet) 75.3% 100%);
}
.scroll-cue:hover .scroll-label,
.scroll-cue:focus-visible .scroll-label { color: var(--magenta-text); }

/* ---------- mobile first (below 900px): simple flow ---------- */

.site-header {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px;
}
.logo-rule, .btn-underline-header { display: none; }
.brand { display: block; transition: opacity .2s ease; }
/* below 900: a 44px-tall tap box; the header row centres it, so the wordmark does not move */
@media (max-width: 899.98px) {
  .brand { display: flex; align-items: center; min-height: 44px; }
}
.brand:hover { opacity: .78; }
.brand img { width: 176px; height: auto; }

.nav-toggle {
  position: relative;
  z-index: 40;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}
.nav-toggle-bars,
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  display: block;
  width: 24px; height: 2px;
  background: currentColor;
  transition: transform .2s ease, background .2s ease;
}
.nav-toggle-bars { position: relative; }
.nav-toggle-bars::before,
.nav-toggle-bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle-bars::before { top: -7px; }
.nav-toggle-bars::after  { top: 7px; }
.nav-toggle:hover { color: var(--magenta-text); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after  { transform: translateY(-7px) rotate(-45deg); }

.site-nav {
  position: fixed;
  z-index: 30;
  top: 0; right: 0;
  width: min(84vw, 320px);
  height: 100vh;
  height: 100dvh;
  padding: 88px 24px 24px;
  background: var(--paper);
  box-shadow: -12px 0 32px rgb(8 21 43 / .12);
  transform: translateX(100%);
  visibility: hidden;
  transition: transform .25s ease, visibility 0s linear .25s;
}
.site-nav[data-open] {
  transform: none;
  visibility: visible;
  transition: transform .25s ease;
}
.nav-list a,
.footer-nav a {
  display: flex;
  align-items: center;
  min-height: 48px;
  font-size: 16px;
  letter-spacing: .21em;
}
.site-nav .btn-header {
  margin-top: 24px;
  padding: 15px 20px;
  font-size: 14px;
  letter-spacing: .23em;
}

.hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px 16px 24px;
  text-align: center;
}
.hud-arch { width: 120px; height: 60px; }
.coords { margin-top: 6px; font-size: 12px; letter-spacing: .14em; }
.lockup { width: 100%; margin-top: 20px; }
.lockup img { width: 100%; height: auto; }
.lockup .lettering-web-studio { width: 79%; margin: 4px auto 0; }
.subhead { margin-top: 20px; font-size: min(28px, 7vw); letter-spacing: .112em; }
.btn-cta {
  margin-top: 24px;
  padding: 16px 22px 16px calc(22px + .31em);
  font-size: 14px;
  letter-spacing: .31em;
  word-spacing: 3px;
}
.btn-cta { position: relative; }
/* below 900 the underline hangs off the button itself so it stays flush with its left edge */
.btn-cta::after {
  content: "";
  position: absolute;
  left: -2px; top: calc(100% + 6px);
  width: 34%; height: 2px;
  background: linear-gradient(90deg,
    var(--grad-cyan) 0 15.7%, transparent 15.7% 19.1%,
    var(--grad-cyan) 19.1% 53%, #8D4ADF 53%, #6A6AE0 87.8%, var(--grad-magenta) 87.8% 100%);
}
.btn-underline-cta { display: none; }
.intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 40px;
}
.intro-rule { display: block; width: 90px; height: 4px; }
.intro-line { display: none; }
.location {
  margin-top: 20px;
  padding-left: .575em;
  font-size: 15px;
  line-height: 1.6;
  letter-spacing: .575em;
}
.tagline { margin-top: 16px; font-size: 16px; line-height: 1.56; letter-spacing: .094em; }
.estd, .side-rule, .vertical-text { display: none; }

/* the band is the hero photo on mobile: taller than its 3.46:1 frame, cropped on the plaza */
.band {
  width: 100%;
  height: min(56vw, 360px);
  object-fit: cover;
  object-position: 52% 50%;
}

.strip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  padding: 24px 16px 32px;
}
.scroll-cue { display: none; }

/* ---------- desktop: 16:9 stage, every coordinate in mockup px ---------- */

@media (min-width: 900px) {
  .page { container-type: inline-size; }

  /* the header sits before <main> in the DOM (one banner, then one main holding both screens) but still
     draws on the hero stage: it is 0 px tall at the top of .page, so it carries the stage's units too */
  /* the site footer (after the FAQ screen) is sized in the same stage units and text floors */
  .stage, .site-header, .site-footer {
    /* the stage always spans the full width (100cqw, so a classic scrollbar never causes a horizontal
       scroll); on windows shorter than 16:9 the hero is taller than the window and the page scrolls */
    --u: calc(calc(var(--cqw, 1cqw) * 100) / 2048);
    /* text units --t-*: equal to --u here; floored for small stages below. --d-* = --t-* minus --u,
       the growth the layout compensates for (literally 0 here, so stages >= 1847 are untouched) */
    --t-nav: var(--u); --t-btn: var(--u); --t-crd: var(--u); --t-tag: var(--u); --t-cta: var(--u);
    --t-vert: var(--u); --t-scr: var(--u); --t-loc: var(--u); --t-estd: var(--u);
    --t-legal: var(--u);
    --d-nav: 0px; --d-btn: 0px; --d-crd: 0px; --d-loc: 0px; --d-cta: 0px; --d-estd: 0px;
  }
  .stage {
    position: relative;
    width: calc(var(--u) * 2048);
    height: calc(var(--u) * 1152);
  }
  /* live text floor: every run = max(floor, mockup size * stage/2048) - 11px labels, 12px tagline.
     --t-* = max(--u, floor / mockup px). The largest ratio is the vertical text's 11/12.2 = 0.901639,
     so no floor can bind on a stage >= 2048 * 0.901639 = 1846.6; there --t-* stays literally --u.
     A container query on .page, so the gate reads the stage width itself (scrollbar excluded). */
  @container (max-width: 1846.5px) {
    .stage, .site-header, .site-footer {
      --t-nav:  max(var(--u), 0.887097px);  /* 11 / 12.4  */
      --t-btn:  max(var(--u), 0.852713px);  /* 11 / 12.9  */
      --t-crd:  max(var(--u), 0.758621px);  /* 11 / 14.5  */
      --t-tag:  max(var(--u), 0.761905px);  /* 12 / 15.75 */
      --t-cta:  max(var(--u), 0.711974px);  /* 11 / 15.45 */
      --t-vert: max(var(--u), 0.901639px);  /* 11 / 12.2  */
      --t-scr:  max(var(--u), 0.808824px);  /* 11 / 13.6  */
      --t-loc:  max(var(--u), 0.683230px);  /* 11 / 16.1  */
      --t-estd: max(var(--u), 0.694006px);  /* 11 / 15.85 */
      --t-legal: max(var(--u), 0.901639px); /* 11 / 12.2 (footer legal row; the same ratio as the vertical text) */
      --d-nav:  calc(var(--t-nav) - var(--u));
      --d-btn:  calc(var(--t-btn) - var(--u));
      --d-crd:  calc(var(--t-crd) - var(--u));
      --d-loc:  calc(var(--t-loc) - var(--u));
      --d-cta:  calc(var(--t-cta) - var(--u));
      --d-estd: calc(var(--t-estd) - var(--u));
    }
  }
  /* wrappers stay static and boxless-in-effect so every piece positions against the stage */
  .site-header, .hero, .strip { display: block; padding: 0; }
  /* the header row and <main> both sit this many mockup px higher than the mockup (less space above the
     wordmark). The header is 0 px tall, so <main> does not follow it: it takes the same lift as a margin */
  .page { --hdr-lift: 20; }
  .site-header { --hdr-up: calc(var(--u) * var(--hdr-lift)); }
  .page > main { margin-top: calc(calc(var(--cqw, 1cqw) * 100) / 2048 * var(--hdr-lift) * -1); }
  /* A04's subject is ~2.4% narrower than the mockup's and sits right of it (patch-aligned at 2048):
     stretch x by 1.02423 with the right edge pinned to the stage's (no overflow right), and clip the
     49.63 that hangs off the left. Vertical scale is already 1:1. */
  .band {
    position: absolute;
    z-index: 0;
    left: calc(var(--u) * -49.63);
    top: calc(var(--u) * 560);
    width: calc(var(--u) * 2097.63);
    height: calc(var(--u) * 592);
    object-fit: fill;
    clip-path: inset(0 0 0 calc(var(--u) * 49.63));
  }
  .hero > *, .site-header > *, .strip > *, .site-nav > *, .intro > * { position: absolute; z-index: 1; }
  .hero .intro, .site-nav, .site-nav .nav-list { position: static; margin: 0; }
  .hero .intro { display: block; }
  .hero { text-align: left; }

  /* header */
  .nav-toggle { display: none; }
  .site-nav {
    width: auto; height: auto; padding: 0;
    background: none; box-shadow: none;
    transform: none; visibility: visible; transition: none;
  }
  .logo-rule {
    display: block;
    left: calc(var(--u) * 57); top: calc(var(--u) * 35 - var(--hdr-up));
    width: calc(var(--u) * 56); height: calc(var(--u) * 4);
  }
  .brand { left: calc(var(--u) * 50.03); top: calc(var(--u) * 53.03 - var(--hdr-up)); }
  .brand img { width: calc(var(--u) * 245.93); }

  .nav-list li { position: absolute; top: calc(var(--u) * 72.26 - var(--d-btn) * 17.55 - var(--d-nav) * 6.2 - var(--hdr-up)); }
  .nav-list a,
  .footer-nav a {
    display: block;
    min-height: 0;
    font-size: calc(var(--t-nav) * 14.4);
    line-height: 1;
    letter-spacing: .21em;
    position: relative;
  }
  .nav-list a::after,
  .footer-nav a::after {
    content: "";
    position: absolute;
    left: 0; right: .21em;
    bottom: calc(var(--u) * -8);
    height: calc(var(--u) * 2);
    background: var(--btn-gradient);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .2s ease;
  }
  .nav-list a:hover::after,
  .nav-list a:focus-visible::after,
  .footer-nav a:hover::after,
  .footer-nav a:focus-visible::after { transform: scaleX(1); }
  /* each item shifts left by the button growth plus the growth of itself and every item to its right;
     the ink gaps (49.4 / 38.6 / 47.4 measured) are widened 15% leftward from CONTACT, which holds its place */
  .nav-work     { left: calc(var(--u) * 1235.94 - var(--d-btn) * 133 - var(--d-nav) * 263.75); }
  .nav-how      { left: calc(var(--u) * 1337.15 - var(--d-btn) * 133 - var(--d-nav) * 222.94); }
  .nav-about    { left: calc(var(--u) * 1503.69 - var(--d-btn) * 133 - var(--d-nav) * 115.19); }
  .nav-contact  { left: calc(var(--u) * 1611.3 - var(--d-btn) * 133 - var(--d-nav) * 66.89); }

  .site-nav .btn-header {
    margin: 0;
    /* grows leftward from its right edge at 1973, by its text growth only (133 = native text width);
       the header row lifts by d*24 so the floored nav clears the HUD arch ink on small stages */
    left: calc(var(--u) * 1743 - var(--d-btn) * 133); top: calc(var(--u) * 55 - var(--d-btn) * 24 - var(--hdr-up));
    width: calc(var(--u) * 230 + var(--d-btn) * 133); height: calc(var(--u) * 48 + var(--d-btn) * 12.9);
    padding: calc(var(--u) * 15.59) 0 0 calc(var(--u) * 37.5);
    border-width: calc(var(--u) * 2);
    font-size: calc(var(--t-btn) * 14.9);
    letter-spacing: .22em;
    word-spacing: calc(var(--t-btn) * 2.5);
  }
  .btn .w-proj { letter-spacing: .165em; }
  .btn-cta .w-proj { letter-spacing: .26em; }
  .btn-underline-header {
    display: block;
    left: calc(var(--u) * 1733 - var(--d-btn) * 133); top: calc(var(--u) * 109 - var(--d-btn) * 11.1 - var(--hdr-up));
    width: calc(var(--t-btn) * 113); height: calc(var(--u) * 2);
  }

  /* hero upper */
  .hud-arch {
    left: calc(var(--u) * 950); top: calc(var(--u) * 80);
    width: calc(var(--u) * 180); height: calc(var(--u) * 90);
  }
  .coords {
    margin: 0;
    left: calc(var(--u) * 938.8 - var(--d-crd) * 102.08); top: calc(var(--u) * 172.55 - var(--d-crd) * 14.5);
    font-size: calc(var(--t-crd) * 14.5);
    line-height: 1;
    letter-spacing: .14em;
  }
  .lockup { margin: 0; width: auto; position: static !important; }
  .lockup img { position: absolute; height: auto; margin: 0; }
  .lockup .lettering-pensacola {
    left: calc(var(--u) * 475.02); top: calc(var(--u) * 188.02);
    width: calc(var(--u) * 1126.99);
  }
  .lockup .lettering-web-studio {
    left: calc(var(--u) * 580.74); top: calc(var(--u) * 351.74);
    width: calc(var(--u) * 891.52);
    margin: 0;
  }
  .subhead {
    margin: 0;
    left: calc(var(--u) * 791); top: calc(var(--u) * 444.1);
    font-size: calc(var(--u) * 40.7);
    line-height: 1;
    letter-spacing: .112em;
  }
  .btn-cta {
    margin: 0;
    left: calc(var(--u) * 851 - var(--d-cta) * 172); top: calc(var(--u) * 515);
    width: calc(var(--t-cta) * 344); height: calc(var(--t-cta) * 53);
    padding: calc(var(--t-cta) * 17.4) 0 0 calc(var(--t-cta) * 56.45);
    border-width: calc(var(--u) * 2);
    font-size: calc(var(--t-cta) * 16.45);
    letter-spacing: .30em;
    word-spacing: calc(var(--t-cta) * 2.5);
  }
  .btn-cta::after { display: none; }
  .btn-underline-cta {
    display: block;
    margin: 0;
    left: calc(var(--u) * 851 - var(--d-cta) * 172); top: calc(var(--u) * 574 + var(--d-cta) * 59);
    width: calc(var(--t-cta) * 115); height: calc(var(--u) * 2.5);
  }

  .intro-rule {
    left: calc(var(--u) * 100); top: calc(var(--u) * 301);
    width: calc(var(--u) * 90); height: calc(var(--u) * 4);
  }
  .intro-line {
    display: block;
    left: calc(var(--u) * 80); top: calc(var(--u) * 319);
    width: calc(var(--u) * 2); height: calc(var(--u) * 293);
  }
  .location {
    margin: 0; padding: 0;
    left: calc(var(--u) * 140.9); top: calc(var(--u) * 327.94);
    font-size: calc(var(--t-loc) * 16.1);
    line-height: calc(var(--t-loc) * 25);
    letter-spacing: .575em;
    white-space: nowrap;
  }
  .tagline {
    margin: 0;
    left: calc(var(--u) * 141.2); top: calc(var(--u) * 392.2 + var(--d-loc) * 64.26);
    font-size: calc(var(--t-tag) * 16.75);
    line-height: calc(var(--t-tag) * 25);
    letter-spacing: .094em;
    white-space: nowrap;
    text-align: left;
  }

  .estd {
    display: block;
    left: calc(var(--u) * 1690 - var(--d-estd) * 100); top: calc(var(--u) * 290 - var(--d-estd) * 95);
    width: calc(var(--t-estd) * 200); height: calc(var(--t-estd) * 190);
  }
  .estd-ring { width: 100%; height: 100%; }
  .estd-text {
    position: absolute;
    left: calc(var(--t-estd) * 50); top: calc(var(--t-estd) * 73.84);
    width: calc(var(--t-estd) * 100);
    padding-left: .29em;
    font-size: calc(var(--t-estd) * 15.85);
    line-height: calc(var(--t-estd) * 20);
    letter-spacing: .29em;
    text-align: center;
  }

  .side-rule {
    display: block;
    left: calc(var(--u) * 1967.5); top: calc(var(--u) * 342);
    width: calc(var(--u) * 1.5); height: calc(var(--u) * 197);
  }
  .vertical-text {
    display: block;
    left: calc(var(--u) * 1963); top: calc(var(--u) * 556);
    font-size: calc(var(--t-vert) * 12.2);
    line-height: 1;
    letter-spacing: .56em;
    word-spacing: calc(var(--t-vert) * -3);
    writing-mode: vertical-rl;
    transform: rotate(180deg);
  }

  /* bottom strip */
  .scroll-cue { display: block; left: calc(var(--u) * 60); top: calc(var(--u) * 1083.24 - var(--t-scr) * 45.24); }
  .tri-bar { width: calc(var(--t-scr) * 93); height: calc(var(--t-scr) * 6); }
  .scroll-label {
    position: absolute;
    left: calc(var(--t-scr) * -1); top: calc(var(--t-scr) * 31.64);
    font-size: calc(var(--t-scr) * 13.6);
    line-height: 1;
    letter-spacing: .178em;
  }
  .scroll-label::after {
    content: "";
    position: absolute;
    left: calc(var(--t-scr) * 170); top: calc(var(--t-scr) * 6.4);
    width: calc(var(--t-scr) * 28); height: calc(var(--t-scr) * 1.5);
    background: var(--body);
  }

}

/* ---------- Work section (screen 2) ---------- */

/* below 900: a plain stacked flow (T7 refines it) */
.work {
  position: relative;
  isolation: isolate;
  padding: 48px 16px 56px;
}
.work-bg {
  position: absolute;
  z-index: -1;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.work-title img { width: 100%; height: auto; }
.work-title .lettering-recent-projects { width: 92%; margin: 6px auto 0; }
.work-note { margin: 32px 0 0; padding-left: 20px; border-left: 2px solid var(--note-blue); }
.work-note-label {
  font-family: var(--font-caps);
  font-weight: 500;
  font-size: 15px;
  letter-spacing: .40em;
  word-spacing: .05em;
  color: var(--violet-text);
}
/* --font-body carries two weights: the tagline's 400 and this note's 500 (FONTS.md, Work section) */
.work-note-body {
  margin-top: 12px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  line-height: 1.52;
  letter-spacing: .13em;
  word-spacing: .11em;
  color: var(--body);
}
.work-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px 24px;
  margin-top: 32px;
}
@media (min-width: 600px) {
  .work-grid { grid-template-columns: 1fr 1fr; }
  /* the featured card takes the first row on its own, so three cards fill 1 + 2 */
  .work-grid > li:first-child { grid-column: 1 / -1; }
}

/* per-card geometry in mockup px (PALETTE.md "Geometry": frame outer box --fx/--fy/--fw/--fh, screenshot
   --sx/--sy/--sw/--sh; FONTS.md "Text geometry": caption and category baselines --cb/--kb, ink-left --tx).
   Three projects: card 1 is featured, its frame spanning the mockup's two card rows (y 402.7-982.5), and cards 2
   and 3 stack beside it with the mockup's row gap between them. Each slot has its thumbnail's own aspect (16:9 for
   card 1, 1208:639 for cards 2 and 3) inside card 1's measured frame insets; the block is centred on the mockup
   grid's centre line (x 1017). The desktop stage places each card by these; below 900 --sh scales the nav band. */
.work-grid > li:nth-child(1) { --fx: 282.4;  --fy: 402.7; --fw: 984.6; --fh: 579.8; --sx: 289.9;  --sy: 429.9; --sw: 968.4; --sh: 544.7; --cb: 1002.68; --kb: 1021.07; --tx: 297.7; }
.work-grid > li:nth-child(2) { --fx: 1308.2; --fy: 402.7; --fw: 443.4; --fh: 261.1; --sx: 1315.7; --sy: 429.9; --sw: 427.2; --sh: 226.0; --cb: 683.98;  --kb: 702.37;  --tx: 1323.5; }
.work-grid > li:nth-child(3) { --fx: 1308.2; --fy: 721.4; --fw: 443.4; --fh: 261.1; --sx: 1315.7; --sy: 748.6; --sw: 427.2; --sh: 226.0; --cb: 1002.68; --kb: 1021.07; --tx: 1323.5; }

.card { display: block; }
.card-frame {
  position: relative;
  display: block;
  padding: 27px 8px 8px;
  border: 1px solid var(--card-border);
  border-top-color: var(--card-border-top);
  border-radius: 10px;
  background: var(--paper);
}
/* the three window dots: one disc, the other two as its offset shadows */
.card-dots {
  position: absolute;
  left: 15px; top: 10px;
  width: 6.7px; height: 6.7px;
  border-radius: 50%;
  background: var(--dot-magenta);
  box-shadow: 14.8px 0 0 var(--dot-grey), 29.6px 0 0 var(--dot-cyan);
}
.card-shot {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 442 / 226;
}
.card-shot img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 0;
}
/* the translucent header band behind each site's nav, with its faint bottom edge (spec amendment, B4 gate).
   Per card: --band-h (mockup px from the screenshot top), --band (tone) and --band-edge, fitted by
   pipeline/work/T5w-scratch/bandfit.py so the band's mean colour matches the mockup's */
.card-shot::after {
  content: "";
  position: absolute;
  left: 0; top: 0; right: 0;
  height: calc(var(--band-h) / 226 * 100%);
  background: var(--band);
  border-bottom: 2px solid var(--band-edge, transparent);
}
/* below the band, a soft lift that fades out over --lift-h mockup px: the thumbnails' rows under the nav are
   darker than the mockup's, which flipped the band edge's step (T6; fitted by pipeline/work/T6w-scratch/bandfit2.py) */
.card-shot::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: calc(var(--band-h) / 226 * 100%);
  height: calc(var(--lift-h, 0) / 226 * 100%);
  background: linear-gradient(var(--lift, transparent), transparent);
}
.card-name,
.card-cat {
  display: block;
  font-family: var(--font-caps);
  font-weight: 500;
  line-height: 1;
}
.card-name {
  margin-top: 10px;
  padding-left: 6px;
  font-size: 15px;
  letter-spacing: .13em;
  word-spacing: .21em;
  color: var(--ink);
}
.card-cat {
  margin-top: 7px;
  padding-left: 6px;
  font-size: 11.35px;
  letter-spacing: .23em;
  word-spacing: .2em;
  color: var(--label);
}
.card:hover .card-frame {
  border-color: transparent;
  background:
    linear-gradient(var(--paper), var(--paper)) padding-box,
    var(--btn-gradient) border-box;
}
.card:focus-visible { border-radius: 10px; }

/* below 900 (spec D6): the side note keeps the desktop's gradient L-rule; every thumbnail shows at its own
   aspect, so no baked-in logo, nav or button is cropped; the nav band and lift scale with it (--band-h and
   --lift-h are mockup px of the card's --sh); cards in a row share a height so their captions line up */
@media (max-width: 899.98px) {
  .work-note { position: relative; padding-left: 44px; border-left: 0; }
  .work-note::before,
  .work-note::after { content: ""; position: absolute; left: 0; top: 6px; }
  .work-note::before {
    width: 32px; height: 2px;
    background: linear-gradient(90deg, var(--note-cyan) 68%, var(--note-violet) 88%);
  }
  .work-note::after {
    width: 2px; bottom: -12px;
    background: linear-gradient(180deg, var(--note-blue) 25%, var(--note-magenta) 78%);
  }
  .work-grid > li { display: flex; }
  .card { display: flex; flex: 1; flex-direction: column; }
  .card-frame { flex: 1; }
  .card-shot { aspect-ratio: auto; }
  .card-shot img { height: auto; object-fit: fill; }
  .card-shot::after { height: calc(var(--band-h) / var(--sh) * 100%); }
  .card-shot::before {
    top: calc(var(--band-h) / var(--sh) * 100%);
    height: calc(var(--lift-h, 0) / var(--sh) * 100%);
  }
}
/* ---------- hero motion (main.js "Hero motion") ----------
   Three overlays, placed in px by main.js over the stage: the band's canvas (intro, fringe, cursor wake), PENSACOLA's
   canvas (intro, glitch) and its light (scan and cursor light, masked to the lettering's own alpha). The stage is
   their containing block at every width. */
.stage { position: relative; }
.band-fx, .pensacola-glitch, .pensacola-light {
  position: absolute;
  left: 0; top: 0; width: 0; height: 0;
  margin: 0;
  pointer-events: none;
}
/* desktop: one layer over .band (z 0, earlier in the DOM), under the z-1 hero copy */
.band-fx { z-index: 0; }
.pensacola-glitch, .pensacola-light { z-index: 1; }
.pensacola-light {
  display: none;
  overflow: hidden;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  /* screen lifts the lettering's navy texture toward neon and cannot darken it; the mask isolates the light's own
     children, so the blend sits on this element against the lettering below */
  mix-blend-mode: screen;
}
.fx-live .pensacola-light { display: block; }
/* the scan: a skewed band of cyan, white and magenta light that crosses the lettering once per run */
.pensacola-light::before {
  content: "";
  position: absolute;
  top: -10%; bottom: -10%; left: 0;
  width: 34%;
  background: linear-gradient(100deg, transparent 8%, rgb(80 208 248 / .35) 34%, rgb(214 250 255 / .9) 50%,
    rgb(223 130 224 / .45) 64%, transparent 90%);
  transform: translateX(-120%) skewX(-14deg);
}
.pensacola-light.is-scanning::before { animation: fx-scan 1.6s cubic-bezier(.5, 0, .2, 1) both; }
@keyframes fx-scan {
  from { transform: translateX(-120%) skewX(-14deg); }
  to   { transform: translateX(320%) skewX(-14deg); }
}
/* the cursor light: --fx-x/--fx-y/--fx-r set by main.js */
.pensacola-light::after {
  content: "";
  position: absolute;
  left: 0; top: 0;
  width: var(--fx-r, 300px); height: var(--fx-r, 300px);
  margin: calc(var(--fx-r, 300px) / -2) 0 0 calc(var(--fx-r, 300px) / -2);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgb(200 248 255 / .95), rgb(80 208 248 / .5) 38%, rgb(146 70 185 / .2) 68%, transparent);
  transform: translate(var(--fx-x, -999px), var(--fx-y, -999px));
  opacity: 0;
  transition: opacity .4s ease;
}
.pensacola-light.is-lit::after { opacity: 1; }
/* while the canvas draws a glitch frame it carries the whole lettering */
.lettering-pensacola.is-glitching { visibility: hidden; }
/* before the intro the lettering is hidden; if main.js never takes over, it appears at 4 s on its own */
.fx-intro .lettering-pensacola { animation: fx-failsafe 0s 4s both; }
@keyframes fx-failsafe { from { opacity: 0; } to { opacity: 1; } }

/* two columns: the longest half-width caption (MR. KITCHEN ADVISER) stays on one line down to 600 */
@media (min-width: 600px) and (max-width: 899.98px) {
  .card-name { font-size: min(15px, 2.2vw); }
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
  .card { transition: transform .2s ease; }
  .card:hover { transform: translateY(-3px); }
}

/* desktop: the section is a second 2048x1152 stage in the same mockup px (spec D2, same --u) */
@media (min-width: 900px) {
  .work {
    --u: calc(calc(var(--cqw, 1cqw) * 100) / 2048);
    /* text units, as on screen 1: --t-* = --u here, floored below (captions / label 11px, note body 12px) */
    --t-cap: var(--u); --t-cat: var(--u); --t-lbl: var(--u); --t-note: var(--u);
    width: calc(var(--u) * 2048);
    height: calc(var(--u) * 1152);
    padding: 0;
  }
  /* the categories' 11 / 11.35 is the largest ratio, so no floor binds on a stage >= 2048 * 0.969163 = 1984.85 */
  @container (max-width: 1984.8px) {
    .work {
      --t-cap:  max(var(--u), 0.723684px);  /* 11 / 15.2  */
      --t-cat:  max(var(--u), 0.969163px);  /* 11 / 11.35 */
      --t-lbl:  max(var(--u), 0.714286px);  /* 11 / 15.4  */
      --t-note: max(var(--u), 0.774194px);  /* 12 / 15.5  */
    }
  }
  .work-title img { position: absolute; height: auto; margin: 0; }
  /* both letterings patch-aligned to the mockup (T5w-scratch/align.py; the assets carry 2.8% padding) */
  .work-title .lettering-our-work {
    left: calc(var(--u) * 621.89); top: calc(var(--u) * 190.97);
    width: calc(var(--u) * 811.62);
  }
  .work-title .lettering-recent-projects {
    left: calc(var(--u) * 613.05); top: calc(var(--u) * 314.85);
    width: calc(var(--u) * 863.64);
  }

  /* side note: bottom-anchored (body line 4 stays put), so floored text grows up into the empty top band;
     the L-rule's arm rides with the label and its vertical still ends at y 416 */
  .work-note {
    position: absolute;
    left: calc(var(--u) * 151.9);
    bottom: calc(var(--u) * (1152 - 334.1));
    margin: 0; padding: 0; border: 0;
  }
  .work-note::before,
  .work-note::after {
    content: "";
    position: absolute;
    left: calc(var(--u) * (72 - 151.9));
    top: calc(var(--t-lbl) * 4.83);
  }
  .work-note::before {
    width: calc(var(--u) * 58.8); height: max(1px, calc(var(--u) * 1.5));
    background: linear-gradient(90deg, var(--note-cyan) 68%, var(--note-violet) 88%);
  }
  .work-note::after {
    width: max(1px, calc(var(--u) * 1.5));
    bottom: calc(var(--u) * -81.9);
    background: linear-gradient(180deg, var(--note-blue) 25%, var(--note-magenta) 78%);
  }
  .work-note-label {
    font-size: calc(var(--t-lbl) * 15.4);
    line-height: 1;
    white-space: nowrap;
  }
  .work-note-body {
    margin-top: calc(var(--u) * 19.09);
    font-size: calc(var(--t-note) * 15.5);
    line-height: calc(var(--t-note) * 23.61);
    white-space: nowrap;
  }

  /* grid: each card at its own measured mockup rect (the per-card geometry tokens above).
     The thumbnails were cropped to each card's own region aspect, so the per-card slots match the assets. */
  .work-grid {
    position: absolute;
    inset: 0;
    display: block;
    margin: 0;
  }
  .work-grid > li {
    --base: 0.842;  /* Roboto Condensed baseline in a line-height 1 box, em */
    position: absolute;
    left: calc(var(--u) * var(--fx));
    top: calc(var(--u) * var(--fy));
    width: calc(var(--u) * var(--fw) - var(--cut, 0px) * var(--sw) / var(--sh));
  }
  /* card 3 drops by card 2's caption-block growth: the caption's floor growth (t-cap - u) times its 20.18 mockup px
     below the frame, plus the category's (t-cat - u) times the 37.24 from the caption baseline to card 3's frame
     (18.36 caption-to-category + 1.79 category descent + 17.06 clear), so the grown captions and card 2's focus
     ring keep clear of card 3. The two stacked cards each give up half of it (--cut) from their height, and their
     width with it at the thumbnail's aspect, so card 3's frame still ends level with card 1's. 0 wherever
     --t-cap == --t-cat == --u (stage >= 1984.85) */
  .work-grid > li:nth-child(n+2) {
    --cut: calc(((var(--t-cap) - var(--u)) * 20.18 + (var(--t-cat) - var(--u)) * 37.24) / 2);
  }
  .work-grid > li:nth-child(3) { top: calc(var(--u) * var(--fy) + var(--cut)); }
  .card-frame {
    height: calc(var(--u) * var(--fh) - var(--cut, 0px));
    padding: 0;
    border-radius: calc(var(--u) * 10);
  }
  .card-dots {
    left: calc(var(--u) * 15.65 - 1px); top: calc(var(--u) * 10.55 - 1px);
    width: calc(var(--u) * 6.7); height: calc(var(--u) * 6.7);
    box-shadow: calc(var(--u) * 14.8) 0 0 var(--dot-grey), calc(var(--u) * 29.6) 0 0 var(--dot-cyan);
  }
  .card-shot {
    position: absolute;
    left: calc(var(--u) * (var(--sx) - var(--fx)) - 1px); top: calc(var(--u) * (var(--sy) - var(--fy)) - 1px);
    width: calc(var(--u) * var(--sw) - var(--cut, 0px) * var(--sw) / var(--sh));
    height: calc(var(--u) * var(--sh) - var(--cut, 0px));
    aspect-ratio: auto;
  }
  .card-shot::after { height: calc(var(--u) * var(--band-h)); border-bottom-width: calc(var(--u) * 2); }
  .card-shot::before { top: calc(var(--u) * var(--band-h)); height: calc(var(--u) * var(--lift-h, 0)); }
  /* baselines stay at the mockup's; floored text grows upward from them */
  .card-name {
    /* the frame-to-caption baseline drop is in the caption's text unit, so a floored caption keeps its mockup
       clearance under the frame (T7) instead of growing up into it */
    margin-top: calc(var(--t-cap) * (var(--cb) - var(--fy) - var(--fh)) - var(--t-cap) * 15.2 * var(--base));
    padding-left: calc(var(--u) * (var(--tx) - var(--fx)));
    font-size: calc(var(--t-cap) * 15.2);
  }
  .card-cat {
    /* the caption-to-category baseline gap is in the category's text unit, so the pair keeps the mockup's
       gap-to-cap ratio as the category floors (T7); the caption baseline stays pinned */
    margin-top: calc(var(--t-cat) * (var(--kb) - var(--cb)) - var(--t-cat) * 11.35 * var(--base) - var(--t-cap) * 15.2 * (1 - var(--base)));
    padding-left: calc(var(--u) * (var(--tx) - var(--fx)));
    font-size: calc(var(--t-cat) * 11.35);
  }
  .card:focus-visible { border-radius: calc(var(--u) * 10); }
}

/* ---------- How It Works section (between Work and Pricing) ---------- */

/* below 900 (spec D6): heading, arch and coordinates centred, then one column of steps beside a dashed route down
   the left edge, each step's pin at its numeral (600-899: the steps alternate either side of a central route) */
.how {
  position: relative;
  isolation: isolate;
  padding: 48px 16px 56px;
}
.how-bg {
  position: absolute;
  z-index: -1;
  inset: 0;
  width: 100%; height: 100%;
}
/* the Work plate ends on #F1F0F1 and this one (the same plate) starts on #F5F5F5: ramp from it to clear, as Pricing
   does, so the screen 2 -> How seam has no paper step */
.how::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0; right: 0; top: 0;
  height: 48px;
  background: linear-gradient(#F1F0F1, rgb(241 240 241 / 0));
  pointer-events: none;
}
/* work-topo (spec D3) carries the Work plate's blurred field residue at its sides (alpha-free, under Work's sharp field
   images: x 0-14.1% / 85.1-100%, y 41-86%); the plate is flat paper (#F5F5F5, = --paper) everywhere else, so the
   residue is masked out and the page paper shows through */
.how-bg .work-topo {
  -webkit-mask: linear-gradient(90deg, transparent 16%, #000 18% 82%, transparent 84%),
    linear-gradient(#000 37%, transparent 39% 88%, #000 90%);
  mask: linear-gradient(90deg, transparent 16%, #000 18% 82%, transparent 84%),
    linear-gradient(#000 37%, transparent 39% 88%, #000 90%);
}
/* the shared gradients and the pin symbol: a 0x0 box, never display: none (its gradients would stop painting) */
.how-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.how-side, .how-vlabel, .how-route { display: none; }
.how-title img { width: 100%; height: auto; }
.how-title .lettering-first-hello { margin-top: 10px; }
.how .how-arch { width: 72px; height: 36px; margin: 24px auto 0; }
.how-arch g { stroke-width: 2.6; }
/* the mockup draws the whole arch in screen 1's blue, the inner arcs included */
.how-arch path { stroke: #8DB3E6; }
.how .how-coords { font-family: var(--font-label); font-weight: 400; white-space: nowrap; color: var(--how-coords); margin-top: 4px; font-size: 12px; letter-spacing: .14em; text-align: center; }

.how-steps { margin: 40px 0 0; padding: 0; list-style: none; }
.how-step {
  --pin-y: 26px;  /* the pin's point on the route, from the step's top: level with the numeral's middle */
  position: relative;
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  column-gap: 14px;
}
.how-num { width: auto; height: 52px; overflow: visible; }
.how-num text {
  font-family: var(--font-caps);
  font-weight: 400;
  font-size: 100px;
  fill: none;
  stroke: url(#how-num-grad);
  stroke-width: 1.6px;
  vector-effect: non-scaling-stroke;
}
.how-icon { width: auto; height: 50px; }
.how-step-title {
  grid-column: 1 / -1;
  margin: 14px 0 0;
  font-family: var(--font-caps);
  font-weight: 600;
  font-size: 18px;
  line-height: 1.25;
  letter-spacing: .02em;
  color: var(--how-title);
}
.how-step-body {
  grid-column: 1 / -1;
  margin-top: 6px;
  font-family: var(--font-caps);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: .035em;
  color: var(--ink-blue);
}
.how-br { display: none; }

/* the route: one dashed segment per step, from its pin down to the next step's pin (the dashes are a mask over the
   segment's gradient, so they keep their pitch whatever the length); the pins sit on it */
.how-pin {
  position: absolute;
  top: calc(var(--pin-y) - 30px);
  width: 26px; height: 37px;
  overflow: visible;
}
.how-pin-shadow { fill: rgb(106 92 221 / .08); }
.how-step:not(:last-child)::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: var(--pin-y);
  width: 2.5px;
  height: calc(100% + var(--step-gap));
  background: var(--how-route-violet);
  -webkit-mask: repeating-linear-gradient(#000 0 9px, transparent 9px 15px);
  mask: repeating-linear-gradient(#000 0 9px, transparent 9px 15px);
}
.how-steps .how-step-1::before { background: linear-gradient(var(--side-cyan) 40%, var(--how-route-violet)); }

@media (max-width: 599.98px) {
  .how-steps { --step-gap: 40px; padding-left: 44px; }
  .how-step + .how-step { margin-top: var(--step-gap); }
  .how-pin { left: -44px; }
  .how-step::before { left: -32.25px; }
}

/* 600-899: two columns either side of a central route; each step rises into the one before it by --lap, so
   the columns stagger as on the stage (every step is taller than 2 x --lap, so a column never collides) */
@media (min-width: 600px) and (max-width: 899.98px) {
  .how-title { width: 86%; margin: 0 auto; }
  .how-steps { --lap: 56px; --step-gap: calc(-1 * var(--lap)); --half: 32px; margin-top: 48px; }
  .how-step { width: calc(50% - var(--half)); }
  .how-step + .how-step { margin-top: calc(-1 * var(--lap)); }
  .how-step:nth-child(even) { margin-left: auto; }
  .how-step:nth-child(odd) .how-pin { left: calc(100% + var(--half) - 13px); }
  .how-step:nth-child(even) .how-pin { right: calc(100% + var(--half) - 13px); }
  .how-step:nth-child(odd)::before { left: calc(100% + var(--half) - 1.25px); }
  .how-step:nth-child(even)::before { right: calc(100% + var(--half) - 1.25px); }
}

/* the scroll reveal (spec D7; main.js adds .how-anim only with JS, motion allowed and no webdriver): each step fades
   up as it enters; once step 04 is in view the stage route draws itself under its mask and each pin pops in, from its
   tip, as the line reaches it. Below 900 a step's own pin pops in just after the step */
@keyframes how-pin-pop {
  0%   { opacity: 0; transform: translateY(-8px) scale(.3); }
  55%  { opacity: 1; transform: translateY(0) scale(1.18); }
  78%  { transform: scale(.94); }
  100% { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: no-preference) {
  .how-anim .how-step { opacity: 0; transition: opacity .6s ease; }
  .how-anim .how-step > * { transform: translateY(14px); transition: transform .6s ease; }
  .how-anim .how-step.is-revealed { opacity: 1; }
  .how-anim .how-step.is-revealed > * { transform: none; }
  .how-anim .how-route-pin { opacity: 0; transform-box: view-box; transform-origin: 19px 54px; } /* the tip, in the pin's own translated space */
  .how-anim .how-route-pin.is-revealed { animation: how-pin-pop .5s cubic-bezier(.34, 1.4, .64, 1) both; }
  .how-anim .how-step .how-pin { transform-origin: 50% 100%; }
  .how-anim .how-step.is-revealed .how-pin { animation: how-pin-pop .5s .3s cubic-bezier(.34, 1.4, .64, 1) both; }
}

/* desktop: a 2048x1152 stage in the same mockup px (spec D5, same --u), every piece placed against the section.
   min-height, so it can only grow; the floored body text grows down from its first baseline */
@media (min-width: 900px) {
  .how {
    --u: calc(calc(var(--cqw, 1cqw) * 100) / 2048);
    /* text units: --t-* = --u here, floored below (body 12px, the coordinates and vertical labels 11px) */
    --t-body: var(--u); --t-crd: var(--u); --t-vlab: var(--u);
    width: calc(var(--u) * 2048);
    min-height: calc(var(--u) * 1152);
    padding: 0;
  }
  /* the vertical labels' 11 / 13.3 is the largest ratio, so no floor binds on a stage >= 2048 * 0.827068 = 1693.9 */
  @container (max-width: 1693.9px) {
    .how {
      --t-body: max(var(--u), 0.502092px);  /* 12 / 23.9 */
      --t-crd:  max(var(--u), 0.696203px);  /* 11 / 15.8 */
      --t-vlab: max(var(--u), 0.827068px);  /* 11 / 13.3 */
    }
  }
  .how > *, .how-title img, .how-step > * { position: absolute; margin: 0; }
  .how > .how-bg { z-index: -1; }
  .how::after { height: calc(var(--u) * 96); }
  .how-title, .how-steps, .how-step { position: static; }
  .how-steps { margin: 0; }
  .how-step::before, .how-pin { display: none; }

  /* both letterings by their alpha > 64 ink boxes (8 / 48 px margins in the files) on the mockup ink */
  .how-title .lettering-how-it-works {
    left: calc(var(--u) * 412.98); top: calc(var(--u) * 72.98);
    width: calc(var(--u) * 1205.04);
  }
  .how-title .lettering-first-hello {
    margin: 0;
    left: calc(var(--u) * 393.88); top: calc(var(--u) * 183.88);
    width: calc(var(--u) * 1257.27);
  }
  /* screen 1's arch at 0.42 (ink 999-1046 x 252-281); its strokes at the mockup's ~1.1 px */
  .how .how-arch {
    left: calc(var(--u) * 984.7); top: calc(var(--u) * 249.1);
    width: calc(var(--u) * 75.6); height: calc(var(--u) * 37.8);
    margin: 0;
  }
  .how .how-coords {
    margin: 0;
    left: calc(var(--u) * 1023); top: calc(var(--u) * 291);
    font-size: calc(var(--t-crd) * 15.8);
    line-height: 1;
    letter-spacing: 0.094em;
    transform: translateX(-50%);
  }

  /* the side frame: crosshairs, rules and ticks in mockup px (non-scaling strokes, at least 1 px). Where the
     vertical labels floor they grow about their centres, and the rule is masked away under them (--vg each side) */
  .how-side { display: block; overflow: visible; }
  .how-side-left  { left: calc(var(--u) * 40);   top: calc(var(--u) * 30); width: calc(var(--u) * 40); height: calc(var(--u) * 1090); }
  .how-side-right { left: calc(var(--u) * 1960); top: calc(var(--u) * 30); width: calc(var(--u) * 50); height: calc(var(--u) * 1090); }
  .how-side path { fill: none; vector-effect: non-scaling-stroke; stroke-width: max(1px, calc(var(--u) * 1.5)); }
  .how-side .how-cross { stroke-width: max(1px, calc(var(--u) * 2)); }
  .how-side-left .how-cross  { stroke: var(--how-cross-cyan); }
  .how-side-right .how-cross { stroke: var(--grad-magenta); }
  .how-side-left .how-rule   { stroke: var(--how-rule-cyan); }
  .how-side-right .how-rule  { stroke: url(#how-side-grad); }
  .how {
    --vg: calc((var(--t-vlab) - var(--u)) * 60);
    /* label centres, as offsets from the side frame's top (mockup y 30) */
    --vc1: calc(var(--u) * (348.5 - 30)); --vc2: calc(var(--u) * (800 - 30));
    --vh: calc(var(--u) * 77 + var(--vg));  /* half the cleared run: the rule's gap (the narrowest of the four), plus the growth */
  }
  .how-side {
    -webkit-mask: linear-gradient(#000 calc(var(--vc1) - var(--vh)), transparent 0 calc(var(--vc1) + var(--vh)),
      #000 0 calc(var(--vc2) - var(--vh)), transparent 0 calc(var(--vc2) + var(--vh)), #000 0);
    mask: linear-gradient(#000 calc(var(--vc1) - var(--vh)), transparent 0 calc(var(--vc1) + var(--vh)),
      #000 0 calc(var(--vc2) - var(--vh)), transparent 0 calc(var(--vc2) + var(--vh)), #000 0);
  }
  /* D11: the generator's coordinates, kept as decoration; read bottom to top, centred on the mockup ink */
  .how-vlabel {
    display: block;
    font-family: var(--font-label);
    font-weight: 700;
    font-size: calc(var(--t-vlab) * 13.3);
    line-height: 1;
    letter-spacing: 0.45em;
    color: var(--how-vlabel);
    white-space: nowrap;
    writing-mode: vertical-rl;
    /* centred on the ink, not the box: the trailing tracking sits at the top once rotated (.26em, measured) */
    transform: translate(-50%, calc(-50% - .26em)) rotate(180deg);
  }
  .how-vlabel-1 { left: calc(var(--u) * 60);   top: calc(var(--u) * 348); }
  .how-vlabel-2 { left: calc(var(--u) * 60);   top: calc(var(--u) * 799.5); }
  .how-vlabel-3 { left: calc(var(--u) * 1987); top: calc(var(--u) * 351); }
  .how-vlabel-4 { left: calc(var(--u) * 1987); top: calc(var(--u) * 800.5); }

  /* the route and its five pins: one SVG over mockup x 880-1180, y 330-1060 */
  .how-route {
    display: block;
    left: calc(var(--u) * 880); top: calc(var(--u) * 330);
    width: calc(var(--u) * 300); height: calc(var(--u) * 730);
    overflow: visible;
  }
  .how-route-path {
    fill: none;
    stroke: url(#how-route-grad);
    stroke-width: 3;
    stroke-dasharray: 10 5.5;
  }

  /* steps: numeral box (--nx --ny --nw --nh: the ink box inset 0.2, so the 2.4 stroke's AA edge lands on the
     mockup's), icon box (--ix --iy --iw), title ink-left and baseline (--tx --tb), body ink-left and first baseline
     (--bx --bb), all mockup px; title and body tracking per step (--tls --bls, em): the mockup sets each block at its
     own width, fitted line by line at 2048 */
  .how-step-1 { --nx: 248.2; --ny: 338.2; --nw: 98.6; --nh: 90.6; --ix: 394.79; --iy: 334.59; --iw: 90.41; --tx: 516; --tb: 363; --bx: 519; --bb: 400; --tls: -0.0065; --bls: 0.0245; }
  .how-step-2 { --nx: 1177.2; --ny: 436.2; --nw: 104.6; --nh: 80.6; --ix: 1303.81; --iy: 427.39; --iw: 113.38; --tx: 1449; --tb: 470; --bx: 1450; --bb: 506; --tls: -0.0140; --bls: 0.0103; }
  .how-step-3 { --nx: 234.2; --ny: 599.2; --nw: 115.6; --nh: 89.6; --ix: 376.23; --iy: 598.39; --iw: 112.54; --tx: 520; --tb: 627; --bx: 520; --bb: 662; --tls: -0.0090; --bls: 0.0079; }
  .how-step-4 { --nx: 1178.2; --ny: 716.2; --nw: 104.6; --nh: 84.6; --ix: 1308.82; --iy: 716.81; --iw: 115.07; --tx: 1461; --tb: 745; --bx: 1463; --bb: 780; --tls: -0.0102; --bls: -0.0226; }
  .how-step-5 { --nx: 238.2; --ny: 881.2; --nw: 115.6; --nh: 87.6; --ix: 382.49; --iy: 867.36; --iw: 113.31; --tx: 526; --tb: 906; --bx: 526; --bb: 942; --tls: -0.0188; --bls: -0.0130; }
  .how-num {
    left: calc(var(--u) * var(--nx)); top: calc(var(--u) * var(--ny));
    width: calc(var(--u) * var(--nw)); height: calc(var(--u) * var(--nh));
  }
  .how-num text { stroke-width: max(1px, calc(var(--u) * 2.4)); }
  .how-icon {
    left: calc(var(--u) * var(--ix)); top: calc(var(--u) * var(--iy));
    width: calc(var(--u) * var(--iw)); height: auto;
  }
  .how-step-title {
    --base: 0.842;  /* Roboto Condensed baseline in a line-height 1 box, em */
    left: calc(var(--u) * var(--tx) - 0.05em);
    top: calc(var(--u) * var(--tb) - var(--u) * 29.5 * var(--base));
    font-size: calc(var(--u) * 29.5);
    line-height: 1;
    letter-spacing: calc(var(--tls) * 1em);
    white-space: nowrap;
  }
  .how-step-body {
    left: calc(var(--u) * var(--bx) - 0.08em);
    top: calc(var(--u) * var(--bb) - var(--t-body) * (29.3 / 2 + 23.9 * .3418));
    font-size: calc(var(--t-body) * 23.9);
    line-height: calc(var(--t-body) * 29.3);
    /* where the 12px floor binds, every gap gives back (--t-body - --u) px, so step 3's first line stays clear of
       pin 3 down to 900 (0.7 px into its box without it) */
    letter-spacing: calc(var(--bls) * 1em - (var(--t-body) - var(--u)));
    white-space: nowrap;
  }
  /* the two lines a step's tracking cannot hold within 3% carry their own correction (--lfit, em) */
  .how-fit { letter-spacing: calc((var(--bls) + var(--lfit)) * 1em - (var(--t-body) - var(--u))); }
  .how-br { display: inline; }
}

/* ---------- Pricing section (screen 3) ---------- */

/* below 900: one stacked flow in reading order - heading, prices, features, splat (P7 refines it) */
.pricing {
  position: relative;
  isolation: isolate;
  padding: 48px 16px 56px;
}
.pricing-bg {
  position: absolute;
  z-index: -1;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* the Work plate ends on #F1F0F1, 1.1 dE darker than this plate's --paper: ramp from it to clear so the
   screen 2 -> 3 seam has no paper step (row scan, P5) */
.pricing::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0; right: 0; top: 0;
  height: 48px;
  background: linear-gradient(#F1F0F1, rgb(241 240 241 / 0));
  pointer-events: none;
}
.pricing-rule, .pricing-vertical { display: none; }
.pricing-title img { width: 100%; height: auto; }
.pricing-title .lettering-design-package { width: 74%; margin-top: 10px; }
.prices {
  display: flex;
  align-items: flex-start;
  margin: 28px 0 0;
}
.price { flex: none; }
.price dt img { width: auto; height: 46px; }
.price dd {
  margin: 8px 0 0;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 14px;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink-blue);
}
.price-setup dd { letter-spacing: .596em; word-spacing: -.064em; }
.price-monthly dd { letter-spacing: .332em; word-spacing: -.013em; }
.price-monthly {
  position: relative;
  margin-left: 20px;
  padding-left: 20px;
}
/* the divider (PALETTE.md stops), 1.5 mockup px wide on the stage */
.price-monthly::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 1.5px;
  background: linear-gradient(180deg,
    var(--price-cyan) 16%, var(--price-blue) 36% 70%, var(--price-violet) 94%);
}
.features { display: grid; gap: 18px; margin-top: 32px; }
.features li {
  display: flex;
  align-items: center;
  gap: 16px;
  font-family: var(--font-feature);
  font-weight: 400;
  font-size: 18px;
  line-height: 1.22;
  letter-spacing: .066em;
  word-spacing: .03em;
  color: var(--ink-blue);
}
.features img { flex: none; width: 40px; height: auto; }
.splat { display: block; margin-top: 32px; }
.splat img { width: 100%; height: auto; }

/* below 900 (spec D7, P7): one tracking for the class (FONTS.md's 0.066em, set above; the per-line fits are a
   desktop fit), and the desktop's 0.2 px stem stroke at its own proportion of the size (0.2 / 30.6 em), so it
   stays as light at 18px as on the stage */
@media (max-width: 899.98px) {
  .features li { -webkit-text-stroke: calc(.2em / 30.6) currentColor; }
  /* the two-line row keeps the mockup's relation: its icon is centred on the FIRST line (half the 1.22
     line-height), not on the whole item. 0.9433 = icon-pages.png's h/w */
  .features li { --m-iw: 40px; }
  .features .feature-pages { align-items: flex-start; }
  .feature-pages img { margin-top: calc(.61em - var(--m-iw) * .9433 / 2); }
}
/* 600-899: the heading spans the content width, so the prices and features grow with it; the splat is
   centred below at 90% */
@media (min-width: 600px) and (max-width: 899.98px) {
  .prices { margin-top: 36px; }
  .price dt img { height: clamp(52px, 7.3vw, 64px); }
  .price dd { font-size: 16px; }
  .price-monthly { margin-left: 28px; padding-left: 28px; }
  .features { gap: 22px; margin-top: 40px; }
  .features li { gap: 20px; font-size: clamp(19px, 2.6vw, 22px); }
  .features li { --m-iw: 2.4em; }
  .features img { width: var(--m-iw); }
  .splat { width: 90%; margin: 40px auto 0; }
}
/* the prices side by side need 338 px of content (both at 46px tall, measured); narrower, they stack and the
   divider is dropped */
@media (max-width: 369.98px) {
  .prices { flex-direction: column; gap: 16px; }
  .price-monthly { margin-left: 0; padding-left: 0; }
  .price-monthly::before { content: none; }
}

@media (prefers-reduced-motion: no-preference) {
  .splat img { transition: transform .3s ease, filter .3s ease; }
  .splat:hover img,
  .splat:focus-visible img { transform: scale(1.015); filter: brightness(1.06); }
}

/* desktop: the third 2048x1152 stage, every coordinate in mockup px (spec D2, same --u). The empty header
   band (y 0-150) is kept. Positions: docs/pws/FONTS.md + PALETTE.md "Pricing section", and the patch-aligned
   asset boxes from pipeline/work/P5-scratch/align.py */
@media (min-width: 900px) {
  .pricing {
    --u: calc(calc(var(--cqw, 1cqw) * 100) / 2048);
    /* text unit for the vertical text only: the feature lines and labels floor below the 900 breakpoint
       (FONTS.md), so they stay on --u here */
    --t-vtx: var(--u);
    width: calc(var(--u) * 2048);
    height: calc(var(--u) * 1152);
    padding: 0;
  }
  /* the vertical text's 11 / 13.98 floor binds on a stage < 2048 * 0.786838 = 1611.4 */
  @container (max-width: 1611.4px) {
    .pricing { --t-vtx: max(var(--u), 0.786838px); }
  }
  .pricing > *, .pricing-title img, .price dt, .price dd, .features img, .features span { position: absolute; }
  .pricing > .pricing-bg { z-index: -1; }
  .pricing::after { height: calc(var(--u) * 96); }
  .pricing-title, .prices, .price, .features, .features li { position: static; }
  .pricing-title img, .price dt img { height: auto; margin: 0; }
  .prices, .features { margin: 0; }

  /* both letterings patch-aligned to the mockup (the assets carry 8 / 11 px padding) */
  .pricing-title .lettering-small-business {
    left: calc(var(--u) * 257.02); top: calc(var(--u) * 170.53);
    width: calc(var(--u) * 1212);
  }
  .pricing-title .lettering-design-package {
    left: calc(var(--u) * 259.88); top: calc(var(--u) * 311.12);
    width: calc(var(--u) * 868);
    margin: 0;
  }

  /* prices sized by digit height (the 0s: 145.49 of 197 file px and 135.01 of 171, mockup 49.34 / 49.41),
     placed by the digits' top edge (mockup 406.34 / 406.19) and a least-squares fit of the glyph centres.
     $1,200 is 1.9% over its digit height (digits +1.0 px, centred on the mockup's): the asset's glyph spacing
     is wider than the mockup's, and this scale minimises the worst glyph-centre error (3.8 -> 1.3 px, P6) */
  .price dt { margin: 0; }
  .price-setup dt   { left: calc(var(--u) * 261.82); top: calc(var(--u) * 397.14); width: calc(var(--u) * 248.52); }
  .price-monthly dt { left: calc(var(--u) * 667.67); top: calc(var(--u) * 399.59); width: calc(var(--u) * 175.30); }
  .price dt img { width: 100%; }
  /* labels: baseline 498.27, ink-left 264.8 / 660.5 (FONTS.md); the box sits a side-bearing left of the ink */
  .price dd {
    --lb: 0.866;  /* Barlow Semi Condensed baseline in a line-height 1 box, em (measured) */
    margin: 0;
    top: calc(var(--u) * 498.27 - var(--u) * 27.7 * var(--lb));
    font-size: calc(var(--u) * 27.7);
  }
  .price-setup dd   { left: calc(var(--u) * 264.1); }
  .price-monthly dd { left: calc(var(--u) * 659.0); }
  .price-monthly { margin: 0; padding: 0; }
  .price-monthly::before {
    left: calc(var(--u) * 587.62); top: calc(var(--u) * 404.8); bottom: auto;
    width: max(1px, calc(var(--u) * 1.5)); height: calc(var(--u) * 94.2);
  }

  /* features: each icon at its patch-aligned box (--ix, --iy, --iw), each line's baseline at FONTS.md's (--bl);
     ink-left 386.6 for every row (box 385.0: the live side bearing measured 0.4 px short of it, P6) */
  .feature-pages    { --ix: 262.02; --iy: 553.40; --iw: 73; --bl: 588.07; --ls: .0751; }
  .feature-rocket   { --ix: 263.95; --iy: 651.11; --iw: 63; --bl: 694.60; --ls: .0689; }
  .feature-support  { --ix: 266.95; --iy: 728.55; --iw: 55; --bl: 774.41; --ls: .0591; }
  .feature-hosting  { --ix: 264.06; --iy: 809.64; --iw: 68; --bl: 857.17; --ls: .0605; }
  .feature-calendar { --ix: 266.22; --iy: 889.92; --iw: 57; --bl: 935.31; --ls: .0582; --dx: -1.15; }  /* its T overhangs 1.1 px more in the mockup */
  .feature-shield   { --ix: 262.12; --iy: 968.02; --iw: 57; --bl: 1014.32; --ls: .0602; }
  /* the size sits on the li, not the span, so the li's em tracking resolves at 30.6 (it inherits as a length) */
  .features li {
    --fb: 1.013;  /* Barlow Condensed baseline in a 37.23 / 30.6 line box, em (measured) */
    display: block;
    font-size: calc(var(--u) * 30.6);
    line-height: calc(var(--u) * 37.23);
    /* per-line tracking (--ls, em): the mockup's tracking drifts line to line, so one size with each line's
       ink width fitted to the mockup's within 1 px at 2048 (P6) */
    letter-spacing: calc(var(--ls) * 1em);
    /* Barlow Condensed 400 measured 10% light in stem against the mockup (integrated stem 2.58 vs 2.88 px, Chrome and
       Firefox alike) and 500 is 17% heavy, so the stem is thickened by a 0.2 px same-colour stroke instead (P6) */
    -webkit-text-stroke: calc(var(--u) * 0.2) currentColor;
  }
  .feature-pages span::first-line { letter-spacing: .0735em; }  /* item 1 line 1; --ls is its line 2 */
  .features { display: block; }
  .features img {
    left: calc(var(--u) * var(--ix)); top: calc(var(--u) * var(--iy));
    width: calc(var(--u) * var(--iw));
  }
  .features span {
    left: calc(var(--u) * (385.0 + var(--dx, 0)));
    top: calc(var(--u) * var(--bl) - var(--u) * 30.6 * var(--fb));
    white-space: nowrap;
  }

  /* the splat is registered by its white text block (NEED ... for you!) to the mockup's, not by its outline:
     image box 927.42, 315.87, 1145.55 wide. The link (and its focus ring) is the ink box, the file's alpha > 64
     bbox 109,98-2291,1598; the image's transparent margin past x 2048 is clipped by the section */
  .pricing { overflow-x: clip; }
  .splat {
    margin: 0;
    left: calc(var(--u) * 979.45); top: calc(var(--u) * 362.65);
    width: calc(var(--u) * 1041.49); height: calc(var(--u) * 715.97);
  }
  .splat img {
    position: absolute;
    left: calc(var(--u) * -52.03); top: calc(var(--u) * -46.78);
    width: calc(var(--u) * 1145.55); max-width: none;
  }

  /* left rule segments and the right-edge rule, 1.5 mockup px (PALETTE.md geometry and stops). When the
     vertical text floors it grows about its centre, and the segments' inner ends give way by the same amount
     (--vg, half the growth of its 506.06 mockup px ink run) so it keeps its clearance */
  .pricing-rule { display: block; width: max(1px, calc(var(--u) * 1.5)); }
  .pricing { --vg: calc((var(--t-vtx) - var(--u)) * 253.03); }
  .pricing-rule-upper {
    left: calc(var(--u) * 79.24); top: calc(var(--u) * 154.1);
    height: calc(var(--u) * 118.5 - var(--vg));
    background: linear-gradient(180deg, var(--side-cyan) 58%, var(--side-lavender) 91%);
  }
  .pricing-rule-lower {
    left: calc(var(--u) * 79.01); top: calc(var(--u) * 826.4 + var(--vg));
    height: calc(var(--u) * 232.7 - var(--vg));
    background: linear-gradient(180deg, var(--side-periwinkle), var(--side-blue) 15% 87%, var(--side-blue-end));
  }
  .pricing-rule-edge {
    left: calc(var(--u) * 1966.3); top: calc(var(--u) * 155.9);
    height: calc(var(--u) * 329.2);
    background: linear-gradient(180deg, var(--grad-violet) 41%, var(--edge-violet) 52% 85%, rgb(166 120 204 / .78));
  }

  /* screen 1's vertical text supplies only the colour, rotation and bottom-to-top reading; face, size and
     tracking are FONTS.md's. Centred on the ink run's mockup centre (y 552.69; the ink sits 3.4 text px below the box's
     centre, measured) and the cap/baseline edges x 75.83-85.75 */
  .pricing-vertical {
    display: block;
    left: calc(var(--u) * 73.8); top: calc(var(--u) * 552.69 - var(--t-vtx) * 3.4);
    font-family: var(--font-caps);
    font-weight: 500;
    font-size: calc(var(--t-vtx) * 13.98);
    line-height: 1;
    letter-spacing: .372em;
    word-spacing: .069em;
    color: var(--ink);
    white-space: nowrap;
    writing-mode: vertical-rl;
    transform: translateY(-50%) rotate(180deg);
  }
  /* 900-1199 (P7, spec D7 open item): the floored vertical text has eaten the upper left segment (0 px at
     1098, under 18 px below 1200), so both left segments go; and the text's tracking tightens so its ink run
     (20.57em untracked, 42 gaps; 506.06 mockup px at .372em) stays within 780 mockup px about its centre,
     i.e. below y 162.7 and clear of the empty header band. It binds below about 1045 px */
  @container (max-width: 1199.98px) {
    .pricing-rule-upper, .pricing-rule-lower { display: none; }
    .pricing-vertical { letter-spacing: min(.372em, calc((var(--u) * 780 - 20.57em) / 42)); }
  }
}

/* ---------- FAQ section (screen 4) ---------- */

/* below 900: a plain stacked flow (F6 refines it) */
.faq {
  position: relative;
  isolation: isolate;
  padding: 48px 16px 56px;
}
.faq-bg {
  position: absolute;
  z-index: -1;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.faq-title img { width: 100%; max-width: 454px; height: auto; margin: 0 auto; }
.faq-heading {
  display: block;
  margin-top: 16px;
  font-family: var(--font-caps);
  font-weight: 500;
  font-size: 15px;
  line-height: 1.4;
  letter-spacing: .3em;
  text-align: center;
  color: var(--ink-blue);
}
/* the rule's stops follow its core trace (PALETTE.md note 5), second blue band kept */
.faq-rule {
  display: block;
  width: 110px; height: 2px;
  margin: 18px auto 0;
  background: linear-gradient(90deg, var(--side-cyan) 0%, var(--faq-rule-blue) 16%, var(--faq-rule-blue) 20%,
    var(--faq-rule-violet) 42%, var(--faq-rule-violet) 60%, var(--faq-rule-blue) 72%, var(--faq-rule-blue) 81%,
    var(--faq-rule-magenta) 92%, var(--faq-rule-magenta) 100%);
}
.faq-sub,
.faq-a {
  font-family: var(--font-sub);
  font-weight: 400;
  color: var(--ink-blue);
}
.faq-sub {
  margin-top: 16px;
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: .124em;
  word-spacing: .112em;
  text-align: center;
}
.faq-list { margin-top: 28px; }
/* each frame is a masked ring over the item (spec D3): closed a flat --faq-border, open the 2D gradient field
   (PALETTE.md note 4) - a paler bottom edge, a magenta bottom-right corner, cyan to lavender across */
.faq-item {
  --ring-w: 1px;
  --ring-bg: var(--faq-border);
  position: relative;
}
.faq-item[open] {
  --ring-w: 2px;
  --ring-bg:
    linear-gradient(to top, rgb(245 244 244 / .35) 0 var(--ring-w), transparent var(--ring-w)),
    radial-gradient(30% 70% at 100% 100%, var(--faq-magenta), transparent 70%),
    linear-gradient(90deg, var(--faq-cyan) 0%, #80C0E4 28%, var(--faq-lavender) 62%, var(--faq-lavender) 100%);
}
.faq-item + .faq-item { margin-top: 10px; }
.faq-item::before {
  content: "";
  position: absolute;
  inset: 0;
  padding: var(--ring-w);
  border-radius: var(--ring-r, 2px);
  background: var(--ring-bg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}
.faq-item summary {
  position: relative;
  display: block;
  padding: 16px 48px 16px 16px;
  list-style: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 14px;
  line-height: 1.3;
  letter-spacing: .2em;
  color: var(--ink-blue);
}
.faq-item summary::-webkit-details-marker { display: none; }
/* the + / - : two bars; the vertical one collapses when the item opens */
.faq-mark {
  --ms: 2px;
  position: absolute;
  right: 16px; top: 18px;
  width: 16px; height: 16px;
  color: var(--ink-blue);
}
.faq-mark::before,
.faq-mark::after {
  content: "";
  position: absolute;
  background: currentColor;
}
.faq-mark::before { left: 0; right: 0; top: calc(50% - var(--ms) / 2); height: var(--ms); }
.faq-mark::after  { top: 0; bottom: 0; left: calc(50% - var(--ms) / 2); width: var(--ms); }
.faq-item[open] .faq-mark { color: var(--faq-minus); }
.faq-item[open] .faq-mark::after { transform: scaleY(0); }
.faq-a {
  padding: 0 16px 18px;
  font-size: 18.4px;
  line-height: 1.5;
  letter-spacing: .06em;
}
/* an inline link in an answer, styled as the legal pages' links */
.faq-a a {
  color: var(--magenta-text);
  text-decoration: underline;
  text-underline-offset: .18em;
  text-decoration-thickness: 1px;
}
.faq-a a:hover { text-decoration-thickness: 2px; }

@media (prefers-reduced-motion: no-preference) {
  .faq-mark { transition: color .2s ease; }
  .faq-mark::after { transition: transform .2s ease; }
}

/* desktop: the fourth 2048x1152 stage in the same mockup px (spec D5, same --u). The stage height is a minimum
   (spec D4): the list is in flow from its mockup top (y 554.8), so an open answer pushes the items below it, and
   then the section, down. Positions: docs/pws/FONTS.md + PALETTE.md "FAQ section" (the block's axis is x 1036.4) */
@media (min-width: 900px) {
  .faq {
    --u: calc(calc(var(--cqw, 1cqw) * 100) / 2048);
    /* text units: the questions floor at 11px (caps), the answer and subtitle at 12px (body; FONTS.md) - the
       answer's 15% enlargement rides on its unit, so a floored answer reads 13.8px */
    --t-q: var(--u); --t-a: var(--u); --t-sub: var(--u);
    --fq: calc(var(--t-q) * 18.24);   /* question size */
    --fa: calc(var(--t-a) * 19.62);   /* answer size: the mockup's 17.06, enlarged 15% */
    --la: calc(var(--t-a) * 29.42);   /* answer line pitch: 25.58, enlarged 15% */
    --qb: 0.900;  /* Barlow Semi Condensed baseline in a line-height 1 box, em (measured) */
    --ab: 0.842;  /* Abel baseline in a line-height 1 box, em (measured) */
    width: calc(var(--u) * 2048);
    min-height: calc(var(--u) * 1152);
    /* the bottom padding is the mockup's clear under its last item, item 6 (1027.31 on the 62.4 pitch) */
    padding: calc(var(--u) * 554.8) 0 calc(var(--u) * (1152 - 1027.31));
  }
  /* the subtitle's 12 / 16.98 is the largest ratio, so no floor binds on a stage >= 2048 * 0.706714 = 1447.35 */
  @container (max-width: 1447.4px) {
    .faq {
      --t-q:   max(var(--u), 0.603070px);  /* 11 / 18.24 */
      --t-a:   max(var(--u), 0.703400px);  /* 12 / 17.06 */
      --t-sub: max(var(--u), 0.706714px);  /* 12 / 16.98 */
    }
  }
  .faq-bg, .faq-title > *, .faq-rule, .faq-sub { position: absolute; margin: 0; }
  /* the plate is the 1152u stage; if the section grows it stays top-anchored and covers */
  .faq-bg { left: 0; top: 0; width: 100%; height: 100%; object-position: 50% 0; }

  /* FAQ: the file's alpha > 64 bbox (inset L4 T3 R3 B4 of 1000x371) on the mockup ink [811,231,454,166] */
  .faq-title .lettering-faq {
    left: calc(var(--u) * 810.17); top: calc(var(--u) * 229.63);
    width: calc(var(--u) * 456.62); max-width: none;
  }
  /* placed by ink-left 691.25 (the F's side bearing 1.28) and baseline 441.27, not centred */
  .faq-heading {
    left: calc(var(--u) * (691.25 - 1.28)); top: calc(var(--u) * (441.27 - 26.4 * 0.842));
    font-size: calc(var(--u) * 26.4);
    line-height: 1;
    letter-spacing: .568em;
    word-spacing: -.135em;
    white-space: nowrap;
  }
  .faq-rule {
    left: calc(var(--u) * 984.6); top: calc(var(--u) * 472.08);
    width: calc(var(--u) * 108.85); height: max(1px, calc(var(--u) * 1.65));
  }
  /* ink-left 804.67 (box 803.72: the E's side bearing, measured) and baseline 508.94; a floored subtitle grows about
     its ink centre (450.73 wide) */
  .faq-sub {
    left: calc(var(--u) * 803.72 - (var(--t-sub) - var(--u)) * 225.37);
    top: calc(var(--u) * 508.94 - var(--t-sub) * 16.98 * var(--ab));
    font-size: calc(var(--t-sub) * 16.98);
    line-height: 1;
    white-space: nowrap;
  }

  /* boxes x 590.0-1482.8, 52.1 tall on a 62.4 pitch. The open item grows 7.9 up (its question baseline and mark
     stay where a closed one's sit) and down by its answer; the mockup's gap under it is 11.65, not 10.3 */
  .faq-list {
    margin: 0 0 0 calc(var(--u) * 590);
    width: calc(var(--u) * 892.8);
    padding-top: calc(var(--u) * 7.9);
  }
  .faq-item { --ring-w: max(1px, calc(var(--u) * 1.75)); --ring-r: calc(var(--u) * 2); }
  .faq-item[open] { --ring-w: max(1px, calc(var(--u) * 2)); margin-top: calc(var(--u) * -7.9); }
  .faq-item + .faq-item { margin-top: calc(var(--u) * 10.3); }
  .faq-item + .faq-item[open] { margin-top: calc(var(--u) * (10.3 - 7.9)); }
  .faq-item[open] + .faq-item { margin-top: calc(var(--u) * 11.65); }

  /* question ink-left 631.6 (box 631.2: Barlow's side bearings are 0.06-0.64); baseline 33.24 below a closed
     box's top, 41.14 below the open one's */
  .faq-item summary {
    min-height: calc(var(--u) * 52.1);
    padding: calc(var(--u) * 33.24 - var(--fq) * var(--qb)) calc(var(--u) * 77.8) 0 calc(var(--u) * 41.2);
    font-size: var(--fq);
    line-height: 1;
    letter-spacing: .30em;
    word-spacing: .10em;
  }
  .faq-item[open] summary {
    min-height: 0;
    padding-top: calc(var(--u) * 41.14 - var(--fq) * var(--qb));
  }
  /* 16.1 arm, 2.0 stroke, centred on x 1440.8; y 26.26 below a closed box's top, 33.89 below the open one's */
  .faq-mark {
    --ms: max(1px, calc(var(--u) * 2));
    left: calc(var(--u) * (850.8 - 8.05)); right: auto;
    top: calc(var(--u) * (26.26 - 8.05));
    width: calc(var(--u) * 16.1); height: calc(var(--u) * 16.1);
  }
  .faq-item[open] .faq-mark { top: calc(var(--u) * (33.89 - 8.05)); }
  /* answer: ink-left 631.6, right edge x 1405 (a 773.4 column, so answer 1 wraps as the mockup's); first
     baseline 36.75 below the question's, the last 30.12 above the box bottom. Abel's ink sits 0.5 above its metric
     baseline here (measured on the render), hence 37.25 / 29.62. Both clears are in the answer's text unit, so a
     floored answer keeps the mockup's clear to its question and to the box */
  .faq-a {
    padding:
      calc(var(--t-a) * 37.25 - var(--fq) * (1 - var(--qb)) - var(--fa) * var(--ab) - (var(--la) - var(--fa)) / 2)
      calc(var(--u) * 77.8)
      calc(var(--t-a) * 29.62 - (var(--la) + var(--fa)) / 2 + var(--fa) * var(--ab))
      calc(var(--u) * 41.6);
    font-size: var(--fa);
    line-height: var(--la);
    letter-spacing: .155em;
    word-spacing: -.05em;
  }
  /* Abel ships only 400, 0.53 px light on stem (FONTS.md): the answer and subtitle carried 0.80 of the mockup's ink
     mass, so their stems are thickened by a 0.2 px same-colour stroke, as Pricing's feature lines are (1.00 / 0.98
     / 0.96 on the answer lines, 0.98 on the subtitle; F4) */
  .faq-a, .faq-sub { -webkit-text-stroke: calc(var(--u) * 0.2) currentColor; }

}

/* ---------- CTA section (screen 6) ---------- */

/* below 900 (spec D7): the card is a grid item, and the two mosaics are placed against its grid area, so they follow
   the card's edges and top however its copy wraps. The mosaics are opaque paper-baked plates; the glow sits over
   them and under the glass card, whose backdrop-filter frosts the plates' inner halves beneath it */
.cta {
  position: relative;
  isolation: isolate;
  overflow-x: clip;  /* the mosaics bleed past the page edges (spec D7, D11); clip, so no scroll container */
  background: var(--paper);
}
.cta-mosaic {
  position: absolute;
  height: auto;
}
/* the plates' baked paper reads 2-3 levels under --paper (#F3F2F1 against #F5F4F4, past spec D1's +-2 gate), so each
   fades out along the edges that meet open paper; the page edge (left) and the clipped overflow (right) keep theirs */
.cta-mosaic-left {
  left: 0;
  -webkit-mask: linear-gradient(90deg, #000 90%, transparent), linear-gradient(transparent, #000 7% 93%, transparent);
  -webkit-mask-composite: source-in;
  mask: linear-gradient(90deg, #000 90%, transparent), linear-gradient(transparent, #000 7% 93%, transparent);
  mask-composite: intersect;
}
.cta-mosaic-right {
  -webkit-mask: linear-gradient(90deg, transparent, #000 5%), linear-gradient(transparent, #000 7% 93%, transparent);
  -webkit-mask-composite: source-in;
  mask: linear-gradient(90deg, transparent, #000 5%), linear-gradient(transparent, #000 7% 93%, transparent);
  mask-composite: intersect;
}
/* the streak layer is desktop-only (C6). On the stage the tails run under the card's empty side margins (the text
   zone is its middle 48%); below 900 the text spans all but the card's padding, so any tail would cross the copy.
   The plates' own inner halves, under the thinned side glass, carry the "under the glass" read instead. The filter
   SVG stays rendered at zero size: Firefox drops filters defined inside a display:none SVG */
.cta-streaks { display: none; }
.cta-filters { position: absolute; width: 0; height: 0; }
.cta-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(60% 30% at 30% 80%, rgb(66 136 236 / .34), rgb(66 136 236 / 0)),
    radial-gradient(60% 26% at 70% 82%, rgb(162 119 230 / .44), rgb(162 119 230 / 0));
}
.cta-card {
  position: relative;
  isolation: isolate;
  max-width: 640px;
  margin: 0 auto;
  padding: 36px 20px 40px;
  border: 3px solid var(--modal-ink);
  border-radius: 28px;
  background: var(--cta-glass);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 0 8px rgb(8 21 43 / .035);
  text-align: center;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .cta-card { background: rgb(250 250 251 / .9); }
}
.cta-rule {
  display: block;
  width: 64px; height: 4px;
  margin: 0 auto;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--tri-cyan), var(--cta-rule-magenta));
}
.cta-title {
  margin-top: 28px;
  font-family: var(--font-caps);
  font-weight: 500;
  font-size: 24px;
  line-height: 1.25;
  color: var(--tri-navy);
}
/* each line carries its own tracking (FONTS.md) and pads its left by it, so the trailing tracking cancels and the
   centred line sits on its ink */
.cta-title .cta-line { display: block; }
.cta-title-1 { letter-spacing: .2265em; word-spacing: .011em; padding-left: .2265em; }
.cta-title-2 { letter-spacing: .2365em; word-spacing: .030em; padding-left: .2365em; }
.cta-body {
  margin-top: 20px;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.6;
  letter-spacing: .081em;
  word-spacing: .036em;
  color: var(--ink-blue);
}
.btn-start {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-height: 56px;
  margin-top: 28px;
  padding: 12px 24px;
  border-radius: 10px;
  /* the 4-stop fill under a two-sided sheen: white lifts the top half, a deep blue-violet sinks the bottom half
     (PALETTE note 5) */
  background:
    linear-gradient(180deg, rgb(255 255 255 / .06), rgb(255 255 255 / 0) 50%, rgb(47 0 255 / 0) 50%, rgb(47 0 255 / .11)),
    linear-gradient(90deg, var(--cta-btn-cyan) 1.2%, var(--cta-btn-blue) 29.9%, var(--cta-btn-violet) 55%,
      var(--cta-btn-magenta) 98.8%);
  color: var(--modal-ink);
  font-family: var(--font-caps);
  font-weight: 500;
  font-size: 15px;
  line-height: 1;
  letter-spacing: .104em;
  word-spacing: .090em;
  white-space: nowrap;
}
/* the drop shadow is a blurred copy of the fill (PALETTE note 6): cyan under the left end, pink under the right. It
   paints under the button, inside the card's stacking context */
.btn-start::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 5px;
  border-radius: inherit;
  background: inherit;
  translate: 0 8px;
  filter: blur(12px);
  opacity: .42;
}
.btn-start:hover { filter: brightness(1.05); }
.btn-start:hover::before { opacity: .56; }
/* the site's ring, following the button's corners (the shared a:focus-visible squares them) */
.btn-start:focus-visible { border-radius: 10px; }
.btn-start-rocket { flex: none; width: 26px; height: 25px; fill: currentColor; }

/* below 900 (spec D7): each plate is --mw of the width, its box centred on a card edge (16 px in; 8% at 600-899),
   so it bleeds off-page outward and runs under the glass inward. It rises above the card's top (the mockup's clouds
   start above the card): by half its height below 600, which puts the dense core on the card's top corner, since
   the in-card half at that width is mostly under copy; by a third at 600-899. The section's top padding covers the
   rise. Each plate's off-page part is cut by an inset() clip-path at the page edge; the section's clip would hide it
   anyway, but the plates are opaque, so the offscreen invariants count them by their clipped box. The insets are
   single lengths or percentages, never a %-and-px calc(): the invariants parse the computed inset() and cannot read
   a calc(). The glass thins inside the card's padding only, where no copy runs. The heading's per-line --dx fit is a
   stage fit: the translate that uses it is desktop only, and it is zeroed here too, because these lines rewrap and
   centre on the card */
@media (max-width: 899.98px) {
  .cta {
    --mw: 45%;
    container-type: inline-size;  /* for the clip insets, which must compute to a plain length (below) */
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    padding: calc(19% + 16px) 0 64px;
  }
  .cta-card { grid-area: 1 / 1; width: calc(100% - 32px); max-width: none; }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .cta-card {
      background: linear-gradient(90deg, rgb(250 250 251 / .3), var(--cta-glass) 7% 93%, rgb(250 250 251 / .3));
    }
  }
  .cta-mosaic { grid-area: 1 / 1; top: 0; width: var(--mw); }
  .cta-mosaic-left {
    left: calc(16px - var(--mw) / 2);
    translate: 0 -50%;
    clip-path: inset(0 0 0 calc(calc(var(--cqw, 1cqw) * 22.5) - 16px));  /* half of --mw, less the gutter */
  }
  .cta-mosaic-right {
    left: calc(100% - 16px - var(--mw) / 2);
    translate: 0 -46%;
    clip-path: inset(0 calc(calc(var(--cqw, 1cqw) * 22.5) - 16px) 0 0);
  }
  .cta-line { --dx: 0; }
}
/* 600-899: the card is 84% of the width (its edges 8% in), the plates 46% (so the off-page part is 23 - 8 = 15% of
   the width, 32.61% of a plate); the heading grows toward the stage's 30 px at 900 */
@media (min-width: 600px) and (max-width: 899.98px) {
  .cta { --mw: 46%; padding-top: calc(14% + 16px); }
  .cta-card { width: 84%; padding: 44px 40px 48px; }
  .cta-mosaic-left { left: calc(8% - var(--mw) / 2); translate: 0 -34%; clip-path: inset(0 0 0 32.61%); }
  .cta-mosaic-right { left: calc(92% - var(--mw) / 2); translate: 0 -30%; clip-path: inset(0 32.61% 0 0); }
  .cta-title { font-size: clamp(24px, 3.36vw, 30px); }
}
/* the translate property is Chrome 104+ (Android Chrome 99 dropped it and the mosaics slid down behind the card):
   the same offsets as transforms, only where translate is unsupported, so the two never stack */
@supports not (translate: 0) {
  .btn-start::before { transform: translateY(8px); }
  @media (max-width: 899.98px) {
    .cta-mosaic-left { transform: translateY(-50%); }
    .cta-mosaic-right { transform: translateY(-46%); }
  }
  @media (min-width: 600px) and (max-width: 899.98px) {
    .cta-mosaic-left { transform: translateY(-34%); }
    .cta-mosaic-right { transform: translateY(-30%); }
  }
  @media (min-width: 900px) {
    .cta-line { transform: translateX(calc(var(--u) * var(--dx, 0))); }
    .btn-start::before { transform: translateY(calc(var(--u) * 16)); }
  }
}

@media (prefers-reduced-motion: no-preference) {
  .btn-start { transition: filter .2s ease; }
  .btn-start::before { transition: opacity .2s ease; }
}

/* desktop: a stage in the same mockup px (spec D6: --u, mockup y 100-905, so section y = mockup y - 100; the footer
   hairline below is the mockup's y 905). Boxes: docs/pws/PALETTE.md and FONTS.md "CTA section". Inside the card,
   positions are written as mockup px minus the card's origin (--ox, --oy), its outer box [448.77, 216.69, 1150.65,
   594.22]. The 3.8 rim is an inset shadow, not a border, because Chrome floors border widths to whole pixels. Text is placed by baseline: top = baseline - size x --k */
@media (min-width: 900px) {
  .cta {
    --u: calc(calc(var(--cqw, 1cqw) * 100) / 2048);
    --t-body: var(--u);  /* the body floors at 12px (FONTS.md: below a 1059 stage) */
    --k-rc: 0.8418;      /* Roboto Condensed */
    --k-bsc: 0.9;        /* Barlow Semi Condensed */
    /* the card's corners, TL TR BR BL: the mockup's are uneven (rim-core circles 46.8, 45.7, 48.1, 43.0; PALETTE
       "Geometry"), so each is set to land its rim core on the mockup's (C5) rather than one 48 */
    --cta-radius: calc(var(--u) * 50.6) calc(var(--u) * 49) calc(var(--u) * 50.4) calc(var(--u) * 47);
    width: calc(var(--u) * 2048);
    height: calc(var(--u) * 805);
    padding: 0;
  }
  @container (max-width: 1059.3px) {
    .cta { --t-body: max(var(--u), 0.517241px); }  /* 12 / 23.2 */
  }
  /* the plates' boxes, fitted so each cloud lands on the mockup's (C5: gray NCC outside the card, 0.94 / 0.99), not
     B9's slot boxes [0,118,670] and [1460,152,708]; section y = mockup y - 100. Both run past the stage edge (the
     left by 32, the right past x 2048) and the section clips them. Each is also cut at the stage edge by an inset()
     clip-path, which paints nothing different but keeps the opaque plates' boxes on the page for the offscreen
     invariants (C6); the streak copies below are cut the same way */
  .cta-mosaic-left  {
    left: calc(var(--u) * -32); top: calc(var(--u) * 29); width: calc(var(--u) * 697);
    clip-path: inset(0 0 0 calc(var(--u) * 32));
  }
  .cta-mosaic-right {
    left: calc(var(--u) * 1429); top: calc(var(--u) * 52); width: calc(var(--u) * 705.2);
    clip-path: inset(0 calc(var(--u) * 86.2) 0 0);  /* 1429 + 705.2 - 2048 */
  }
  /* the streak tails under the glass (C5). The mockup's clouds trail saturated horizontal streaks well into the card
     (to x ~700 on the left, from x ~1350 on the right), which the frosted card alone washes out. Each plate is drawn
     again here, smeared sideways toward the centre by an SVG filter (a horizontal-only Gaussian, #cta-smear-*), and
     clipped to the card's box under a mask that falls off toward the text zone; the card's glass thins at its two
     sides to match. Fitted on the mockup's column depth over rows 280-600 (docs/pws/REPORT-C5.md) */
  .cta-streaks {
    --m: linear-gradient(90deg, #000, rgb(0 0 0 / .48) 6%, rgb(0 0 0 / .36) 14%, rgb(0 0 0 / .28) 24%,
      rgb(0 0 0 / .14) 34%, transparent 44% 64%, rgb(0 0 0 / .15) 74%, rgb(0 0 0 / .3) 82%, rgb(0 0 0 / .35) 90%,
      rgb(0 0 0 / .38) 95%, rgb(0 0 0 / .6));
    position: absolute;
    display: block;
    left: calc(var(--u) * 448.77); top: calc(var(--u) * (216.69 - 100));
    width: calc(var(--u) * 1150.65); height: calc(var(--u) * 594.22);
    overflow: hidden;
    border-radius: var(--cta-radius);
    -webkit-mask: var(--m);
    mask: var(--m);
  }
  .cta-streak { position: absolute; background: center / 100% 100% no-repeat; }
  .cta-streak-left {
    left: calc(var(--u) * (-32 - 448.77)); top: calc(var(--u) * (129 - 216.69));
    width: calc(var(--u) * 697); height: calc(var(--u) * 584.69);
    background-image: url(../assets/cta-mosaic-left.webp);
    filter: url(#cta-smear-left);
    clip-path: inset(0 -100% 0 calc(var(--u) * 32));  /* open on the side the smear runs out of the box */
  }
  .cta-streak-right {
    left: calc(var(--u) * (1429 - 448.77)); top: calc(var(--u) * (152 - 216.69));
    width: calc(var(--u) * 705.2); height: calc(var(--u) * 537.9);
    background-image: url(../assets/cta-mosaic-right.webp);
    filter: url(#cta-smear-right);
    clip-path: inset(0 calc(var(--u) * 86.2) 0 -100%);
  }
  /* two elliptical radial gradients with linear falloff, fitted over 1,490 windows (PALETTE note 3); centres in
     section px. The layer is the section's box, so the section's bottom (the footer hairline) cuts the haze off */
  .cta-glow {
    background:
      radial-gradient(calc(var(--u) * 470) calc(var(--u) * 235) at calc(var(--u) * 761) calc(var(--u) * 597),
        rgb(66 136 236 / .34), rgb(66 136 236 / 0)),
      radial-gradient(calc(var(--u) * 461) calc(var(--u) * 203) at calc(var(--u) * 1245) calc(var(--u) * 616),
        rgb(162 119 230 / .44), rgb(162 119 230 / 0));
  }
  .cta-card {
    --ox: 448.77;
    --oy: 216.69;
    position: absolute;
    left: calc(var(--u) * 448.77); top: calc(var(--u) * (216.69 - 100));
    width: calc(var(--u) * 1150.65); height: calc(var(--u) * 594.22);
    max-width: none;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: var(--cta-radius);
    /* the glass thins toward its sides so the streaks read through; the text zone keeps --cta-glass. Its lower part
       thickens (the first layer): the mockup's card passes only ~1/5 of the glow behind it (at y 650-805 it reads
       2-5 levels under the fill, not 12-17), and the darkening at (1024,790) is the button's shadow, not glow. The
       glow's own fit is outside the card and is unchanged. The blur is light (3, from 14) because the streaks arrive
       pre-smeared, and a heavy blur dissolves their rows */
    background: linear-gradient(rgb(250 250 251 / 0) 58%, rgb(250 250 251 / .75) 78%, rgb(250 250 251 / .6)),
      linear-gradient(90deg, rgb(250 250 251 / .25), var(--cta-glass) 26% 74%, rgb(250 250 251 / .4));
    -webkit-backdrop-filter: blur(calc(var(--u) * 3));
    backdrop-filter: blur(calc(var(--u) * 3));
    box-shadow: inset 0 0 0 calc(var(--u) * 3.8) var(--modal-ink), 0 0 calc(var(--u) * 8) rgb(8 21 43 / .035);
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .cta-card {
      background: linear-gradient(rgb(250 250 251 / 0) 58%, rgb(250 250 251 / .75) 78%, rgb(250 250 251 / .6)),
        linear-gradient(90deg, rgb(250 250 251 / .4), rgb(250 250 251 / .9) 26% 74%, rgb(250 250 251 / .5));
    }
  }
  .cta-card > * { position: absolute; margin: 0; }
  .cta-rule {
    left: calc(var(--u) * (979.6 - var(--ox))); top: calc(var(--u) * (282.85 - var(--oy)));
    width: calc(var(--u) * 88.5); height: calc(var(--u) * 6.1);
    border-radius: calc(var(--u) * 3);
  }
  /* the heading and body span the card, centred on its axis (x 1024.10) */
  .cta-title, .cta-body { left: 0; width: 100%; line-height: 1; }
  .cta-line { display: block; white-space: nowrap; }
  /* Mockup fidelity, kept by the user's approval at checkpoint 1 (2026-09-27): every text line's ink sits right of
     the axis the card, rule and button share (FONTS.md "Heading axis"), by --dx mockup px per line. To centre, set
     --dx: 0 on .cta-line (below 900 it is 0) */
  .cta-line { translate: calc(var(--u) * var(--dx, 0)) 0; }
  .cta-title-1 { --dx: 17.1; }  /* ink centre 1041.1 */
  .cta-title-2 { --dx: 21.1; }  /* 1045.1 */
  .cta-body-1  { --dx: 10.3; }  /* 1034.3 */
  .cta-body-2  { --dx: 14.3; }  /* 1038.3 */
  .cta-body-3  { --dx: 20.6; }  /* 1044.6 */
  /* 68.8, baselines 393.00 and 474.73 (pitch 81.73) */
  .cta-title {
    top: calc(var(--u) * (393 - var(--oy)) - var(--u) * 68.8 * var(--k-rc));
    font-size: calc(var(--u) * 68.8);
  }
  .cta-title-2 { margin-top: calc(var(--u) * (81.73 - 68.8)); }
  /* 23.2, baselines 536.73, 578.05 and 619.87; a floored body grows down from line 1 */
  .cta-body {
    top: calc(var(--u) * (536.73 - var(--oy)) - var(--t-body) * 23.2 * var(--k-bsc));
    font-size: calc(var(--t-body) * 23.2);
  }
  .cta-body .cta-line { padding-left: .081em; }  /* the trailing tracking, so each centred line sits on its ink */
  .cta-body-2 { margin-top: calc(var(--t-body) * (41.32 - 23.2)); }
  .cta-body-3 { margin-top: calc(var(--t-body) * (41.82 - 23.2)); }
  /* the fill [791.74, 671.33, 463.65, 85.99], radius 12; the rocket and label are placed by their left offsets
     (the group sits 5.6 right of the button's centre), not centred */
  .btn-start {
    left: calc(var(--u) * (791.74 - var(--ox))); top: calc(var(--u) * (671.33 - var(--oy)));
    display: block;
    width: calc(var(--u) * 463.65); height: calc(var(--u) * 85.99);
    min-height: 0;
    padding: 0;
    border-radius: calc(var(--u) * 12);
    font-size: calc(var(--u) * 27.2);
  }
  /* offset 16.1 down, sigma 22.4, spread -9.3, opacity .42 (PALETTE note 6) */
  .btn-start::before {
    inset: calc(var(--u) * 9);
    translate: 0 calc(var(--u) * 16);
    filter: blur(calc(var(--u) * 22));
  }
  .btn-start:focus-visible { border-radius: calc(var(--u) * 12); }
  /* the tap target: the 85.99-tall fill is under 44 px below a 1048 stage, so an invisible hit box grows it to 44
     there, centred on the fill; from 1048 up it is the fill itself */
  .btn-start::after {
    content: "";
    position: absolute;
    inset: min(0px, (var(--u) * 85.99 - 44px) / 2) 0;
  }
  /* the traced path's viewBox origin is mockup (847, 698), 37 x 36 */
  .btn-start-rocket {
    position: absolute;
    left: calc(var(--u) * (847 - 791.74)); top: calc(var(--u) * (698 - 671.33));
    width: calc(var(--u) * 37); height: calc(var(--u) * 36);
  }
  /* ink-left 913.55, baseline 725.22; the S's side bearing (--sb, em) sits the box left of the ink */
  .btn-start-label {
    --sb: 0.04;
    position: absolute;
    left: calc(var(--u) * (913.55 - 791.74) - var(--sb) * 1em);
    top: calc(var(--u) * (725.22 - 671.33) - 1em * var(--k-rc));
  }
}

/* ---------- site footer (after the FAQ screen; no mockup: spec amendment "footer", brief F4b) ---------- */

/* below 900: one centred column - wordmark, nav, legal links, copyright - every link >= 44x44. The CTA row moved
   out to section.cta (screen 6); the footer opens on .footer-main's hairline */
.site-footer {
  padding: 0 16px 28px;
  background: var(--paper);
  color: var(--ink);
  text-align: center;
}
.footer-main {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding-top: 32px;
  border-top: 1px solid var(--faq-border);
}
.footer-brand { display: flex; align-items: center; min-height: 44px; transition: opacity .2s ease; }
.footer-brand:hover { opacity: .78; }
.footer-brand img { width: 176px; height: auto; }
.footer-nav-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 8px;
}
.footer-nav a { justify-content: center; padding: 0 10px 0 calc(10px + .21em); }
.footer-legal {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin-top: 20px;
  font-family: var(--font-label);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: .2em;
  text-transform: uppercase;
}
.footer-legal-links { order: -1; display: flex; flex-wrap: wrap; justify-content: center; align-items: center; }
.footer-legal-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 8px;
  color: var(--ink);
  transition: color .2s ease;
}
.footer-legal-links a:hover,
.footer-legal-links a:focus-visible { color: var(--magenta-text); }
.footer-dot { color: var(--body); }
.footer-copy { color: var(--body); line-height: 1.6; }

/* desktop: the footer spans the stage width in stage units. Content edges are the header's: the wordmark's left
   (50.03) and the header button's right edge (1973, measured). Rows at 2048, in u: the hairline (the CTA mockup's
   y 905 line); brand row (40 above, the wordmark's 55.7); legal row (40 above, 12.2 text, 48 below) */
@media (min-width: 900px) {
  .site-footer {
    width: calc(var(--u) * 2048);
    padding: 0 calc(var(--u) * (2048 - 1973)) calc(var(--u) * 48) calc(var(--u) * 50.03);
    text-align: left;
  }
  .footer-main {
    border-top: max(1px, calc(var(--u) * 1)) solid var(--faq-border);
    flex-direction: row;
    justify-content: space-between;
    gap: 0;
    margin: 0;
    padding-top: calc(var(--u) * 40);
  }
  .footer-brand { display: block; min-height: 0; }
  .footer-brand img { width: calc(var(--u) * 245.93); }
  /* the header nav's gaps, box to box (53.0 / 53.2 / 52.2 measured) */
  .footer-nav-list { flex-wrap: nowrap; gap: calc(var(--u) * 53); }
  .footer-nav a { padding: 0; }
  .footer-legal {
    flex-direction: row;
    justify-content: space-between;
    align-items: baseline;
    gap: 0;
    margin-top: calc(var(--u) * 40);
    font-size: calc(var(--t-legal) * 12.2);
    line-height: 1;
  }
  .footer-legal-links { order: 0; gap: calc(var(--u) * 16); }
  .footer-copy, .footer-legal-links li { line-height: 1; white-space: nowrap; }
  .footer-legal-links a { display: inline; min-height: 0; padding: 0; white-space: nowrap; }
  /* the last link's trailing tracking hangs past the edge, so the nav and legal ink end on the content edge */
  .footer-nav li:last-child a { margin-right: -.21em; }
  .footer-legal-links li:last-child a { margin-right: -.2em; }
}

/* ---------- start-project modal (screen 5) ---------- */

/* the scroll lock hides the page scrollbar; main.js measures its width into --modal-sbw and the root pads by it, so the
   page keeps its width and does not shift or rescale (scrollbar-gutter on the root moved clientWidth and 100vw) */
html.modal-open { overflow: hidden; padding-right: var(--modal-sbw, 0px); }

/* full-viewport, transparent dialog; the panel inside it is the visible modal. A size container, so the panel's
   --u is the dialog width / 2048: the same as the hero stage's (the dialog gives up the hidden scrollbar's width too) */
.modal {
  width: calc(100% - var(--modal-sbw, 0px));
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--paper);
  overflow: auto;
  overscroll-behavior: contain;
  container-type: size;
  color-scheme: dark;
}
.modal [hidden] { display: none !important; }
/* the fitted scrim (PALETTE note 10, M3 amendment): navy at a 0.215 at the top, 0.16 from y 560 of 1152 down */
.modal::backdrop { background: linear-gradient(rgb(10 11 32 / .215), rgb(10 11 32 / .16) 48.6%); }

.modal-panel {
  --ring-w: 2px;
  --panel-r: 16px;
  --modal-title-gradient: linear-gradient(90deg, #32C4F4 25%, #3EA3F0 31%, var(--side-periwinkle) 36%, #7972EB 41%,
    #A050E6 50%, #C251E0 67%, #DA6FE0 76%);
  position: relative;
  isolation: isolate;
  width: calc(100% - 32px);
  max-width: 600px;
  margin: 16px auto;
  padding: 60px 20px 24px;
  border-radius: var(--panel-r);
  background: linear-gradient(100deg, var(--modal-navy) 55%, var(--modal-violet));
  box-shadow: 0 6px 20px rgb(0 30 70 / .18);
}
.modal-bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* a tall panel crops the square plate to a strip: keep the strip with the bright contour, bottom right */
  object-position: right bottom;
  border-radius: inherit;
}
/* the ring's inner glow over the plate edge: blue down the left, faint elsewhere (mockup inner-edge profiles) */
.modal-glow {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow:
    inset var(--glow-l, 5px) 0 var(--glow-lb, 8px) 0 rgb(15 70 140 / .75),
    inset calc(var(--glow-s, 3px) * -1) 0 var(--glow-sb, 5px) 0 rgb(40 40 100 / .4),
    inset 0 var(--glow-s, 3px) var(--glow-sb, 5px) 0 rgb(70 64 84 / .3),
    inset 0 calc(var(--glow-s, 3px) * -1) var(--glow-sb, 5px) 0 rgb(20 40 140 / .35);
  pointer-events: none;
}

/* every frame is a masked gradient ring over its box (the FAQ open-item technique, spec D4) */
.modal-panel::before,
.field::before,
.modal-submit::before {
  content: "";
  position: absolute;
  inset: 0;
  padding: var(--ring-w);
  border-radius: inherit;
  background: var(--ring-bg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}
/* the panel ring (PALETTE note 2, M3 amendment): cyan down both sides, violet across the top turning magenta only at
   the top-right corner, cyan-violet-cyan along the bottom; the right-edge layer starts below the corner so the corner
   stays magenta */
.modal-panel {
  --ring-bg:
    linear-gradient(#5E9DBB 5%, #6CA2C3 25%, #5C9FC2 50%, #309EC9 68%, #2982AE 85%, var(--modal-ring-cyan))
      right bottom / calc(var(--ring-w) * 1.5) calc(100% - var(--panel-r) * 1.75) no-repeat,
    linear-gradient(#476D9B 3%, #669FC8 25%, #6EBBD6 50%, #7CC0D7 65%, #7BA9C3 85%, #5C82BB 97%)
      left center / calc(var(--ring-w) * 1.5) calc(100% - var(--panel-r) * 1.5) no-repeat,
    linear-gradient(90deg, #59459C 3%, var(--modal-ring-aqua) 20%, #676AD6 38%, #686AD6 70%, #72BCF8 82%,
      var(--modal-ring-cyan) 89%)
      left bottom / 100% calc(var(--ring-w) * 1.5) no-repeat,
    linear-gradient(90deg, #476D9B 1%, #7C55B2 7.7%, #6A6AC2 26.5%, #6B66C2 45.3%, #6A67C2 50%, #7952C2 64.2%,
      #8E48B7 83%, var(--modal-ring-magenta) 92.4%);
}
.modal-panel::before { z-index: 1; }
/* the 1-px light line inside the colour line, mixed over the ring colour at the share each edge implies (PALETTE
   note 2): a cyan-white at 0.78 down the left and white at 0.72 down the right, lavender at 0.6 along the top turning pink at the magenta corner (the mockup's top line is
   a saturated violet, not a whitened one); none along the bottom, where the mockup's ring is one soft violet line */
.modal-panel::after {
  content: "";
  position: absolute;
  inset: var(--ring-w);
  z-index: 1;
  padding: max(1px, var(--line-w, 1px));
  border-radius: calc(var(--panel-r) - var(--ring-w));
  background:
    linear-gradient(90deg, rgb(244 216 255 / .6) 70%, rgb(255 180 255 / .5) 92%) top / 100% calc(var(--ring-w) * 1.5)
      no-repeat,
    linear-gradient(rgb(245 255 255 / .78) 0 0) left center / 50% calc(100% - var(--ring-w) * 3) no-repeat,
    linear-gradient(rgb(250 252 255 / .72) 0 0) right center / 50% calc(100% - var(--ring-w) * 3) no-repeat,
    var(--ring-bg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

.modal-close {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  width: 44px;
  height: 44px;
  padding: 14px;
  border: 0;
  background: none;
  color: var(--paper);
  cursor: pointer;
}
.modal-close svg { width: 100%; height: 100%; overflow: visible; fill: none; stroke: currentColor; stroke-width: 2; }
.modal-close:hover { color: var(--modal-btn-cyan); }

/* heading: Roboto Condensed 500, two separately tracked lines, centred on their ink (a text-indent equal to the
   tracking balances the trailing letter-spacing) */
.modal-title {
  margin: 0 0 28px;
  font-family: var(--font-caps);
  font-weight: 500;
  line-height: 1;
  text-align: center;
  outline-offset: 6px;
}
.modal-kicker,
.modal-title-main { display: block; white-space: nowrap; }
/* one line each down to 390 (where YOUR BUSINESS's ink leaves ~30 px a side); the cqw terms only shrink them below
   that, so the widest word never leaves the panel */
.modal-kicker {
  font-size: min(14px, calc(var(--cqw, 1cqw) * 3.59));
  letter-spacing: .382em;
  word-spacing: .159em;
  text-indent: .382em;
  color: var(--modal-ink);
  text-shadow: 0 0 8px rgb(80 60 255 / .35);
}
.modal-title-main {
  margin-top: 12px;
  font-size: min(26px, calc(var(--cqw, 1cqw) * 6.67));
  letter-spacing: .281em;
  word-spacing: .06em;
  text-indent: .281em;
  background: var(--modal-title-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 4px rgb(80 60 255 / .45));
}

.modal-form { display: grid; gap: 28px; }
.modal-label {
  display: block;
  margin: 18px 0 8px;
  font: 400 12px/1.4 var(--font-caps);
  letter-spacing: .114em;
  word-spacing: .176em;
  color: var(--modal-ink);
}
.modal-fields > .modal-label:first-child { margin-top: 0; }

.field {
  --ring-w: 1.5px;
  /* one blue -> slate -> violet gradient along the top; the mockup draws the left edge a deeper blue, the right edge a
     lighter violet and the bottom darker and more violet than the top (PALETTE note 3, per-edge core reads). The edge
     strips are twice the ring width and the mask trims them: Chrome rounds a 1.5-px tile down to 1 px. M7c (user-directed,
     over mockup fidelity): every edge lifted along its own hue to >= 3:1 on the plate, the edges' order kept (the right
     edge, already clear, unchanged); the mockup's reads were left #355282, bottom #4C6092 / #484A7C / #574276 */
  --ring-bg:
    linear-gradient(#486798 0 0) left / calc(var(--ring-w) * 2) 100% no-repeat,
    linear-gradient(#756E93 0 0) right / calc(var(--ring-w) * 2) 100% no-repeat,
    linear-gradient(90deg, #566B9E 11%, #5E6195 50%, #705B91 89%) bottom / 100% calc(var(--ring-w) * 2) no-repeat,
    linear-gradient(90deg, var(--modal-field-blue) 11%, var(--modal-field-slate) 50%, var(--modal-field-violet) 89%);
  position: relative;
  border-radius: 4px;
}
.field.is-invalid { --ring-bg: var(--modal-error); }
.field-icon {
  position: absolute;
  left: 12px;
  top: 12px;
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--paper);
  pointer-events: none;
}
.field-divider {
  position: absolute;
  left: 48px;
  top: 10px;
  bottom: 10px;
  width: 1px;
  background: var(--modal-divider);
}
.field-desc .field-divider,
.field-area .field-divider { bottom: auto; height: 51px; }
.field input,
.field select,
.field textarea {
  display: block;
  width: 100%;
  height: 48px;
  margin: 0;
  padding: 0 16px 0 62px;
  border: 0;
  border-radius: inherit;
  background: transparent;
  color: var(--paper);
  font: 400 16px/1 var(--font-body);
  letter-spacing: .047em;
  word-spacing: .058em;
}
.field textarea {
  height: 112px;
  min-height: 112px;
  padding-top: 14px;
  padding-right: 40px;
  line-height: 1.6;
  resize: vertical;
}
/* placeholders: Barlow Semi Condensed 400 plus a 0.0092em (0.15 px at 16.27) stroke, tracked per field. M5: 300,
   FONTS' pick, measured 0.35-0.45 px light in the field (the grey-on-navy render thins strokes the white-on-black bake
   did not); 500 matches the weight but hints the x-height to 9 px against the mockup's 8.1 */
.field input::placeholder,
.field textarea::placeholder {
  color: var(--ph-ink, var(--modal-placeholder));
  letter-spacing: var(--ph-ls, .047em);
  -webkit-text-stroke: .0092em currentColor;
  opacity: 1;
}
#bp-name    { --ph-ls: .0317em; }
#bp-email   { --ph-ls: .0317em; } /* not in the mockup: in ADDRESS's slot, with the name field's tracking */
#bp-url     { --ph-ls: .0516em; --ph-ink: var(--modal-placeholder-hi); }
#bp-desc    { --ph-ls: .043em; }
.field select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 48px;
  cursor: pointer;
}
.field select.is-empty { color: var(--modal-placeholder-hi); letter-spacing: .039em; -webkit-text-stroke: .0092em currentColor; }
.field select option { color: var(--paper); background: var(--modal-navy); font-weight: 400; }
.field select option:disabled { color: var(--modal-placeholder); }
.field-chevron {
  position: absolute;
  right: 20px;
  top: 20px;
  width: 16px;
  height: 9px;
  fill: none;
  stroke: var(--paper);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}
.field-error {
  margin: 6px 0 0;
  font: 400 12px/1.25 var(--font-body);
  letter-spacing: .02em;
  color: var(--modal-error);
}
/* start.php could not take the inquiry: one line under the submit button */
.modal-send-error { margin: -16px 0 0; text-align: center; }

/* screen 1's focus ring on every control; --focus (#9188DA) is 6.2:1 on --modal-navy, so no modal variant */
.modal input:focus-visible,
.modal select:focus-visible,
.modal textarea:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 4px;
}
.modal input:focus:not(:focus-visible),
.modal select:focus:not(:focus-visible),
.modal textarea:focus:not(:focus-visible) { outline: none; }

.modal-submit {
  --ring-w: 2px;
  --ring-bg:
    linear-gradient(90deg, var(--note-cyan) 0 var(--ring-w), transparent var(--ring-w)),
    linear-gradient(90deg, var(--faq-cyan) 5%, #7E64CD 52%, #DC78D6 94%, var(--modal-btn-magenta) 100%)
      bottom / 100% var(--ring-w) no-repeat,
    linear-gradient(90deg, var(--modal-btn-cyan) 5%, var(--modal-btn-periwinkle) 31%, var(--modal-btn-violet) 52%,
      var(--modal-btn-pink) 76%, #EA89DF 94%, var(--modal-btn-magenta) 100%);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  width: 100%;
  min-height: 56px;
  margin: 0;
  padding: 12px 16px;
  border: 0;
  border-radius: 3px;
  background: radial-gradient(40% 120% at 100% 50%, var(--modal-btn-glow) 8%, transparent);
  color: var(--modal-ink);
  font: 400 14px/1.2 var(--font-caps);
  letter-spacing: .183em;
  word-spacing: .155em;
  cursor: pointer;
  transition: box-shadow .2s ease;
}
.modal-submit:hover { box-shadow: inset 0 0 18px rgb(146 70 185 / .35); }
.modal-arrow {
  flex: none;
  width: 21px;
  height: 12px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.modal-thanks { text-align: center; }
.modal-thanks-body {
  margin: 0 auto 28px;
  max-width: 34em;
  font: 400 16px/1.5 var(--font-body);
  color: var(--card-border);
}

/* scheduling state (in-person meeting / quick call): the same heading, a line, Calendly's inline page in a plain
   iframe, and a new-tab link under it that a CLOSE replaces once the visitor has booked. Calendly draws on white */
.modal-book { text-align: center; }
.modal-book-body {
  margin: 0 auto 20px;
  max-width: 34em;
  font: 400 16px/1.5 var(--font-body);
  color: var(--card-border);
}
.modal-book-frame {
  height: max(420px, min(660px, calc(100vh - 160px)));
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
}
.modal-book-frame iframe { display: block; width: 100%; height: 100%; border: 0; }
.modal-book-alt {
  margin: 14px 0 0;
  font: 400 14px/1.5 var(--font-body);
  color: var(--card-border);
}
.modal-book-alt a { color: var(--modal-btn-cyan); }
.modal-book .modal-done { margin-top: 20px; }

/* below 900 the panel is in flow: centred in the dialog while it is shorter than the window (the thanks view), top
   and bottom gutters kept while it is taller (the dialog scrolls). The spacers carry the gutters, since auto margins
   collapse to 0 on overflow */
@media (max-width: 899.98px) {
  .modal[open] { display: flex; flex-direction: column; }
  .modal[open]::before,
  .modal[open]::after { content: ""; flex: none; height: 16px; }
  .modal-panel { flex: none; margin-block: auto; }
  /* WE'LL BE IN TOUCH is 17 letters against YOUR BUSINESS's 12: it breaks into two balanced lines when it has to,
     and each line box carries its own gradient */
  .modal-thanks .modal-title-main { white-space: normal; text-wrap: balance; text-indent: 0; padding-left: .281em; }
  /* the error sits in flow below its control, so the field is a one-column grid: the ring, icon, divider, chevron and
     control share row 1 (an absolutely placed grid child takes its grid area as its containing block; its end line must
     be explicit, since an auto end means the container's padding edge) and the error takes row 2, outside the ring */
  .field { display: grid; grid-template-columns: minmax(0, 1fr); }
  .field::before,
  .field > .field-icon,
  .field > .field-divider,
  .field > .field-chevron,
  .field > input,
  .field > select,
  .field > textarea { grid-row: 1 / 2; grid-column: 1; }
  .field > .field-error { grid-row: 2 / 3; grid-column: 1; }
}

/* 600-899: the desktop panel reflowed. The panel is 92% of the window; --v is its width / the mockup panel's 929.7, and
   every size is mockup px x --v (the desktop's proportions), with the text floors and 44-px tap targets as minimums.
   Two columns, fields then the phone / competitors / requirements column (the mockup's styles column), in the
   mockup's 432.3 : 294.7 split with its 79.8 gutter and 50.6 / 72.3 sides */
@media (min-width: 600px) and (max-width: 899.98px) {
  .modal-panel {
    --v: calc(calc(var(--cqw, 1cqw) * 92) / 929.7);
    --panel-r: calc(var(--v) * 23);
    /* the desktop's per-letter stops (panel px), less the 50.64 left padding: the span starts at the content edge */
    --modal-title-gradient: linear-gradient(90deg,
      #32C4F4 calc(var(--v) * 188.16), #3EA3F0 calc(var(--v) * 228.06), #657DEE calc(var(--v) * 269.86),
      #7972EB calc(var(--v) * 310.86), #A050E6 calc(var(--v) * 377.46), #C251E0 calc(var(--v) * 523.96),
      #DA6FE0 calc(var(--v) * 602.46), #D466DF calc(var(--v) * 640.96));
    width: 92%;
    max-width: none;
    margin-inline: auto;
    padding: calc(var(--v) * 44) calc(var(--v) * 72.3) calc(var(--v) * 44.35) calc(var(--v) * 50.64);
  }
  .modal-close {
    top: calc(var(--v) * 45.86 - 22px);
    right: calc(var(--v) * 46.3 - 22px);
    padding: calc(22px - var(--v) * 8.9);
  }
  /* the mockup's baselines 64.07 and 125.33, first label's 188.22 */
  /* centred on the panel, as drawn, not on the asymmetric content box */
  .modal-title { margin: 0 calc(var(--v) * -21.66) calc(var(--v) * 44) 0; }
  .modal-kicker { font-size: max(11px, calc(var(--v) * 22.05)); }
  .modal-title-main { margin-top: calc(var(--v) * 21); font-size: calc(var(--v) * 47.89); }

  .modal-form {
    grid-template-columns: 432.3fr 294.7fr;
    column-gap: calc(var(--v) * 79.76);
    row-gap: calc(var(--v) * 41.2);
    align-items: start;
  }
  .modal-label {
    --fs: max(11px, calc(var(--v) * 14.92));
    margin: calc(var(--v) * 40.07 - var(--fs) * .84) 0 calc(var(--v) * 11.83 - var(--fs) * .16);
    font-size: var(--fs);
    line-height: 1.2;
  }
  .modal-fields > .modal-label:first-child { margin-top: 0; }

  .field {
    --ring-w: max(1px, calc(var(--v) * 1.5));
    --fs: max(12px, calc(var(--v) * 16.27));
    border-radius: calc(var(--v) * 4);
  }
  .field-icon {
    left: calc(var(--v) * 14.46);
    top: calc(50% - var(--v) * 12);
    width: calc(var(--v) * 24);
    height: calc(var(--v) * 24);
  }
  .field-desc .field-icon,
  .field-area .field-icon { top: calc(var(--v) * 27.1); }
  .field-divider { left: calc(var(--v) * 49.66); top: calc(var(--v) * 10); bottom: calc(var(--v) * 10); width: max(1px, var(--v)); }
  .field-desc .field-divider,
  .field-area .field-divider { top: calc(var(--v) * 10.6); height: calc(var(--v) * 51); }
  .field input,
  .field select,
  .field textarea {
    height: max(44px, calc(var(--v) * 49));
    padding: 0 calc(var(--v) * 16) 0 calc(var(--v) * 65);
    font-size: var(--fs);
  }
  .field select { padding-right: calc(var(--v) * 50); }
  /* three placeholder lines at the 1.6 pitch always fit; the mockup's 113.1 wherever that is taller */
  .field textarea {
    height: max(calc(var(--v) * 113.1), calc(var(--fs) * 4.8 + 16px));
    min-height: max(calc(var(--v) * 113.1), calc(var(--fs) * 4.8 + 16px));
    padding: 8px calc(var(--v) * 45.3) 8px calc(var(--v) * 65);
  }
  .field-chevron {
    right: calc(var(--v) * 20.16);
    top: calc(50% - var(--v) * 4.5);
    width: calc(var(--v) * 16);
    height: calc(var(--v) * 9);
  }

  /* the submit's box, 477.89 x 60.85 at mockup x 226.7 (176.06 inside the fields' edge) */
  .modal-form .modal-send-error { grid-column: 1 / -1; margin-top: calc(var(--v) * -28); }
  .modal-form .modal-submit {
    grid-column: 1 / -1;
    justify-self: start;
    width: calc(var(--v) * 477.89);
    margin-left: calc(var(--v) * 176.06);
  }
  .modal-submit {
    --ring-w: max(1px, calc(var(--v) * 2));
    gap: calc(var(--v) * 20);
    min-height: max(44px, calc(var(--v) * 60.85));
    padding: 8px calc(var(--v) * 16);
    font-size: max(11px, calc(var(--v) * 17.61));
  }
  .modal-arrow { width: calc(var(--v) * 21); height: calc(var(--v) * 12); }

  .modal-thanks { padding: calc(var(--v) * 20) 0; }
  .modal-thanks-body { margin-bottom: calc(var(--v) * 44); font-size: max(12px, calc(var(--v) * 20)); }
  .modal-done { width: calc(var(--v) * 240); margin-inline: auto; }
  .modal-book { padding-top: calc(var(--v) * 20); }
  .modal-book-body { margin-bottom: calc(var(--v) * 28); font-size: max(12px, calc(var(--v) * 20)); }
  .modal-book-alt { font-size: max(12px, calc(var(--v) * 16)); }
}

/* below 600: one column, full width less a 16-px gutter a side. Inputs stay 16 px, so iOS Safari does not zoom on
   focus (over the mockup's scale) */
@media (max-width: 599.98px) {
  .modal-panel { max-width: none; margin-inline: auto; }
  /* the submit label on one line at 390: 0.11em tracking, not the desktop's 0.183 */
  .modal-submit { gap: 12px; padding-inline: 12px; letter-spacing: .11em; word-spacing: .1em; }
}

/* desktop: the panel is the mockup's box in stage units (mockup px x --u), centred horizontally; its top sits where
   the mockup's does on a 16:9 window (134.82 of 1152, i.e. 441.18 above the centre line), never above the gutter.
   Every piece inside is placed in panel-relative mockup px (mockup x - 557.3, y - 134.82; PALETTE/FONTS tables).
   Text is placed by baseline: top = baseline - font-size x --k, --k the face's baseline in a line-height-1 box. */
@media (min-width: 900px) {
  .modal-panel {
    --u: calc(calc(var(--cqw, 1cqw) * 100) / 2048);
    --gutter: max(16px, calc(var(--u) * 24));
    --ring-w: calc(var(--u) * 2);
    --line-w: var(--u);
    --panel-r: calc(var(--u) * 23);
    --k-rc: 0.8418;   /* Roboto Condensed */
    --k-bsc: 0.9;     /* Barlow Semi Condensed */
    /* text floors: max(floor, mockup size x --u); 11px labels / heading / submit, 12px inputs, cards, errors, body */
    --t-kick: max(var(--u), 0.498866px);  /* 11 / 22.05 */
    --t-lbl:  max(var(--u), 0.737265px);  /* 11 / 14.92 */
    --t-ph:   max(var(--u), 0.737554px);  /* 12 / 16.27 */
    --t-chk:  max(var(--u), 0.655738px);  /* 12 / 18.3 */
    --t-sub:  max(var(--u), 0.624645px);  /* 11 / 17.61 */
    /* YOUR BUSINESS stops at each letter's ink centre (PALETTE note 7) in panel px: the span is as wide as the panel */
    --modal-title-gradient: linear-gradient(90deg,
      #32C4F4 calc(var(--u) * 238.8), #3EA3F0 calc(var(--u) * 278.7), #657DEE calc(var(--u) * 320.5),
      #7972EB calc(var(--u) * 361.5), #A050E6 calc(var(--u) * 428.1), #C251E0 calc(var(--u) * 574.6),
      #DA6FE0 calc(var(--u) * 653.1), #D466DF calc(var(--u) * 691.6));
    width: calc(var(--u) * 929.7);
    max-width: none;
    height: calc(var(--u) * 862.6);
    /* left at the mockup's 557.3, not centred: the mockup's panel axis is 1022.1, 1.9 left of the window's */
    margin: max(var(--gutter), calc(calc(var(--cqh, 1cqh) * 50) - var(--u) * 441.18)) auto var(--gutter) calc(var(--u) * 557.3);
    padding: 0;
    box-shadow: 0 calc(var(--u) * 6) calc(var(--u) * 20) rgb(0 30 70 / .18);
    --glow-l: calc(var(--u) * 5);
    --glow-lb: calc(var(--u) * 8);
    --glow-s: calc(var(--u) * 3);
    --glow-sb: calc(var(--u) * 5);
  }
  /* plate A28 shows exactly the region it was cropped from, [567,143,910,846]; the ring band around it is the panel's
     navy plus the inner glow. The generation drew the bright contour ~14 px high, so the plate is enlarged 1.8% about
     the region's top-right corner (box [550.6,143,926.4,861.2]) and clipped back to the region: that lands the contour
     on the mockup's (M5 registration; placed 1:1 it sat 2 right and 14 up, under M4's cover 11 right and 6 up) */
  .modal-bg {
    inset: auto;
    left: calc(var(--u) * -6.7);
    top: calc(var(--u) * 8.18);
    width: calc(var(--u) * 926.4);
    height: calc(var(--u) * 861.2);
    border-radius: 0;
    object-fit: fill;
    clip-path: inset(0 0 calc(var(--u) * 15.2) calc(var(--u) * 16.4) round calc(var(--u) * 12));
  }
  .modal-view, .modal-form, .modal-fields { display: block; margin: 0; }
  .modal-thanks { position: absolute; inset: 0; }

  /* the x's ink box is 15.4 x 15.4 against the mockup's 16.15 x 15.36 (M5: it drew 14.3), centred on 1441.15, 181.16 */
  .modal-close {
    top: calc(var(--u) * 29.86); right: auto; left: calc(var(--u) * 867.41);
    width: calc(var(--u) * 32); height: calc(var(--u) * 32);
    padding: calc(var(--u) * 7.1);
  }

  .modal-title { position: absolute; left: 0; top: 0; width: 100%; margin: 0; }
  .modal-kicker, .modal-title-main { position: absolute; left: 0; width: 100%; margin: 0; }
  .modal-kicker {
    --fs: calc(var(--t-kick) * 22.05);
    top: calc(var(--u) * 64.07 - var(--fs) * var(--k-rc));
    font-size: var(--fs);
    text-shadow: 0 0 calc(var(--u) * 8) rgb(60 50 255 / .12);
  }
  .modal-title-main {
    --fs: calc(var(--u) * 47.89);
    top: calc(var(--u) * 125.33 - var(--fs) * var(--k-rc));
    font-size: var(--fs);
    filter: drop-shadow(0 0 calc(var(--u) * 7) rgb(40 30 255 / .2));
    /* a transparent stroke widens the background-clip area: M5 measured the stems 0.55 px narrow at half max */
    -webkit-text-stroke: calc(var(--u) * .4) transparent;
  }

  .modal-label {
    --fs: calc(var(--t-lbl) * 14.92);
    position: absolute;
    left: calc(var(--u) * 51.6);
    top: calc(var(--u) * var(--b) - var(--fs) * var(--k-rc));
    margin: 0;
    font-size: var(--fs);
    line-height: 1;
    white-space: nowrap;
  }
  /* label baselines, 11.9 above each field's top (FONTS "Labels and fields") */
  /* and tracking fitted per label to its mockup ink width (M5; the class's 0.114em ran HOW SOON... 5 px long) */
  .modal-fields > .modal-label:nth-of-type(1) { --b: 188.22; letter-spacing: .0998em; }
  .modal-fields > .modal-label:nth-of-type(2) { --b: 289.12; letter-spacing: .1251em; } /* EMAIL ADDRESS: tracked like WEB ADDRESS */
  .modal-fields > .modal-label:nth-of-type(3) { --b: 389.82; letter-spacing: .1251em; }
  .modal-fields > .modal-label:nth-of-type(4) { --b: 489.99; letter-spacing: .1030em; }
  .modal-fields > .modal-label:nth-of-type(5) { --b: 655.68; letter-spacing: .0883em; }
  /* HOW WOULD YOU LIKE TO START? (not in the mockup): the meeting select sits beside the timeframe, in the right
     column on the timeframe's baseline, tracked like the column's labels */
  .modal-fields > .modal-label:nth-of-type(6) { --b: 655.68; left: calc(var(--u) * 563.66); letter-spacing: .114em; }
  /* the right column (the mockup's styles column, x 562.7, 294.7 wide): PHONE NUMBER and COMPETITORS on the NAME and
     EMAIL baselines, the two-line requirements label on DESCRIPTION's, its lines at the old legend's 24.29 pitch */
  .modal-fields-side > .modal-label { left: calc(var(--u) * 563.66); }
  .modal-fields-side > .modal-label:nth-of-type(n) { letter-spacing: .114em; }
  .modal-fields-side > .modal-label:nth-of-type(3) {
    top: calc(var(--u) * (489.99 - 12.145) - var(--fs) * (var(--k-rc) - .5));
    line-height: calc(var(--u) * 24.29);
  }
  .modal-fields-side > .modal-label span { display: block; }

  .field {
    --ring-w: max(1px, calc(var(--u) * 1.5));
    --fs: calc(var(--t-ph) * 16.27);
    position: absolute;
    left: calc(var(--u) * 50.64);
    top: calc(var(--u) * var(--y));
    width: calc(var(--u) * 432.3);
    height: calc(var(--u) * 49);
    border-radius: calc(var(--u) * 4);
  }
  .field-name    { --y: 200.05; }
  .field-email   { --y: 301.38; } /* ADDRESS's slot (the user replaced ADDRESS with EMAIL ADDRESS) */
  .field-url     { --y: 401.14; }
  .field-desc    { --y: 502.6; height: auto; }
  .field-time    { --y: 667.15; }
  .modal-fields-side > .field { left: calc(var(--u) * 562.7); width: calc(var(--u) * 294.7); }
  .field-phone   { --y: 200.05; }
  .modal-fields > .field-meet { --y: 667.15; left: calc(var(--u) * 562.7); width: calc(var(--u) * 294.7); }
  /* the competitors textarea ends level with WEB ADDRESS's bottom (450.14); the requirements one 39.85 above the
     meeting label's baseline, WEB ADDRESS's bottom-to-DESCRIPTION gap (615.83) */
  .field-rivals  { --y: 301.38; --ta-h: 148.76; height: auto; }
  .field-needs   { --y: 526.18; --ta-h: 89.65; height: auto; }
  /* icons centred 26.46 inside the field's left edge and on its centre line (the textarea's 39.1 below its top) */
  .field-icon {
    left: calc(var(--u) * 14.46);
    top: calc(var(--u) * 12.5);
    width: calc(var(--u) * 24);
    height: calc(var(--u) * 24);
  }
  .field-desc .field-icon,
  .field-area .field-icon { top: calc(var(--u) * 27.1); }
  .field-divider {
    left: calc(var(--u) * 49.66);
    top: calc(var(--u) * 10);
    bottom: calc(var(--u) * 10);
    width: max(1px, var(--u));
  }
  .field-desc .field-divider,
  .field-area .field-divider { top: calc(var(--u) * 10.6); height: calc(var(--u) * 51); }
  /* one line box exactly --fs tall, its baseline 31.1 below the field top; placeholder ink-left 65.8 inside */
  .field input,
  .field select {
    position: absolute;
    inset: 0;
    height: 100%;
    padding: calc(var(--u) * 31.1 - var(--fs) * var(--k-bsc)) calc(var(--u) * 16)
             calc(var(--u) * 17.9 - var(--fs) * (1 - var(--k-bsc))) calc(var(--u) * 65);
    font-size: var(--fs);
  }
  .field select { padding-right: calc(var(--u) * 50); }
  /* the textarea: a 1.6 line pitch, first baseline 30.3 below the top; the right padding puts the text box's right
     edge at mockup x 995, so the placeholder breaks after "and" as drawn (FONTS "Line pitch") */
  .field textarea {
    position: relative;
    height: calc(var(--u) * 113.1);
    min-height: calc(var(--u) * 113.1);
    max-height: calc(var(--u) * 138);
    padding: calc(var(--u) * 30.3 - var(--fs) * (var(--k-bsc) + .3)) calc(var(--u) * 45.3) 0 calc(var(--u) * 65);
    font-size: var(--fs);
  }
  /* the right column's textareas fill their slots, so they do not resize */
  .field-area textarea {
    height: calc(var(--u) * var(--ta-h));
    min-height: calc(var(--u) * var(--ta-h));
    max-height: calc(var(--u) * var(--ta-h));
    resize: none;
  }
  /* the shortened requirements box still shows its placeholder's lines where the 12-px floor binds (below 1510 they
     wrap to three: the first baseline 30.3 down, two 1.6 pitches, a descent) */
  .field-needs textarea {
    height: max(calc(var(--u) * var(--ta-h)), calc(var(--u) * 30.3 + var(--fs) * 3.5));
    min-height: max(calc(var(--u) * var(--ta-h)), calc(var(--u) * 30.3 + var(--fs) * 3.5));
    max-height: max(calc(var(--u) * var(--ta-h)), calc(var(--u) * 30.3 + var(--fs) * 3.5));
  }
  .field-chevron {
    right: auto;
    left: calc(var(--u) * 396.14);
    top: calc(var(--u) * 21.2);
    width: calc(var(--u) * 16);
    height: calc(var(--u) * 9);
  }
  .field-meet .field-chevron { left: calc(var(--u) * 258.54); } /* the same 20.16 inside the narrower field's edge */
  .field-error {
    position: absolute;
    left: 0;
    top: calc(100% + var(--u) * 4);
    margin: 0;
    font-size: max(12px, calc(var(--u) * 14));
    line-height: 1.2;
    white-space: nowrap;
  }

  /* submit [784.00, 892.22, 477.89, 60.85]: label ink-left 51.1 inside, baseline 38.2 below the top; arrow at 435.8 */
  .modal-submit {
    --ring-w: max(1px, calc(var(--u) * 2));
    --fs: calc(var(--t-sub) * 17.61);
    position: absolute;
    left: calc(var(--u) * 226.7);
    top: calc(var(--u) * 757.4);
    display: block;
    width: calc(var(--u) * 477.89);
    height: calc(var(--u) * 60.85);
    min-height: 0;
    padding: calc(var(--u) * 38.2 - var(--fs) * var(--k-rc)) 0
             calc(var(--u) * 22.65 - var(--fs) * (1 - var(--k-rc))) calc(var(--u) * 50.7);
    border-radius: calc(var(--u) * 3);
    font-size: var(--fs);
    line-height: 1;
    text-align: left;
    white-space: nowrap;
  }
  .modal-submit:hover { box-shadow: inset 0 0 calc(var(--u) * 18) rgb(146 70 185 / .35); }
  /* under the submit, across the panel so it stays one line; hung off the panel's bottom edge (the gap under the
     button is ~27px at 900 wide), and specific enough to beat .field-error's top */
  .modal-form .modal-send-error {
    position: absolute;
    left: 0;
    right: 0;
    top: auto;
    bottom: 8px;
    margin: 0;
  }
  .modal-arrow {
    position: absolute;
    left: calc(var(--u) * 435.8);
    top: calc(var(--u) * 25.85);
    width: calc(var(--u) * 21);
    height: calc(var(--u) * 12);
  }

  /* thank-you state: the same heading, then the body and a CLOSE button in the submit's treatment */
  .modal-thanks-body {
    position: absolute;
    left: calc(var(--u) * 184.85);
    top: calc(var(--u) * 250);
    width: calc(var(--u) * 560);
    max-width: none;
    margin: 0;
    font-size: max(12px, calc(var(--u) * 20));
  }
  .modal-done {
    left: calc(var(--u) * 344.85);
    top: calc(var(--u) * 380);
    width: calc(var(--u) * 240);
    padding-left: 0;
    text-align: center;
    text-indent: .183em;
  }

  /* scheduling state: the frame fills the panel between the one-line body and a footer that holds the new-tab
     link, then the CLOSE in the thanks CLOSE's column, hung off the bottom edge */
  .modal-book { position: absolute; inset: 0; }
  .modal-book-body {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(var(--u) * 150);
    max-width: none;
    margin: 0;
    font-size: max(12px, calc(var(--u) * 18));
  }
  .modal-book-frame {
    position: absolute;
    left: calc(var(--u) * 56);
    right: calc(var(--u) * 56);
    top: calc(var(--u) * 196);
    bottom: calc(var(--u) * 92);
    height: auto;
    border-radius: calc(var(--u) * 10);
  }
  .modal-book-alt {
    position: absolute;
    left: 0;
    right: 0;
    bottom: calc(var(--u) * 36);
    margin: 0;
    font-size: max(12px, calc(var(--u) * 16));
  }
  .modal-book .modal-done { top: auto; bottom: calc(var(--u) * 18); margin: 0; }
}

/* 900-1279: the text floors (11 / 12 px) outgrow the mockup boxes below a --u of 0.625 (1280 / 2048): at 900 the
   legend ran 32 px out of the panel, the submit label 60 px into its arrow, HOW SOON... into the card column and
   the textarea placeholder past its box. So --u holds at 0.625 here: the same mockup geometry, at the smallest scale
   that holds the floored text, centred as drawn (its axis 1.9 --u left of the window's). >=1280 is untouched */
@media (min-width: 900px) and (max-width: 1279.98px) {
  .modal-panel {
    --u: 0.625px;
    margin-left: calc(calc(var(--cqw, 1cqw) * 50) - var(--u) * 466.75);
  }
}
/* wherever the 12-px error floor binds (14u < 12px, i.e. below 1755) the floored line is taller than the mockup's gap
   between a field and the next label (about 24u, 15 px at the held 1280 scale): the error tucks up to 1 px under the
   ring on a unit line box, leaving 2-3 clear ink rows above the next label */
@media (min-width: 900px) and (max-width: 1754.98px) {
  .field-error {
    top: calc(100% + 1px);
    line-height: 1;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .modal[open] .modal-panel { animation: modal-in .24s cubic-bezier(.2, .7, .3, 1) both; }
  .modal[open]::backdrop { animation: modal-fade .24s ease-out both; }
}
@keyframes modal-in { from { opacity: 0; transform: translateY(12px) scale(.985); } }
@keyframes modal-fade { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
  }
}

/* ---------- Contact page (screen 7) ---------- */

/* tokens: docs/pws/PALETTE.md "Contact page (screen 7)"; faces, sizes and per-line tracking: docs/pws/FONTS.md
   "Contact page (screen 7)". Everything here is scoped to body.page-contact or to contact-only classes, so screens
   1-6 cannot move. Reused: --ink-blue (lockup, subhead), --body (feature body, chevron), --ink (SEND MESSAGE) */
body.page-contact {
  --field-border:   #93B1D4; /* field frame, top and bottom */
  --field-cyan:     #88BBDC; /* field frame, left edge */
  --field-lavender: #98A2C9; /* field frame, right edge */
  --field-label:    #263851; /* placeholder labels (K5 correction: the 2% core) */
  --send-cyan:      #1CABE1; /* SEND MESSAGE border, left */
  --send-violet:    #8371B9; /* SEND MESSAGE border, middle */
  --send-magenta:   #8C3EA5; /* SEND MESSAGE border, right */
  --divider:        #C8CDD6; /* feature hairlines */
  --feature-title:  #8834A5; /* feature titles */
  --font-lockup: 'Lexend Mega', 'Arial', sans-serif;
  /* where each face's baseline sits below the top of a line-height: 1 box, per em (measured in Chrome at 2048) */
  --k-lekton: .733;
  --k-barlow: .905;
  --k-abel:   .865;
  --k-lexend: .861;
  --k-roboto: .87;
}

/* below 900 (spec D10): one flow in reading order - title, lockup, subhead, side copy, form, features, plate, strip.
   The hero is an inline-size container here, so the lockup and subhead scale with its content width (cqw) */
.contact-title { width: 100%; margin-top: 20px; }
.contact-title img { width: 100%; height: auto; }
.contact-lockup {
  margin-top: 16px;
  font-family: var(--font-lockup);
  color: var(--ink-blue);
  white-space: nowrap;
}
.contact-lockup span { display: block; line-height: 1.6; }
.contact-lockup-1 { padding-left: 1.0144em; font-size: min(44.957px, calc(var(--cqw, 1cqw) * 5.4)); font-weight: 450; letter-spacing: 1.0144em; }
/* both lines keep the mockup's 1.715 size ratio; PENSACOLA binds (its box is 18.3em with the tracking), so the pair
   fits at 5.4cqw / 3.15cqw - 19.3 / 11.3 px at 390 */
.contact-lockup-2 {
  padding-left: 1.7692em;
  font-size: min(26.214px, calc(var(--cqw, 1cqw) * 3.15));
  font-weight: 400;
  letter-spacing: 1.7692em;
  word-spacing: -.312em;
}
.contact-sub {
  margin-top: 16px;
  font-family: var(--font-sub);
  font-size: min(32.1px, calc(var(--cqw, 1cqw) * 6));
  line-height: 1.2;
  letter-spacing: .0967em;
  word-spacing: .018em;
  color: var(--ink-blue);
}

.contact-form, .contact-sent { width: 100%; max-width: 732px; margin-top: 40px; text-align: left; }
.cf-field {
  position: relative;
  margin-bottom: 14px;
  border: 1px solid transparent;
  background:
    linear-gradient(var(--paper), var(--paper)) padding-box,
    linear-gradient(90deg, var(--field-cyan), var(--field-border) 50%, var(--field-lavender)) border-box;
}
.cf-field input,
.cf-field select,
.cf-field textarea {
  display: block;
  width: 100%;
  height: 58px;
  margin: 0;
  padding: 0 20px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--ink-blue);
  font: 400 16.5px/1.3 var(--font-body);
  letter-spacing: .05em;
}
.cf-field textarea { height: 138px; min-height: 96px; padding-top: 22px; resize: vertical; }
.cf-field input::placeholder,
.cf-field textarea::placeholder,
.cf-field select:invalid {
  color: var(--field-label);
  font-family: var(--font-label);
  font-weight: 700;
  font-size: 14.9px;
  letter-spacing: var(--ph-ls, .226em);
  word-spacing: var(--ph-ws, .17em);
  opacity: 1;
}
/* no right padding: Firefox paints a stray pixel of tracked select text just past the content box's inline end
   (K9b; it scales with letter-spacing). With the content box reaching the border box the select's own clip removes
   it. The chevron overlays the right end; the longest option (E-Commerce Store) stays well clear of it */
.cf-field select { -webkit-appearance: none; appearance: none; padding-right: 0; cursor: pointer; }
.cf-field select option { color: var(--ink-blue); background: var(--paper); font: 400 16px var(--font-body); letter-spacing: normal; }
.cf-field select option:disabled { color: var(--body); }
#contact-name    { --ph-ls: .2395em; --ph-ws: .182em; }
#contact-email   { --ph-ls: .2404em; --ph-ws: .183em; }
#contact-type    { --ph-ls: .2183em; --ph-ws: .136em; }
#contact-details { --ph-ls: .2061em; --ph-ws: .171em; }
.cf-chevron {
  position: absolute;
  right: 20px; top: 50%;
  width: 16px; height: 9px;
  margin-top: -4.5px;
  fill: none;
  stroke: var(--body);
  stroke-width: 1.6;
  pointer-events: none;
}
.cf-field.is-invalid {
  background:
    linear-gradient(var(--paper), var(--paper)) padding-box,
    linear-gradient(var(--feature-title), var(--feature-title)) border-box;
}
/* the error sits inside its field's lower edge, under the value, so the mockup's field grid never moves */
.cf-error {
  position: absolute;
  left: 20px; right: 20px; bottom: 5px;
  font: 500 12px/1 var(--font-body);
  letter-spacing: .03em;
  color: var(--feature-title);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
.cf-field input, .cf-field select { padding-bottom: 6px; }
.cf-details textarea { padding-bottom: 22px; }
.cf-hp {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
.cf-send {
  display: block;
  width: 100%;
  height: 58px;
  margin-top: 6px;
  padding: 0 0 0 .4442em;
  border: 2px solid transparent;
  background:
    linear-gradient(var(--paper), var(--paper)) padding-box,
    linear-gradient(90deg, var(--send-cyan), var(--send-violet) 50%, var(--send-magenta)) border-box;
  color: var(--ink);
  font: 500 13.51px/1 var(--font-caps);
  letter-spacing: .4442em;
  word-spacing: .187em;
  cursor: pointer;
  transition: background .2s ease, color .2s ease;
}
.cf-send:hover,
.cf-send:focus-visible {
  background:
    linear-gradient(90deg, rgb(28 171 225 / .12), rgb(131 113 185 / .12), rgb(140 62 165 / .12)) padding-box,
    linear-gradient(var(--paper), var(--paper)) padding-box,
    linear-gradient(90deg, var(--send-cyan), var(--send-violet) 50%, var(--send-magenta)) border-box;
  color: var(--feature-title);
}
.cf-send:disabled { cursor: progress; opacity: .6; }
/* the site's ring (a:focus-visible / button:focus-visible) on every control */
.cf-field input:focus-visible,
.cf-field select:focus-visible,
.cf-field textarea:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 4px;
}
.cf-field input:focus:not(:focus-visible),
.cf-field select:focus:not(:focus-visible),
.cf-field textarea:focus:not(:focus-visible) { outline: none; }
.cf-send-error {
  margin-top: 10px;
  font: 500 15px/1.3 var(--font-body);
  letter-spacing: .03em;
  color: var(--feature-title);
}
/* no-JS path (spec D6): contact.php answers 303 -> #sent or #send-error; :target shows the panel or the line */
.cf-send-error:target { display: block; }
.contact-sent:target { display: flex; }
.contact-sent:target ~ .contact-form { display: none; }
.contact-sent {
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 18px;
  min-height: 220px;
  padding: 24px;
  border: 1px solid transparent;
  background:
    linear-gradient(var(--paper), var(--paper)) padding-box,
    linear-gradient(90deg, var(--field-cyan), var(--field-border) 50%, var(--field-lavender)) border-box;
  text-align: center;
}
.contact-sent:not([hidden]) { display: flex; }
.contact-sent-title {
  padding-left: .29em;
  font: 700 20px/1.2 var(--font-label);
  letter-spacing: .29em;
  color: var(--feature-title);
}
.contact-sent-title:focus { outline: none; }
.contact-sent-title:focus-visible { outline: 2px solid var(--focus); outline-offset: 6px; }
.contact-sent-body {
  font: 400 18px/1.4 var(--font-body);
  letter-spacing: .05em;
  color: var(--body);
  white-space: normal;
}

.contact-features { width: 100%; max-width: 420px; margin-top: 40px; text-align: left; }
.cfeat {
  display: grid;
  grid-template-columns: 64px 1fr;
  column-gap: 26px;
  align-items: start;
  padding: 20px 0;
}
.cfeat + .cfeat { border-top: 1px solid var(--divider); }
.cfeat img { grid-row: 1 / 3; width: 64px; height: auto; }
.cfeat-title {
  font: 700 15px/1.3 var(--font-label);
  letter-spacing: .25em;
  color: var(--feature-title);
  white-space: nowrap;
}
.cfeat-body {
  margin-top: 8px;
  font: 400 16.5px/1.325 var(--font-body);
  letter-spacing: .08em;
  color: var(--body);
}
.cfeat-line { display: block; }

.contact-plate {
  width: 100%;
  height: auto;
  /* the plate's baked paper is #F3F3F3 (the mockup's) against --paper #F5F4F4: its top and bottom edges meet open
     paper, so they fade out over the plate's empty paper margins (the CTA precedent); left and right are page edges */
  -webkit-mask: linear-gradient(transparent, #000 12% 95%, transparent);
  mask: linear-gradient(transparent, #000 12% 95%, transparent);
}

@media (max-width: 899.98px) {
  body.page-contact .hero { container-type: inline-size; }
  .contact-plate { margin-top: 8px; }
}
/* 600-899: name and email share a row; the select, textarea, button and error line span it */
@media (min-width: 600px) and (max-width: 899.98px) {
  .contact-form { display: grid; grid-template-columns: 1fr 1fr; column-gap: 14px; align-items: start; }
  .cf-type, .cf-details, .cf-send, .cf-send-error { grid-column: 1 / -1; }
}

/* desktop: the page is one 2048x1152 stage in mockup px (spec D8: same --u as the home hero, y offset 0) */
@media (min-width: 900px) {
  body.page-contact .stage {
    /* text floors (11 px caps, 12 px body): each --t-* = max(--u, floor / mockup px) */
    --t-cft:  max(var(--u), .733333px); /* 11 / 15.0  titles  */
    --t-clb:  max(var(--u), .738255px); /* 11 / 14.9  labels  */
    --t-csnd: max(var(--u), .814212px); /* 11 / 13.51 SEND MESSAGE */
    --t-cbd:  max(var(--u), .727273px); /* 12 / 16.5  body    */
    /* the feature column on small stages (K9). Its floored text is up to 1.67x the stage scale below 1502, so:
       - --fu, its vertical unit, keeps the text no more than 1.4x the spacing (t-cft / 1.4 = .5238): rows spread
         down from the column's top (y 610, icon 1) instead of the text crowding the dividers (binds below 1073);
       - --fsh shifts the column left until CLEAN & MODERN CODE's right ink (552u + 196.8t) clears the form's left
         edge (868u) by 18 px - 16 plus the glyph's side bearing (binds below ~1045) */
    --fu:  max(var(--u), .523810px);
    --fsh: max(0px, var(--t-cft) * 196.8 - var(--u) * 316 + 18px);
  }

  /* the left column sits ~9 px higher on this mockup than on the home one (FONTS.md): rule 291, line 310,
     PENSACOLA baseline 335.85 (home 344.72), body line 1 401.75 (home 411.33) */
  body.page-contact .intro-rule { top: calc(var(--u) * 291); }
  body.page-contact .intro-line { top: calc(var(--u) * 310); }
  body.page-contact .location { top: calc(var(--u) * 319.07); }
  body.page-contact .tagline { top: calc(var(--u) * 382.62 + var(--d-loc) * 64.26); }

  /* the plate's mockup box [0, 560, 2048, 512], moved down by --plate-dy (checkpoint 1: breathing room under
     SEND MESSAGE); the strip's pieces (z-index 1) stay above its faded lower edge */
  .contact-plate {
    --plate-dy: 12;
    position: absolute;
    z-index: 0;
    left: 0; top: calc(var(--u) * (560 + var(--plate-dy)));
    width: calc(var(--u) * 2048); height: calc(var(--u) * 512);
  }

  /* CONTACT: the file's alpha ink [117,117,2348,364] of 2582x598 on the mockup ink [659,225,770,120] */
  .contact-title { margin: 0; width: auto; position: static !important; }
  .contact-title img {
    position: absolute;
    z-index: 1;
    left: calc(var(--u) * 619.52); top: calc(var(--u) * 186.69);
    width: calc(var(--u) * 848.96);
  }

  /* lockup: each line spans the stage, centred on the axis (checkpoint 1), padded left by its tracking so the
     trailing tracking cancels */
  .contact-lockup { margin: 0; position: static !important; }
  .contact-lockup span {
    position: absolute;
    z-index: 1;
    left: 0;
    width: calc(var(--u) * 2048);
    line-height: 1;
    text-align: center;
  }
  .contact-lockup-1 {
    padding-right: .086em;  /* P's and A's side bearings leave the ink .043em right of the box centre */
    top: calc(var(--u) * (406.84 - 44.957 * var(--k-lexend)));
    font-size: calc(var(--u) * 44.957);
  }
  .contact-lockup-2 {
    top: calc(var(--u) * (457.76 - 26.214 * var(--k-lexend)));
    font-size: calc(var(--u) * 26.214);
  }

  /* subhead: centred on the axis (checkpoint 1; the mockup leans it 26 px right), padded left by its tracking so the
     trailing tracking cancels; baseline 517.25 */
  .contact-sub {
    margin: 0;
    left: 0;
    width: calc(var(--u) * 2048);
    padding-left: .0967em;
    text-align: center;
    top: calc(var(--u) * (517.25 - 32.1 * var(--k-abel)));
    font-size: calc(var(--u) * 32.1);
    line-height: 1;
    white-space: nowrap;
  }

  /* features: every piece at its mockup box in stage coordinates; floored text keeps its baseline. On small stages
     x shifts left by --fsh and y runs in --fu down from the column's top y 610 (see the stage's variables) */
  .contact-features { position: static !important; margin: 0; width: auto; max-width: none; }
  .cfeat { display: block; padding: 0; }
  .cfeat + .cfeat { border: 0; }
  .cfeat img, .cfeat-title, .cfeat-line, .cfeat + .cfeat::before { position: absolute; z-index: 1; }
  .cfeat-body { margin: 0; }
  /* icons: each file's alpha ink box on the mockup's ink box, one scale from the mean of its x and y fits */
  .cfeat img {
    left: calc(var(--u) * var(--ix) - var(--fsh));
    top: calc(var(--u) * 610 + var(--fu) * (var(--iy) - 610));
    width: calc(var(--fu) * var(--iw));
  }
  .cfeat-1 img { --ix: 460.58; --iy: 609.92; --iw: 66.50; }
  .cfeat-2 img { --ix: 461.37; --iy: 727.25; --iw: 62.92; }
  .cfeat-3 img { --ix: 461.05; --iy: 840.54; --iw: 63.39; }
  /* hairlines x 456.8-757.7 at rows 705 and 823.8 (1 mockup px, a little over); the right end keeps its 8.9 lead
     over title 3's right ink as the floored text widens */
  .cfeat + .cfeat::before {
    content: "";
    left: calc(var(--u) * 456.8 - var(--fsh));
    top: calc(var(--u) * 610 + var(--fu) * (var(--dy) - 610));
    width: calc(var(--u) * 104.1 + var(--t-cft) * 196.8);
    height: max(1px, calc(var(--u) * 1.15));
    background: var(--divider);
  }
  .cfeat-2::before { --dy: 704.95; }
  .cfeat-3::before { --dy: 823.9; }
  .cfeat-title {
    left: calc(var(--u) * var(--x) - var(--fsh));
    top: calc(var(--u) * 610 + var(--fu) * (var(--tb) - 610) - var(--t-cft) * 15 * var(--k-lekton));
    font-size: calc(var(--t-cft) * 15);
    line-height: 1;
  }
  .cfeat-1 { --tb: 626.83; }
  .cfeat-2 { --tb: 744.04; }
  .cfeat-3 { --tb: 858.08; }
  .cfeat-1 .cfeat-title { --x: 553.26; letter-spacing: .2895em; word-spacing: .194em; }
  .cfeat-2 .cfeat-title { --x: 552.17; letter-spacing: .2610em; word-spacing: .014em; }
  .cfeat-3 .cfeat-title { --x: 551.96; letter-spacing: .1950em; word-spacing: .047em; }
  /* body line 1 sits --df below its title's baseline in column units; line 2 hangs --dt below line 1 in body units,
     so floored lines keep their pitch */
  .cfeat-line {
    left: calc(var(--u) * var(--x) - var(--fsh));
    top: calc(var(--u) * 610 + var(--fu) * (var(--tb) + var(--df) - 610) + var(--t-cbd) * (var(--dt, 0) - 16.5 * var(--k-barlow)));
    font-size: calc(var(--t-cbd) * 16.5);
    line-height: 1;
    white-space: nowrap;
  }
  .cfeat-1 .cfeat-line { --df: 32.09; }
  .cfeat-2 .cfeat-line { --df: 33.36; }
  .cfeat-3 .cfeat-line { --df: 33.85; }
  .cfeat-1 .cfeat-line:first-child { --x: 553.61; letter-spacing: .0545em; word-spacing: .052em; }
  .cfeat-1 .cfeat-line:last-child  { --x: 553.75; --dt: 21.78; letter-spacing: .0673em; word-spacing: .072em; }
  .cfeat-2 .cfeat-line:first-child { --x: 551.80; letter-spacing: .0844em; word-spacing: .088em; }
  .cfeat-2 .cfeat-line:last-child  { --x: 551.92; --dt: 21.53; letter-spacing: .0832em; word-spacing: .047em; }
  .cfeat-3 .cfeat-line:first-child { --x: 551.80; letter-spacing: .0960em; word-spacing: .066em; }
  .cfeat-3 .cfeat-line:last-child  { --x: 551.86; --dt: 22.29; letter-spacing: .0942em; word-spacing: .052em; }

  /* form: outer box [868.1, 584.8, 731.9, 378.2] (field frames' 1 px lines at 868.3 / 1598.8, 585.3 / 962);
     each part in form-relative mockup px */
  .contact-form, .contact-sent {
    margin: 0;
    left: calc(var(--u) * 868.1); top: calc(var(--u) * 584.8);
    width: calc(var(--u) * 731.9); max-width: none;
  }
  .contact-form { height: calc(var(--u) * 378.2); }
  .cf-field, .cf-send { position: absolute; margin: 0; }
  .cf-field { border-width: 1px; }
  .cf-name    { left: 0;                       top: 0;                        width: calc(var(--u) * 376.4); }
  .cf-email   { left: calc(var(--u) * 388.6);  top: 0;                        width: calc(var(--u) * 343.3); }
  .cf-type    { left: 0;                       top: calc(var(--u) * 79.9);    width: 100%; }
  .cf-details { left: 0;                       top: calc(var(--u) * 155.3);   width: 100%; }
  /* control height = the frame's outer height less its two 1 px borders */
  .cf-name input, .cf-email input { height: calc(var(--u) * 66.8 - 2px); }
  .cf-type select { height: calc(var(--u) * 62.1 - 2px); }
  .cf-details textarea { height: calc(var(--u) * 138.8 - 2px); min-height: calc(var(--u) * 138.8 - 2px); resize: none; }
  .cf-field input,
  .cf-field select,
  .cf-field textarea {
    padding: 0 calc(var(--u) * 24) 0 calc(var(--u) * var(--px) - 1px);
    font-size: calc(var(--t-cbd) * 16.5);
  }
  .cf-field input::placeholder,
  .cf-field textarea::placeholder,
  .cf-field select:invalid { font-size: calc(var(--t-clb) * 14.9); }
  /* text origin = mockup ink-left - render ink-left, from the field's outer left edge */
  .cf-name    { --px: 30.81; }
  .cf-email   { --px: 31.06; }
  .cf-type    { --px: 29.50; }
  .cf-details { --px: 30.46; }
  .cf-details textarea { padding-top: calc(var(--u) * 24.1); line-height: calc(var(--t-cbd) * 21.87); }
  /* chevron ink [1564,694,15,8], stroke ~1.6 */
  .cf-chevron {
    right: auto; left: calc(var(--u) * 695.2);
    top: calc(var(--u) * 28.2); margin: 0;
    width: calc(var(--u) * 16); height: calc(var(--u) * 9);
  }
  .cf-error {
    left: calc(var(--u) * var(--px) - 1px); right: calc(var(--u) * 24);
    bottom: calc(var(--u) * 5);
    font-size: max(12px, calc(var(--u) * 12.5));
  }
  /* the select is too short for a second line under its label: its error sits right, before the chevron, on the
     label's line */
  .cf-type .cf-error {
    left: auto; right: calc(var(--u) * 60);
    top: calc(var(--u) * 27.6); bottom: auto;
    text-align: right;
  }
  /* inputs and the select centre their line, so padding moves it by half (to the mockup baselines 623.42 / 623.72
     / 703.61) */
  .cf-name input, .cf-email input { padding-bottom: calc(var(--u) * 4.6); }
  .cf-type select { padding-top: calc(var(--u) * 7.4); padding-right: 0; padding-bottom: 0; }
  .cf-details textarea { padding-bottom: calc(var(--u) * 22); }

  /* SEND MESSAGE: box [868, 898, 731.5, 65], 2 px frame; label ink-left 1137.28 (centre 1214.42, 19.3 left of the
     button's centre in the mockup; centred at checkpoint 1), baseline 937.49 */
  .cf-send {
    left: calc(var(--u) * -.1); top: calc(var(--u) * 313.2);
    width: calc(var(--u) * 732.6); height: calc(var(--u) * 65);
    /* a button centres its line, so the top padding moves it down by half, to the baseline 37.49 */
    padding: calc(var(--u) * 5.5) .09em 0 .4442em;  /* the right .09em cancels a .045em ink lean */
    border-width: calc(var(--u) * 2);
    font-size: calc(var(--t-csnd) * 13.51);
    text-align: center;
  }
  /* below the button, over the plate's band: on a paper chip so the mosaic does not cross the words */
  .cf-send-error {
    position: absolute;
    left: 0; top: calc(var(--u) * 386);
    margin: 0;
    padding: calc(var(--u) * 5) calc(var(--u) * 10);
    background: var(--paper);
    font-size: max(12px, calc(var(--u) * 15));
    white-space: nowrap;
  }

  .contact-sent { height: calc(var(--u) * 378.2); min-height: 0; gap: calc(var(--u) * 22); padding: calc(var(--u) * 24); }
  .contact-sent-title { font-size: max(14px, calc(var(--u) * 24)); }
  .contact-sent-body { font-size: max(12px, calc(var(--u) * 18)); }
}

/* ---------- About page (screen 8a) ---------- */

/* spec docs/superpowers/specs/2026-09-28-pws-about-page-design.md; tokens and faces: docs/pws/REPORT-N4.md. Everything
   here is scoped to body.page-about or to about-only classes, so screens 1-7 cannot move. Reused as-is: Contact's
   lockup and subhead classes (.contact-lockup, .contact-sub, re-placed below), --ink-blue (story, subhead, side copy) */
body.page-about {
  --about-kicker:       #831799; /* WHY WE EXIST (7.51:1 on --paper) */
  --about-rule-cyan:    #39D2F2; /* kicker rule, left end */
  --about-rule-blue:    #36B1ED; /* kicker rule, to ~40% */
  --about-rule-violet:  #9042C3; /* kicker rule, from ~44% */
  --about-rule-magenta: #9C36B6; /* kicker rule, right end */
  --font-lockup: 'Lexend Mega', 'Arial', sans-serif;
  --k-lekton: .733;
  --k-abel:   .865;
  --k-lexend: .861;
}

/* below 900: one flow in reading order (N7 finishes this band; nothing here may overflow at 390) */
.about-title { width: 100%; margin-top: 20px; }
.about-title img { width: 100%; height: auto; }
.about-story { width: 100%; max-width: 36em; margin-top: 40px; text-align: left; }
/* a block sized to its text (not inline-block, so no strut from the story's own line box) */
.about-kicker {
  position: relative;
  width: fit-content;
  padding-bottom: 14px;
  font: 700 15px/1 var(--font-label);
  letter-spacing: .5em;
  color: var(--about-kicker);
}
/* the rule: cyan -> blue to ~40%, a short blend to violet by ~44%, violet -> magenta to the end (REPORT-N4 stops) */
.about-kicker::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 3px;
  background: linear-gradient(90deg,
    var(--about-rule-cyan) 3%, var(--about-rule-blue) 25%, var(--about-rule-blue) 40%,
    var(--about-rule-violet) 44%, var(--about-rule-violet) 50%, var(--about-rule-magenta) 97%);
}
.about-cols { margin-top: 24px; }
.about-p {
  font: 400 16px/1.6 var(--font-caps);
  letter-spacing: .06em;
  color: var(--ink-blue);
}
.about-p + .about-p, .about-col + .about-col { margin-top: 1em; }
.about-p strong { font-weight: 700; }
.about-knockout { display: none; }
/* the building art is two images cut from A37 (split after merge, pipeline/work/A37-split.py): about-building-left
   (718x1278) and about-building-right (797x1192), their baked paper lifted to --paper. Below 900 only the left one
   shows, whole (never cropped), flush to the page's left edge with paper to its right. Its left edge is the art's page
   edge; the other three meet open paper and fade into it */
.about-plates { display: block; }
.about-plate-r { display: none; }
.about-plate {
  width: min(62vw, 360px);
  height: auto;
  aspect-ratio: 718 / 1278;
  margin-top: 8px;
  /* the crop's lowest ~15% is empty paper and faint topo: the strip moves up over it */
  margin-bottom: calc(min(62vw, 360px) * -.25);
  -webkit-mask: linear-gradient(90deg, #000 90%, transparent), linear-gradient(transparent, #000 6% 92%, transparent);
  -webkit-mask-composite: source-in;
  mask: linear-gradient(90deg, #000 90%, transparent), linear-gradient(transparent, #000 6% 92%, transparent);
  mask-composite: intersect;
}

@media (max-width: 899.98px) {
  body.page-about .hero { container-type: inline-size; }
  /* lockup: the mockup's 1em / 1.77em tracking scattered the letters at phone size, so both lines are set larger and
     tighter, line 2 tracked to end flush with line 1 (ink 'PENSACOLA' 7.9em, 'WEB STUDIO' 8.4em less the word-space
     trim); each is padded left by its tracking so the trailing tracking cancels */
  body.page-about .contact-lockup-1 { padding-left: .3em; font-size: min(40px, calc(var(--cqw, 1cqw) * 8.4)); font-weight: 500; letter-spacing: .3em; }
  body.page-about .contact-lockup-2 {
    margin-top: .15em;
    padding-left: 1.09em;
    font-size: min(23px, calc(var(--cqw, 1cqw) * 4.8));
    letter-spacing: 1.09em;
  }
}

/* desktop: one stage in mockup px (spec D6: the home hero's --u, y offset 0). The frame is a min-height: the story
   stays in flow, so where the 14 px floor (Q5) makes it wrap to more lines the stage grows */
@media (min-width: 900px) {
  body.page-about .stage {
    /* About content floors (Q5: 14 px): each --t-* = max(--u, 14 / mockup px) */
    --t-asb: max(var(--u), .436137px); /* 14 / 32.1  subhead   */
    --t-akk: max(var(--u), .795455px); /* 14 / 17.6  kicker    */
    --t-ast: max(var(--u), .673077px); /* 14 / 20.8  story     */
    height: auto;
    min-height: calc(var(--u) * 1152);
  }



  /* ABOUT: the file's alpha ink [8,7,2384,508] of 2400x523 on the mockup ink [664,222,758,158]. The asset is 2.2%
     taller for its width than the mockup's word, so x and y scale separately (.31795 / .31102): one mean scale left
     every ink edge 4-5 px off */
  .about-title { margin: 0; width: auto; position: static !important; }
  .about-title img {
    position: absolute;
    z-index: 1;
    left: calc(var(--u) * 661.46); top: calc(var(--u) * 219.82);
    width: calc(var(--u) * 763.08); height: calc(var(--u) * 162.66);
  }

  /* lockup and subhead: Contact's, 33 / 31 / 27 px lower (baselines 439.84, 488.76, 544.25), still centred */
  body.page-about .contact-lockup-1 { top: calc(var(--u) * (440.84 - 44.957 * var(--k-lexend))); }
  body.page-about .contact-lockup-2 { top: calc(var(--u) * (490.26 - 26.214 * var(--k-lexend))); }
  body.page-about .contact-sub {
    top: calc(var(--u) * 544.25 - var(--t-asb) * 32.1 * var(--k-abel));
    padding-left: .01em;
    font-size: calc(var(--t-asb) * 32.1);
    letter-spacing: .01em;  /* the mockup sets this line far tighter than Contact's (.0967em): 858 px of ink */
  }

  /* story: the only in-flow content. The hero's top padding puts the kicker's line box at y 597.1 (cap top 598) */
  body.page-about .hero { padding-top: calc(var(--u) * 597.1); }
  body.page-about .about-story {
    position: relative;
    z-index: 1;
    width: calc(var(--u) * 950);
    max-width: none;
    margin: 0 0 0 calc(var(--u) * 564);
    /* clear of the strip, whose pieces grow upward from the stage's bottom: 16 px (24 at 2048) above the services row
       under the story (top 55.45u up), and never below the scroll cue's top (68.76u + 45.24 t-scr up). Both leave
       the frame at 1152 wherever the story itself is not floored (1440x810 included) */
    padding-bottom: max(calc(var(--u) * 55.45 + max(16px, var(--u) * 24)),
                        calc(var(--u) * 68.76 + var(--t-scr) * 45.24 + 4px));
  }
  body.page-about .about-kicker {
    padding: 0;
    font-size: calc(var(--t-akk) * 17.6);
    letter-spacing: .40em;
  }
  body.page-about .about-kicker::after {
    left: calc(var(--u) * -1);
    top: calc(100% + var(--t-akk) * 13.3);
    bottom: auto;
    width: calc(var(--t-akk) * 187);
    height: calc(var(--u) * 3);
  }
  body.page-about .about-cols {
    display: grid;
    /* each column's measure (with the paragraph's tracking below) reproduces the mockup's line breaks at 2048 for
       paragraphs 2 and 3: column 1 binds in [422.3, 426.4), column 2 in [404.2, 407.3). Paragraph 1 cannot follow
       the mockup at any single tracking (its line 3 is set ~36 px looser than line 1), so "you" joins line 3 */
    grid-template-columns: calc(var(--u) * 424.4) calc(var(--u) * 405.8);
    column-gap: calc(var(--u) * 79.6);
    align-items: start;
    margin-top: calc(var(--t-akk) * 37.3 + var(--u));
  }
  body.page-about .about-col + .about-col { margin: calc(var(--u) * -1) 0 0; }
  body.page-about .about-p { font-size: calc(var(--t-ast) * 20.8); letter-spacing: .065em; word-spacing: .10em; }
  body.page-about .about-p1 { line-height: calc(var(--t-ast) * 27.33); letter-spacing: .064em; word-spacing: 0; }
  /* the mockup indents paragraph 2 by 3 px: a shift, so the column's measure (and its line breaks) stay */
  body.page-about .about-p2 {
    position: relative;
    left: calc(var(--u) * 3);
    margin-top: calc(var(--t-ast) * 17);
    line-height: calc(var(--t-ast) * 26);
  }
  body.page-about .about-p3 { line-height: calc(var(--t-ast) * 32.8); letter-spacing: .075em; }
  /* the mockup's bold is heavier than Roboto Condensed 700 (stem 4 vs 3, REPORT-N4) and sets 23 px wider over line 1 */
  body.page-about .about-p3 strong { letter-spacing: .108em; }

  /* the plate: full frame [0,0,2048,1152] under everything. Its baked paper is ~#F0F0EF against --paper #F5F4F4: its
     lower edge fades out, so where the floor makes the stage taller than the plate no seam shows */
  /* checkpoint 2: the buildings sit at the BOTTOM of the frame, 120 mockup px lower than the mockup, and follow the
     frame's bottom edge when the floor makes it taller. The element is the plate's top 1032 rows (object-fit crops the
     rest, so nothing overflows the stage), its bottom on the stage's bottom. Plate row p lands at stage row p + 120 at
     1152: the art fades out over plate rows 830-915 (80.4%-88.7% of the element), i.e. by stage row 1035, the strip's
     top, so the strip stays on paper. The top 25% (plate rows 0-258, above the first building pixels at ~330) fades in so the plate paper (~#F0F0EF, 4 levels darker) meets --paper without a visible band; 8% showed one */
  /* split plate: each building is its own image at the exact place the full-frame plate put it (plate row p at stage
     row p + 120 at 1152, x unchanged), anchored to the stage's bottom so both follow a taller frame. In mockup px
     (plate px / 1.875): left [0,326.4,382.93,681.6] -> bottom 24; right [1622.93,394.13,425.07,635.73] -> bottom 2.13,
     right 0. The fade-out band is the old one, plate rows 829.7-915.4 (the strip's top at 1152): 73.84%-86.41% of the
     left image, 68.51%-82% of the right. The inner and top edges are 4% paper pad and fade into --paper */
  body.page-about .about-plate {
    display: block;
    position: absolute;
    z-index: 0;
    top: auto;
    aspect-ratio: auto;
    margin: 0;
  }
  body.page-about .about-plate-l {
    left: 0; bottom: calc(var(--u) * 24);
    width: calc(var(--u) * 382.93); height: calc(var(--u) * 681.6);
    -webkit-mask: linear-gradient(90deg, #000 96%, transparent), linear-gradient(transparent, #000 3.5% 73.84%, transparent 86.41%);
    mask: linear-gradient(90deg, #000 96%, transparent), linear-gradient(transparent, #000 3.5% 73.84%, transparent 86.41%);
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
  }
  body.page-about .about-plate-r {
    right: 0; bottom: calc(var(--u) * 2.13);
    width: calc(var(--u) * 425.07); height: calc(var(--u) * 635.73);
    -webkit-mask: linear-gradient(90deg, transparent, #000 4%), linear-gradient(transparent, #000 3.5% 68.51%, transparent 82%);
    mask: linear-gradient(90deg, transparent, #000 4%), linear-gradient(transparent, #000 3.5% 68.51%, transparent 82%);
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
  }

  /* spec D5: a paper backing behind the reused vertical text, where it crosses the right building. The mockup's strip
     is [1952,490,62,215] (~90% paper; the art shows faintly through) around its text; this one keeps that width and
     the mockup's ~5 px margin around the home-position text (x 1963, y 556, 12.2 x 226.8 at the text scale) */
  body.page-about .about-knockout {
    display: block;
    left: calc(var(--u) * (1963 - 31) + var(--t-vert) * 6.1);
    top: calc(var(--u) * (556 - 5));
    width: calc(var(--u) * 62);
    height: calc(var(--t-vert) * 226.8 + var(--u) * 10);
    background: rgb(245 244 244 / .9);
  }
}

/* ---------- About section 2, LOOK AROUND (screen 8b) ---------- */

/* spec docs/superpowers/specs/2026-09-28-pws-about-look-around-design.md; tokens and faces: docs/pws/REPORT-L4.md.
   Mockup pensacola-web-studio-about-2.png rows 130-1110 are the section's frame (y_section = y_mockup - 130); every
   box below is an ink scan of that mockup. All of it is scoped to body.page-about / look-* classes */
body.page-about {
  --look-title:   #751174; /* feature and local titles (9.0:1 on --paper) */
  --look-x:       #812881; /* the list's crosses (7.5:1) */
  --look-divider: #CDD5E0; /* list hairlines, row 372 */
  --look-vdiv:    #BCC9D4; /* feature dividers, x 724-725 */
  --look-side:    #73A9D1; /* side rules x 55 / 1994-1995: one flat blue top to bottom */
  --look-ring-l:  #B07AB4; /* cross ring, sampled on the ring alone (left / right of six rings) */
  --look-ring-r:  #A26AA6;
  --look-rule-cyan:    #10B5F2; /* local rule stops, left to right */
  --look-rule-cyan-2:  #0AA2E6;
  --look-rule-blue:    #3756CC;
  --look-rule-violet:  #7A2DB2;
  --look-rule-magenta: #951598;
}

/* below 900: one flow in reading order (spec D8), on section 1's mobile rhythm (REPORT-N7): 16 px gutters, the
   story's 16 px Roboto Condensed body, the kicker's 15 px Lekton titles. Mosaic and side rules are desktop only */
.about-look { position: relative; padding: 40px 16px 56px; color: var(--ink-blue); font-family: var(--font-caps); }
.about-look h3 { margin: 0; }
.look-rule, .look-mosaic { display: none; }
.look-upper { display: flex; flex-direction: column; }
.look-title { margin: 0; }
.look-title img { width: 100%; height: auto; }
/* the file's ink is [116,12,2318,233] of 2551x258. Below 900 the letters span the column gutter to gutter: the img box
   IS the column (width 100%, the ink's aspect incl. its 12/13 px vertical pad = 2318:258), and object-fit: cover scales
   the file to that height, so its drawn width is 2551/2318 of the box and the centred overflow crops exactly the two
   ~116 px transparent side pads. The box never leaves the column (an earlier negative-margin version put the img's
   box at x -2 at 390, failing no-offscreen-left, although the overflow was clipped) */
@media (max-width: 899.98px) {
  .look-title img { width: 100%; height: auto; aspect-ratio: 2318 / 258; object-fit: cover; object-position: 50% 50%; }
}
.look-sub { margin-top: 14px; font-size: 17px; line-height: 1.35; letter-spacing: .05em; }
.look-list { margin-top: 20px; }
.look-list li {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 56px;
  padding: 8px 0;
  border-bottom: 1px solid var(--look-divider);
  font-size: 16px;
  line-height: 1.35;
  letter-spacing: .06em;
}
.look-list li:last-child { border-bottom: 0; }
.look-x { flex: none; width: 36px; height: 36px; overflow: visible; }
.look-x circle { fill: none; stroke-width: 1.4; }
.look-x path { fill: none; stroke: var(--look-x); stroke-width: 1.6; stroke-linecap: round; }
/* the art runs the full page width (its 4% paper pad is the inset), whole, its edges faded into the paper as at
   >= 900 */
.look-art {
  width: calc(100% + 32px);
  max-width: none;
  height: auto;
  margin: 28px -16px 0;
  -webkit-mask: linear-gradient(90deg, transparent, #000 2% 98%, transparent), linear-gradient(transparent, #000 3% 97%, transparent);
  -webkit-mask-composite: source-in;
  mask: linear-gradient(90deg, transparent, #000 2% 98%, transparent), linear-gradient(transparent, #000 3% 97%, transparent);
  mask-composite: intersect;
}
.look-pivot { margin-top: 8px; font-size: 24px; line-height: 1.25; letter-spacing: .04em; }
.look-pivot span, .look-fbody span, .look-closing span { display: block; }
.look-features { display: grid; gap: 28px; margin-top: 48px; }
.look-feature {
  display: grid;
  grid-template-columns: 72px 1fr;
  column-gap: 18px;
  align-items: start;
}
.look-icon { grid-row: 1 / span 2; width: 72px; height: auto; }
.look-h {
  font: 700 15px/1.3 var(--font-label);
  letter-spacing: .3em;
  color: var(--look-title);
}
.look-fbody { margin-top: 6px; font-size: 16px; line-height: 1.45; letter-spacing: .05em; }
.look-lower { margin-top: 48px; }
.look-local-title { position: relative; padding-bottom: 16px; }
.look-local-title::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 125px; height: 3px;
  /* sampled on the mockup's rule [167,976.5,132,2.5]: cyan to a faint joint at ~46%, then blue-violet to magenta */
  background: linear-gradient(90deg,
    var(--look-rule-cyan) 0 28%, var(--look-rule-cyan-2) 45%,
    var(--look-rule-blue) 48%, var(--look-rule-violet) 76%, var(--look-rule-magenta) 100%);
}
.look-local-body { max-width: 36em; margin-top: 16px; font-size: 16px; line-height: 1.6; letter-spacing: .05em; }
.look-close { margin-top: 48px; }
.look-closing { font-size: 26px; line-height: 1.25; letter-spacing: .03em; }
.look-cta {
  display: block;
  width: 100%;
  max-width: 340px;
  min-height: 52px;
  margin-top: 20px;
  padding: 0 1em;
  font-size: 15px;
  letter-spacing: .3em;
  cursor: pointer;
}
.look-cta-underline {
  display: block;
  width: 116px; height: 2px;
  margin-top: 10px;
  background: linear-gradient(90deg,
    var(--grad-cyan) 0 8%, #8D4ADF 12%, var(--grad-magenta) 19.2%, transparent 19.2% 23.2%,
    var(--grad-cyan) 23.2% 57.6%, transparent 57.6% 59%, #6E33B8 59%, #86258F 100%);
}

/* desktop: the section is its own frame on the stage's units (spec D6: --u = the page width / 2048). Only the list,
   the features and the lower block are in flow, so where the 14 px floor (Q5) wraps a line the section grows (its
   980u is a min-height) and everything below moves down with it. The title, subhead, art and pivot are placed on the
   frame: none of them can grow into the flow (the subhead's baseline is pinned; the pivot never floors at >= 900) */
@media (min-width: 900px) {
  body.page-about .about-look {
    --u: calc(calc(var(--cqw, 1cqw) * 100) / 2048);
    /* Q5 floors: each --t-* = max(--u, 14 / mockup px) */
    --t-lsb: max(var(--u), .583333px); /* 14 / 24    subhead       */
    --t-lli: max(var(--u), .636364px); /* 14 / 22    list          */
    --t-lfh: max(var(--u), .600858px); /* 14 / 23.3  titles        */
    --t-lfb: max(var(--u), .7px);      /* 14 / 20    feature body  */
    --t-llb: max(var(--u), .7px);      /* 14 / 20    local body    */
    --t-lbt: max(var(--u), .583333px); /* 14 / 24    button        */
    width: calc(var(--u) * 2048);
    min-height: calc(var(--u) * 980);
    padding: calc(var(--u) * 122.8) 0 calc(var(--u) * 6);
  }
  body.page-about .about-look > * { position: relative; z-index: 1; }

  /* side rules: mockup x 55 and 1994-1995, rows 148-1109 (1.5 px of flat blue), following a taller frame */
  body.page-about .look-rule {
    display: block;
    position: absolute;
    z-index: 2;
    top: calc(var(--u) * 18); bottom: calc(var(--u) * 1);
    width: calc(var(--u) * 1.5);
    background: var(--look-side);
  }
  body.page-about .look-rule-l { left: calc(var(--u) * 54.5); }
  body.page-about .look-rule-r { left: calc(var(--u) * 1994.25); }

  /* the mosaic (A40, 1428x3310, paper lifted to --paper): registered on the mockup's cloud (side rule masked;
     normalised cross-correlation .929) at one scale, .155, flush to the page's right edge from row 154. Its right
     edge is the art's page edge; the other three meet open paper and fade into it. The right side rule crosses it */
  body.page-about .look-mosaic {
    display: block;
    position: absolute;
    z-index: 0;
    right: 0; top: calc(var(--u) * 24);
    width: calc(var(--u) * 221.3); height: calc(var(--u) * 513.1);
    -webkit-mask: linear-gradient(90deg, transparent, #000 8%), linear-gradient(transparent, #000 4% 94%, transparent);
    -webkit-mask-composite: source-in;
    mask: linear-gradient(90deg, transparent, #000 8%), linear-gradient(transparent, #000 4% 94%, transparent);
    mask-composite: intersect;
  }

  body.page-about .look-upper { display: block; position: static; }

  /* LOOK AROUND: the file's alpha ink [116,12,2318,233] of 2551x258 on the mockup ink [154,166,702,69]. The asset
     is 2.6% taller for its width than the mockup's words, so x and y scale separately (.302847 / .296137), as ABOUT */
  body.page-about .look-title img {
    position: absolute;
    z-index: 1;
    left: calc(var(--u) * 118.87); top: calc(var(--u) * 32.45);
    width: calc(var(--u) * 772.56); height: calc(var(--u) * 76.40);
  }

  /* subhead: ink-left 157, baseline 275 (section 145). In flow, so where the floor wraps it (it stops short of the
     art's mosaic) the list moves down */
  body.page-about .look-sub {
    position: relative;
    z-index: 1;
    max-width: calc(var(--u) * 680);
    margin: 0 0 0 calc(var(--u) * 155);
    font-size: calc(var(--t-lsb) * 24);
    line-height: calc(var(--t-lsb) * 30);
    letter-spacing: .048em;
  }

  /* list: rows 66 apart from 306 (dividers at 372 ... 636, x 156-784), the ring centred on x 180 */
  body.page-about .look-list { margin: calc(var(--u) * 23.2) 0 0 calc(var(--u) * 156); width: calc(var(--u) * 628); }
  body.page-about .look-list li {
    gap: 0;
    min-height: calc(var(--u) * 66);
    padding: calc(var(--u) * 3) 0 0 calc(var(--u) * 2);
    font-size: calc(var(--t-lli) * 22);
    line-height: 1.25;
    letter-spacing: .043em;
  }
  /* the text may run past the dividers' right end (row 1's ink ends at 782), never under the art (x 844) */
  body.page-about .look-item { flex: none; max-width: calc(var(--u) * 600); }
  /* the ring sits ~2 px above its row's text centre */
  body.page-about .look-x {
    width: calc(var(--u) * 44); height: calc(var(--u) * 44);
    margin: calc(var(--u) * -5) calc(var(--u) * 27) 0 0;
  }

  /* the art (A39, 3840x1951, its paper lifted to --paper): registered on the mockup's browser, phone and mosaic
     (rows 150-555, normalised cross-correlation .833) at x .2575 / y .2455. The file is ~5% taller for its width
     than the mockup's drawing (it was generated 16:9 from a 2.07:1 crop), so the two axes scale separately. Its
     4% paper pad fades out at every edge, so no seam can show where it meets the page's paper */
  body.page-about .look-art {
    position: absolute;
    z-index: 0;
    left: calc(var(--u) * 839.5); top: calc(var(--u) * 5.5);
    width: calc(var(--u) * 988.8); height: calc(var(--u) * 479);
    margin: 0;
    -webkit-mask: linear-gradient(90deg, transparent, #000 2% 98%, transparent), linear-gradient(transparent, #000 3% 97%, transparent);
    -webkit-mask-composite: source-in;
    mask: linear-gradient(90deg, transparent, #000 2% 98%, transparent), linear-gradient(transparent, #000 3% 97%, transparent);
    mask-composite: intersect;
  }

  /* pivot: three lines, ink-left 961, baselines 592 / 639 / 686 (section 462 / 509 / 556) */
  body.page-about .look-pivot {
    position: absolute;
    z-index: 1;
    left: calc(var(--u) * 960);
    top: calc(var(--u) * 464 - 41.5 * var(--u) * .95);
    margin: 0;
    font-size: max(14px, calc(var(--u) * 41.5));
    line-height: calc(var(--u) * 47);
    letter-spacing: .024em;
    white-space: nowrap;
  }
  body.page-about .look-pivot span:last-child { letter-spacing: .003em; }

  /* features: circles at x 161 / 778 / 1349 from row 744, titles cap-top 770, bodies baselines 823 / 854; dividers
     x 724-725 rows 747-868 and x 1291-1292 rows 747-859 */
  body.page-about .look-features {
    display: grid;
    grid-template-columns: calc(var(--u) * 568) calc(var(--u) * 567) 1fr;
    gap: 0;
    margin: calc(var(--u) * 42) calc(var(--u) * 73) 0 calc(var(--u) * 156);
  }
  body.page-about .look-feature {
    display: block;
    position: relative;
    min-height: calc(var(--u) * 125);
    padding: calc(var(--u) * 24) calc(var(--u) * 20) 0 var(--tx);
  }
  body.page-about .look-feature + .look-feature::before {
    content: "";
    position: absolute;
    left: 0; top: calc(var(--u) * 3);
    width: calc(var(--u) * 2); height: calc(var(--u) * 121);
    background: var(--look-vdiv);
  }
  /* icons: each file's ring (alpha ink of 400 x 411 / 402 / 408) at one scale, its width and centre on the mockup's
     ring ([161,744,114,125], [778,744,115,125], [1349,745,117,125]). The mockup draws the rings ~9% taller than wide;
     the files' rings are round, so each sits 3-5 px short of the mockup's top and bottom */
  body.page-about .look-feature-1 { --tx: calc(var(--u) * 157); }
  body.page-about .look-feature-2 { --tx: calc(var(--u) * 206); }
  body.page-about .look-feature-3 { --tx: calc(var(--u) * 218); }
  body.page-about .look-icon { position: absolute; }
  body.page-about .look-feature-1 .look-icon {
    left: calc(var(--u) * 3.24); top: calc(var(--u) * 1.98);
    width: calc(var(--u) * 117.53); height: calc(var(--u) * 120.76);
  }
  body.page-about .look-feature-2 .look-icon {
    left: calc(var(--u) * 52.52); top: calc(var(--u) * 3.08);
    width: calc(var(--u) * 118.25); height: calc(var(--u) * 118.84);
  }
  body.page-about .look-feature-3 .look-icon {
    left: calc(var(--u) * 56.5); top: calc(var(--u) * 2.3);
    width: calc(var(--u) * 120); height: calc(var(--u) * 122.4);
  }
  body.page-about .look-h {
    font-size: calc(var(--t-lfh) * 23.3);
    line-height: 1;
    letter-spacing: .163em;
  }
  body.page-about .look-feature-2 .look-h { letter-spacing: .18em; }
  body.page-about .look-feature-3 .look-h { letter-spacing: .194em; }
  body.page-about .look-fbody {
    margin-top: calc(var(--u) * 11);
    font-size: calc(var(--t-lfb) * 20);
    line-height: calc(var(--t-lfb) * 31);
    letter-spacing: .11em;
  }

  /* lower: local title cap-top 942 at x 167, rule [167,976.5,132,2.5], body baselines 1021 / 1052 / 1083; closing
     baselines 960 / 1009 at x 1117, button [1117,1030,405,61], accents [1112,1101,151,2.5] */
  body.page-about .look-lower {
    display: grid;
    grid-template-columns: calc(var(--u) * 950) 1fr;
    align-items: start;
    margin: calc(var(--u) * 71) 0 0 calc(var(--u) * 167);
  }
  body.page-about .look-local-title { padding-bottom: calc(var(--u) * 16); font-size: calc(var(--t-lfh) * 23.3); letter-spacing: .235em; }
  body.page-about .look-local-title::after { width: calc(var(--u) * 132); height: calc(var(--u) * 2.5); }
  body.page-about .look-local-body {
    width: calc(var(--u) * 640);
    margin-top: calc(var(--u) * 21);
    font-size: calc(var(--t-llb) * 20);
    line-height: calc(var(--t-llb) * 31);
    letter-spacing: .083em;
  }
  body.page-about .look-close { margin: calc(var(--u) * -20) 0 0; }
  body.page-about .look-closing {
    font-size: max(14px, calc(var(--u) * 48));
    line-height: calc(var(--u) * 49);
    letter-spacing: .016em;
    white-space: nowrap;
  }
  body.page-about .look-closing span + span { letter-spacing: -.022em; }
  body.page-about .look-cta {
    width: calc(var(--u) * 405 + (var(--t-lbt) - var(--u)) * 223);
    max-width: none;
    height: calc(var(--u) * 61 + (var(--t-lbt) - var(--u)) * 16);
    min-height: 0;
    margin-top: calc(var(--u) * 12);
    padding: calc(var(--u) * 4) 0 0 calc(var(--u) * 59);
    border-width: calc(var(--u) * 2.5);
    font-size: calc(var(--t-lbt) * 24);
    text-align: left;
    letter-spacing: .137em;
  }
  body.page-about .look-cta-underline {
    width: calc(var(--u) * 151); height: calc(var(--u) * 2.5);
    margin: calc(var(--u) * 10) 0 0 calc(var(--u) * -5);
  }

  /* where the body floor engages (stage < 1433.6, --u < .7) the mockup's forced line breaks would leave one-word
     lines: the feature bodies flow as one paragraph instead */
  @container (max-width: 1433.5px) {
    body.page-about .look-fbody span { display: inline; }
  }
}

/* ---------- split section plates (2026-09-29) ----------
   work-bg, pricing-bg and faq-bg were full-frame 3840x2160 plates, mostly empty paper, placed with object-fit: cover.
   Each is now a wrapper (the old class, so every existing rule still places it: absolute, inset 0, z -1) holding its
   subjects, cut bit-exact from the old plate (pipeline/work/split-home-plates.py; edge fades baked into alpha).
   Every img is positioned from the cover geometry the plate had - a 16:9 box --bw x --bh = max(100cqw, 100cqh*16/9)
   wide, centred (FAQ top-anchored at >= 900) - but its element box is only its VISIBLE part (its crop rect
   intersected with the wrapper): object-fit: cover redraws it at the crop's scale (only one axis is ever cut - tall
   sections cut sideways, the 16:9 desktop stage cuts nothing - so cover's scale is the crop's) and object-position
   shifts it by the part cut away. No box leaves the section (no-offscreen-left/right). --x --y --w --h are the crop
   rect as fractions of the plate. pointer-events: none keeps hit-testing on the section. */
.plate { pointer-events: none; overflow: hidden; container-type: size; }
.plate > img {
  --bw: max(calc(var(--cqw, 1cqw) * 100), calc(calc(var(--cqh, 1cqh) * 100) * 16 / 9)); --bh: calc(var(--bw) * 9 / 16);
  --ox: calc((calc(var(--cqw, 1cqw) * 100) - var(--bw)) / 2); --oy: calc((calc(var(--cqh, 1cqh) * 100) - var(--bh)) / 2);
  --L: calc(var(--ox) + var(--bw) * var(--x)); --T: calc(var(--oy) + var(--bh) * var(--y));
  --R: calc(var(--L) + var(--bw) * var(--w)); --B: calc(var(--T) + var(--bh) * var(--h));
  position: absolute; display: block; max-width: none;
  left: max(0px, var(--L)); top: max(0px, var(--T));
  width: max(0px, calc(min(calc(var(--cqw, 1cqw) * 100), var(--R)) - max(0px, var(--L))));
  height: max(0px, calc(min(calc(var(--cqh, 1cqh) * 100), var(--B)) - max(0px, var(--T))));
  object-fit: cover;
  object-position: calc(var(--L) - max(0px, var(--L))) calc(var(--T) - max(0px, var(--T)));
}
.plate > .work-topo { --x: 0.000000; --y: 0.000000; --w: 1.000000; --h: 1.000000; }
.plate > .work-field-left { --x: 0.000000; --y: 0.394444; --w: 0.144792; --h: 0.466204; }
.plate > .work-field-right { --x: 0.847656; --y: 0.401389; --w: 0.152344; --h: 0.474074; }
.plate > .pricing-topo { --x: 0.000000; --y: 0.443981; --w: 0.582031; --h: 0.509259; }
.plate > .pricing-ring { --x: 0.607812; --y: 0.091667; --w: 0.365625; --h: 0.872222; }
.plate > .faq-cloud-left { --x: 0.000000; --y: 0.519907; --w: 0.242969; --h: 0.246296; }
.plate > .faq-cloud-right { --x: 0.766927; --y: 0.525463; --w: 0.233073; --h: 0.236574; }
@media (min-width: 900px) {
  /* the FAQ plate was top-anchored (object-position: 50% 0) at >= 900 */
  .faq-bg > img { --oy: 0px; }
}

/* ---------- Privacy Policy and Terms of Service (legal text pages; no mockup) ---------- */

/* a plain reading column in the site's faces and palette between the shared header and footer. Everything here is
   scoped to body.page-legal or to legal-only classes, so screens 1-8 cannot move */
.legal {
  max-width: 44rem;
  margin: 0 auto;
  padding: 32px 16px 64px;
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  color: var(--body);
}
.legal-head {
  margin-bottom: 36px;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--faq-border);
}
.legal-kicker {
  font-family: var(--font-label);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: .2em;
  color: var(--magenta-text);
}
.legal-title {
  margin: 10px 0 12px;
  font-family: var(--font-caps);
  font-weight: 500;
  font-size: clamp(30px, 6vw, 46px);
  line-height: 1.1;
  letter-spacing: .12em;
  color: var(--ink);
}
.legal-date {
  font-family: var(--font-label);
  font-size: 13px;
  letter-spacing: .08em;
}
.legal h2 {
  margin: 40px 0 12px;
  font-family: var(--font-caps);
  font-weight: 500;
  font-size: 15px;
  line-height: 1.3;
  letter-spacing: .21em;
  text-transform: uppercase;
  color: var(--ink);
}
.legal p + p, .legal p + ul, .legal ul + p { margin-top: 14px; }
.legal ul { margin-top: 4px; }
.legal li { position: relative; padding-left: 22px; }
.legal li + li { margin-top: 8px; }
.legal li::before {
  content: "";
  position: absolute;
  left: 2px; top: .68em;
  width: 7px; height: 7px;
  background: var(--btn-gradient);
}
.legal strong { font-weight: 600; color: var(--ink); }
.legal a {
  color: var(--magenta-text);
  text-decoration: underline;
  text-underline-offset: .18em;
  text-decoration-thickness: 1px;
}
.legal a:hover { text-decoration-thickness: 2px; }
.legal-contact { font-style: normal; color: var(--ink); }

/* the desktop header is 0 px tall and draws on the stage's coordinates (its button ends near y 110 u), so the
   column clears it here (100cqw / 2048 = the stage --u, .page being the container); the footer keeps its own stage-unit layout */
@media (min-width: 900px) {
  .legal { padding-top: max(128px, calc(calc(var(--cqw, 1cqw) * 100) / 2048 * 220)); padding-bottom: 96px; }
}

/* contact@ links inside error lines and the Contact tagline read as links in the surrounding colour */
.field-error a, .cf-send-error a, .tagline-email { color: inherit; text-decoration: underline; text-underline-offset: .18em; }
.field-error a:hover, .cf-send-error a:hover, .tagline-email:hover,
.field-error a:focus-visible, .cf-send-error a:focus-visible, .tagline-email:focus-visible { color: var(--magenta-text); }

/* footer: contact@ tucked under Privacy · Terms, in its own case (the legal row is uppercase). Phones: the pair sits
   above the copyright, as the links alone did; desktop: right-aligned, the links' baseline still on the copyright's */
.footer-legal-side { order: -1; display: flex; flex-direction: column; align-items: center; }
.footer-email {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: -14px;  /* tucked under the links; both keep 44 px tap rows, overlapping only in dead space */
  padding: 0 8px;
  color: var(--ink);
  text-transform: none;
  letter-spacing: .06em;
  font-size: 1.2em;
  font-weight: 400;
  transition: color .2s ease;
}
.footer-email:hover, .footer-email:focus-visible { color: var(--magenta-text); }
@media (min-width: 900px) {
  .footer-legal-side { order: 0; align-items: flex-end; gap: calc(var(--u) * 10); }
  .footer-email { display: inline; min-height: 0; padding: 0; line-height: 1; white-space: nowrap; margin: 0 -.06em 0 0; }
  /* About's framed closing section ends on its side rules; give the footer hairline room below them */
  body.page-about .site-footer { margin-top: calc(var(--u) * 80); }
}
