/* =================================================================
   jl audio — component vocabulary v1
   One shared set of building blocks for every inner page, replacing
   the tick lists / boxed CTA bands / checkmark columns four separate
   bots invented independently. Ports the home page's own section-head
   (.sec-head) and index-row (.svcp-row) patterns as components 1 & 2;
   everything else follows the same rules those two already set:
   --page-x edge, hairline separators, fluid clamp() sizing, nothing
   green at rest, no fills except the black CTA and hero/footer
   surfaces, no icons beyond the arrow and +/×.

   Load AFTER theme-v2.css. Uses only tokens theme-v2.css defines —
   no new colours, no new type sizes.
   ================================================================= */

/* Skip link + generic focus-visible fallback (a11y audit 2026-09-25).
   Skip link markup is identical on every page: the first element in
   <body>, hidden off-screen until keyboard-focused. Targets #main,
   added around each page's content in the same pass. */
.skip-link{
  position:absolute; left:-9999px; top:0; z-index:1000;
  background:var(--black); color:var(--paper);
  padding:.75em 1.25em; font-size:14px; font-weight:500;
  text-decoration:none; border-radius:0 0 4px 0;
}
.skip-link:focus{ left:0; }

/* Fallback outline for any focusable element that doesn't already carry
   its own :focus-visible treatment above — belt-and-braces so keyboard
   focus is never invisible on a control a future page adds. */
a:focus-visible, button:focus-visible, input:focus-visible,
textarea:focus-visible, select:focus-visible, [tabindex]:focus-visible{
  outline:2px solid var(--green-light);
  outline-offset:2px;
}

/* Section-spacing retune (2026-09-22): --sec-pad is the ONE fluid gap
   between the end of one section's band of rows and the next label —
   section-to-section air. --sec-gap is the label's own margin down to
   its hairline — fixed, not fluid, so it always reads as "one line
   below the label" instead of stretching into its own empty band.
   Overridden here (not in theme-v2.css) per component-vocabulary
   convention: everything c-sechead-shaped lives in this file. */
:root{
  --sec-pad: clamp(48px, 5vw, 96px);
  --sec-gap: var(--r2);
}

/* =================================================================
   1. .c-sechead — small label + h2 + optional right link, hairline
   below. Same shape as home's .svcp-head/.sec-head, with an explicit
   eyebrow label line above the heading (home's heads skip the label
   because "services."/"selected work." read as label-weight already;
   inner pages need the extra rung for longer headings).
   No border-top of its own — the hairline that closes the PREVIOUS
   section's band (last row's border-bottom, or the nav/hero hairline
   for a page's first section) is the only hairline above --sec-pad.
   A border-top here would sandwich the label between two hairlines
   and read as a stranded label in an empty band. ================== */
.c-sechead{
  display:flex; align-items:flex-end; justify-content:space-between; gap:var(--r3);
  padding:var(--sec-pad) var(--page-x) var(--sec-gap);
}
.c-sechead .c-sechead-text{display:flex; flex-direction:column; gap:var(--r1);}
.c-sechead .lbl{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink);
}
.c-sechead h2{
  font-family:var(--face); font-size:var(--fs-h2); font-weight:var(--fw-h2); letter-spacing:var(--ls-h2);
  line-height:1.15; text-transform:lowercase; color:var(--black);
}
.c-sechead .c-sechead-link{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--grey-1); white-space:nowrap; transition:color .2s ease-out;
}
.c-sechead .c-sechead-link:hover, .c-sechead .c-sechead-link:focus-visible{
  color:var(--accent); text-decoration:underline; text-underline-offset:.2em;
}
.dark .c-sechead .lbl, .dark .c-sechead .c-sechead-link{color:var(--on-dark-1);}
.dark .c-sechead h2{color:var(--paper);}
.c-sechead__sub{
  font-family:var(--face); font-size:var(--fs-small); color:var(--grey-1);
  margin-top:var(--r1); max-width:40ch;
}
.dark .c-sechead__sub{color:var(--on-dark-1);}

/* =================================================================
   2. .c-row — full-width index row (port of home's .svcp-row).
   Title left at h3–display scale (--lg = home services scale, --md =
   default/smaller, for denser lists like specs-as-rows). Optional
   one-line meta under the title; optional right meta (price/service
   label/arrow). Hover: title colour → accent only, nothing else moves
   except the arrow glyph if present.
   ================================================================= */
.c-rows{border-top:1px solid var(--hairline);}
.c-row{
  display:flex; align-items:center; justify-content:space-between; gap:var(--r4);
  padding:var(--row-pad) var(--page-x);
  border-bottom:1px solid var(--hairline);
  text-decoration:none;
  transition:background .2s ease-out;
}
.c-row:last-child{border-bottom:none;}
.c-row .c-row-title{display:flex; flex-direction:column; gap:var(--r1); min-width:0;}
.c-row .c-row-title b{
  font-family:var(--face); font-weight:var(--fw-h1); letter-spacing:var(--ls-h1);
  text-transform:lowercase; color:var(--black); line-height:1.05; transition:color .2s ease-out;
  font-size:var(--fs-h2); /* --md default */
}
.c-row--lg .c-row-title b{font-size:clamp(28px,4.4vw,56px);}
.c-row .c-row-meta-under{
  font-family:var(--face); font-weight:400; font-size:var(--fs-body); letter-spacing:0;
  color:var(--grey-1); max-width:480px; line-height:1.55;
}
.c-row .c-row-meta{
  display:flex; align-items:center; gap:var(--r2); flex:none;
  font-family:var(--face); font-weight:600; font-size:var(--fs-label); letter-spacing:.08em;
  text-transform:uppercase; color:var(--grey-1); white-space:nowrap; transition:color .2s ease-out;
}
.c-row .c-row-arr{
  font-family:var(--face); color:var(--black); transition:color .2s ease-out, transform .35s cubic-bezier(.22,1,.36,1);
}
.c-row:hover .c-row-title b, .c-row:focus-visible .c-row-title b{color:var(--accent);}
.c-row:hover .c-row-meta, .c-row:focus-visible .c-row-meta{color:var(--accent);}
.c-row:hover .c-row-arr, .c-row:focus-visible .c-row-arr{color:var(--accent); transform:translateX(5px);}
@media (max-width:640px){
  .c-row{flex-direction:column; align-items:flex-start; gap:var(--r2);}
  .c-row .c-row-meta{align-self:flex-start;}
  /* QA 2026-09-28: a row whose only right-hand item is the arrow keeps
     title + arrow on one line on phones (the column stack above is for
     rows with a price/meta block). Stops the arrow orphaning on its own
     line on /links/, /thanks/, 404 and the /start/ chooser. */
  .c-row:has(> .c-row-arr:last-child){flex-direction:row; align-items:center; gap:var(--r3);}
  .c-row:has(> .c-row-arr:last-child) > .c-row-arr{flex:none;}
}

/* =================================================================
   3. .c-spec — spec table: label (uppercase small, fixed column) +
   value (body), hairlines. Replaces tick lists / checkmark columns /
   rate boxes everywhere on inner pages.
   ================================================================= */
.c-spec{border-top:1px solid var(--hairline);}
.c-spec .c-spec-row{
  display:grid; grid-template-columns:160px 1fr; gap:var(--r4);
  padding:var(--r4) var(--page-x);
  border-bottom:1px solid var(--hairline);
}
.c-spec .c-spec-row:last-child{border-bottom:none;}
.c-spec .c-spec-label{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink);
}
.c-spec .c-spec-value{
  font-family:var(--face); font-size:var(--fs-body); font-weight:400; color:var(--black); line-height:1.55;
}
@media (max-width:640px){
  .c-spec .c-spec-row{grid-template-columns:1fr; gap:var(--r1);}
}
/* .c-spec__head — column heading above a .c-spec's rows (used in
   --2col layouts so each column says what it is: "what you send" /
   "deliverables"). Same label styling as .c-spec-label, hairline
   below to separate it from the first row. */
.c-spec__head{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink);
  padding:var(--r3) var(--page-x) var(--r2);
  border-bottom:1px solid var(--hairline);
}
@media (min-width:900px){
  .c-spec--2col .c-spec:first-child .c-spec__head{padding-right:0;}
  .c-spec--2col .c-spec:last-child .c-spec__head{padding-left:0;}
}
/* --2col: two spec tables side by side at >=900px */
.c-spec--2col{
  display:grid; grid-template-columns:1fr; border-top:none;
}
.c-spec--2col .c-spec{border-top:1px solid var(--hairline);}
/* Each row still carries its own --page-x padding (so a single .c-spec
   used alone always sits flush on the page edge) — in the 2-up layout
   that would double the gutter at the shared inner edge, so the inner
   sides are zeroed and the column-gap does that job instead. Outer
   edges (first column's left, last column's right) keep --page-x. */
@media (min-width:900px){
  .c-spec--2col{grid-template-columns:1fr 1fr; column-gap:var(--r6);}
  .c-spec--2col .c-spec:first-child{border-right:1px solid var(--hairline);}
  .c-spec--2col .c-spec:first-child .c-spec-row{padding-right:0;}
  .c-spec--2col .c-spec:last-child .c-spec-row{padding-left:0;}
}

/* =================================================================
   3b. .c-detail — "what to send / what you get" block. Two plain
   stacked-text columns (no grid, no hairlines, no label column) at
   >=900px, single column at <900px. Each column: small uppercase
   label heading, then a stacked list of plain body-size sentences,
   ~40ch measure, --grey-1. Columns separated by whitespace only.
   Optional trailing line (turnaround etc.) in the small label style.
   Replaces .c-spec--2col + a standalone turnaround .c-spec row.
   ================================================================= */
.c-detail{
  padding:var(--r6) var(--page-x);
  border-top:1px solid var(--hairline);
  display:flex; flex-direction:column; gap:var(--r6);
}
.c-detail .c-detail-cols{display:flex; flex-direction:column; gap:var(--r6);}
.c-detail .c-detail-col{max-width:40ch;}
.c-detail .c-detail-label{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink); margin-bottom:var(--r3); display:block;
}
.c-detail .c-detail-list{
  list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:var(--r2);
}
.c-detail .c-detail-list li{
  font-family:var(--face); font-size:var(--fs-body); font-weight:400; color:var(--grey-1); line-height:1.55;
}
.c-detail .c-detail-foot{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink);
}
@media (min-width:900px){
  .c-detail .c-detail-cols{flex-direction:row; gap:var(--r6);}
}
/* .c-prep — "file prep" is a .c-detail whose only children are the label
   and a .c-detail-list of PDF links (2026-09-27: previously bare
   .prep-download anchors as direct flex items, styled like a second
   small-caps label — see .prep-download's own comment in theme-v2.css
   for why that read as two orphan labels with no content between them).
   Reusing .c-detail-list here means the label->list and item->item gaps
   come from the exact same list component the "what to send" section
   uses directly above, so the two sections read as siblings. .c-detail's
   own gap:var(--r6) (48px) between label and list is still too generous
   next to the label's own margin-bottom:var(--r3) (24px) — "what to
   send" avoids this because its label+list sit inside a plain block
   column, not flex siblings — so zero the shared flex gap here and let
   the label's margin alone set the 24px label->list gap, matching that
   rhythm exactly. Loads after theme-v2.css so this wins the
   equal-specificity .c-detail vs .c-prep tie. */
.c-prep{ gap:0; }

/* =================================================================
   4. .c-price — inline price meta for a row or page header. Label
   style, right-aligned, no giant numerals ("from $350" / "$350 /
   track"). This is the ONLY price treatment on the site — no more
   .rate-style oversized figures on new pages.
   ================================================================= */
.c-price{
  font-family:var(--face); font-weight:600; font-size:var(--fs-label); letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink); text-align:right; white-space:nowrap;
}
.c-price .c-price-unit{color:var(--green-ink); font-weight:600;}
.c-row:hover .c-price{color:var(--accent);}

/* =================================================================
   5. .c-cta — end-of-body CTA row: one .c-row--lg with an arrow,
   black text on paper (never a boxed black band). Used once at the
   end of a page body.
   ================================================================= */
.c-cta{border-top:1px solid var(--hairline);}
.c-cta .c-row{border-top:none;}

/* =================================================================
   6. .c-prose — long copy. Label column left (~1/3 at >=900px), ~60ch
   measure right, first paragraph one step larger.
   ================================================================= */
.c-prose{
  padding:var(--r6) var(--page-x);
  border-top:1px solid var(--hairline);
  display:flex; flex-direction:column; gap:var(--r4);
}
.c-prose .c-prose-label{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--grey-1); flex:none;
}
.c-prose .c-prose-body{max-width:50ch; display:flex; flex-direction:column; gap:var(--r3);}
.c-prose .c-prose-body p{font-family:var(--face); font-size:var(--fs-body); color:var(--grey-1); line-height:1.55;}
.c-prose .c-prose-body p:first-child{font-size:calc(var(--fs-body) + 2px); color:var(--grey-1);}
@media (min-width:900px){
  .c-prose{flex-direction:row; align-items:flex-start; gap:var(--r6);}
  .c-prose .c-prose-label{width:33%; padding-top:.2em;}
}

/* =================================================================
   7. .c-field — underline input/textarea/select + small label above.
   Error state = hairline turns black + small message. .c-fieldset =
   two-column (legend left, fields right) at >=900px.
   ================================================================= */
.c-field{display:flex; flex-direction:column; gap:var(--r1); margin-bottom:var(--r4);}
.c-field label{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--grey-1);
}
.c-field input, .c-field textarea, .c-field select{
  font-family:var(--face); font-size:var(--fs-body); color:var(--black); background:none;
  border:none; border-bottom:1px solid var(--grey-2); border-radius:0;
  padding:var(--r2) 0; outline:none; transition:border-color .2s ease-out; width:100%;
}
.c-field select{appearance:none; -webkit-appearance:none;}
.c-field textarea{resize:vertical; min-height:6em;}
.c-field input:focus, .c-field textarea:focus, .c-field select:focus{border-bottom-color:var(--black);}
/* /start/ intake fields carry BOTH .field and .c-field (equal specificity
   with theme-v2.css's `.field input:focus{border-bottom-color:var(--green-ink)}`
   loaded first) — this rule, loading later in the same components.css file,
   was winning the cascade and flattening every focused field back to black,
   killing the sitewide green-ink focus underline on the one production form
   that actually uses it (green3 pixel audit, 2026-09-23). */
.field.c-field input:focus, .field.c-field textarea:focus, .field.c-field select:focus{border-bottom-color:var(--green-ink);}
/* .c-field's background:none above also wiped theme-v2's .field select
   chevron, so selects read as filled text, not a dropdown (QA 2026-09-28).
   Restore it, and show the unchosen "choose one" in muted ink. */
.field.c-field select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 7l5 6 5-6' fill='none' stroke='%239C9A93' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 2px center; background-size:18px 18px;
  padding-right:28px; cursor:pointer;
}
.field.c-field select:invalid{color:var(--grey-1);}
.field.c-field select option{color:#0B0B0A; background:#F7F7F7;}
.field.c-field.has-error input, .field.c-field.has-error textarea, .field.c-field.has-error select{border-bottom-color:var(--error);}
.c-field input::placeholder, .c-field textarea::placeholder{color:var(--grey-2);}
.c-field .c-field-msg{font-family:var(--face); font-size:var(--fs-small); color:var(--grey-1);}
.c-field.is-error input, .c-field.is-error textarea, .c-field.is-error select{border-bottom-color:var(--black);}
.c-field.is-error .c-field-msg{color:var(--black);}

.c-fieldset{border-top:1px solid var(--hairline); padding:var(--r6) var(--page-x);}
.c-fieldset .c-fieldset-legend{
  font-family:var(--face); font-size:var(--fs-h2); font-weight:var(--fw-h2); letter-spacing:var(--ls-h2);
  text-transform:lowercase; color:var(--black); margin-bottom:var(--r4);
}
@media (min-width:900px){
  .c-fieldset{display:flex; gap:var(--r6);}
  .c-fieldset .c-fieldset-legend{width:33%; flex:none; margin-bottom:0; align-self:flex-start;}
  .c-fieldset .c-fieldset-fields{flex:1; max-width:60ch;}
}

/* =================================================================
   8. .c-acc — accordion row: button full width, question h3 left,
   thin + rotating to × right, answer in measure column, one open at
   a time.
   ================================================================= */
.c-acc{border-top:1px solid var(--hairline);}
.c-acc-row{border-bottom:1px solid var(--hairline);}
.c-acc-row:last-child{border-bottom:none;}
.c-acc-q{
  display:flex; align-items:center; justify-content:space-between; gap:var(--r4);
  width:100%; padding:var(--row-pad) var(--page-x);
  background:none; border:none; text-align:left; cursor:pointer;
  font-family:var(--face); font-size:var(--fs-h2); font-weight:var(--fw-h2); letter-spacing:var(--ls-h2);
  color:var(--black); text-transform:lowercase;
}
.c-acc-plus{
  flex:none; position:relative; width:16px; height:16px; transition:transform .28s cubic-bezier(.4,0,.2,1);
}
.c-acc-plus::before, .c-acc-plus::after{
  content:''; position:absolute; background:var(--black); top:50%; left:50%;
}
.c-acc-plus::before{width:16px; height:1px; transform:translate(-50%,-50%);}
.c-acc-plus::after{width:1px; height:16px; transform:translate(-50%,-50%); transition:opacity .2s ease-out;}
.c-acc-row.is-open .c-acc-plus{transform:rotate(45deg);}
.c-acc-a{
  display:grid; grid-template-rows:0fr; transition:grid-template-rows .28s cubic-bezier(.4,0,.2,1);
}
.c-acc-row.is-open .c-acc-a{grid-template-rows:1fr;}
/* min-height:0 on the grid ITEM (not just overflow:hidden on it) — a grid
   item's default min-height:auto resolves to its content's min-content
   size, which refuses to shrink below that even when the track above is
   0fr. Without this, a collapsed row's answer text still renders at a
   sliver of its full height instead of 0 — the faint ghost text bleeding
   through under the last visible FAQ row. 2026-09-25. */
.c-acc-a-inner{overflow:hidden; min-height:0;}
.c-acc-a p{
  max-width:50ch; padding:0 var(--page-x) var(--row-pad);
  font-family:var(--face); font-size:var(--fs-body); color:var(--grey-1); line-height:1.55;
}

/* =================================================================
   9. .c-pagehead — inner page header band. Two-column composition on
   desktop (home-beats rule: visual right ~62%, text left) — left col
   is the breadcrumb/h1/intro/price stack (.c-pagehead-text), right
   col is a hairline-framed live-instrument cell (.c-pagehead-inst),
   top-aligned with the title's cap height. Plain heads with no
   instrument (.c-pagehead without a --inst modifier) keep the old
   single-column stack + watermark untouched.
   ================================================================= */
.c-pagehead{
  position:relative; overflow:visible;
  padding:var(--sec-pad) var(--page-x) var(--r6);
  display:flex; flex-direction:column; gap:var(--r3);
  min-height:calc(11vw + var(--sec-pad) + var(--r6));
}
.c-pagehead-crumb{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink); position:relative; z-index:1;
}
.c-pagehead-crumb a{color:var(--green-ink); transition:color .2s ease-out;}
.c-pagehead-crumb a:hover, .c-pagehead-crumb a:focus-visible{
  color:var(--accent); text-decoration:underline; text-underline-offset:.2em;
}
.c-pagehead h1{
  font-family:var(--face); font-size:var(--fs-h1); font-weight:var(--fw-h1); letter-spacing:var(--ls-h1);
  text-transform:lowercase; color:var(--black); line-height:1.05; position:relative; z-index:1;
  max-width:20ch; /* sen-derived measure discipline: caps display headlines so a
    wrap never orphans a single trailing word — see DESIGN.md §2 */
}
.c-pagehead h1.c-pagehead__h1--upper{text-transform:uppercase;}
/* Opt-in for any future title long enough to wrap 3+ lines — tightens leading
   toward sen's 0.9-0.92 so the block reads as one shape instead of stacked
   lines. None of today's titles need it (longest wraps at most 2 lines). */
.c-pagehead h1.c-pagehead__h1--tight{line-height:.92;}
.c-pagehead-intro{
  font-family:var(--face); font-size:var(--fs-body); color:var(--grey-1); max-width:60ch;
  line-height:1.55; position:relative; z-index:1;
}
.c-pagehead-intro a{color:var(--green-ink); font-weight:600; text-decoration:underline; text-underline-offset:3px; text-decoration-thickness:1px; transition:color .2s ease-out;}
.c-pagehead-intro a:hover, .c-pagehead-intro a:focus-visible{color:var(--accent);}
.c-pagehead-watermark{
  position:absolute; top:calc(50% + var(--nav-h) / 2); right:var(--page-x); left:auto; /* centred on the head TEXT block, not the box that starts under the fixed nav (owner 2026-09-24) */
  transform:translateY(-50%);
  font-family:var(--face); font-weight:600; font-size:11vw; line-height:1;
  color:var(--grey-3); opacity:.55; text-transform:lowercase; letter-spacing:-.02em;
  white-space:nowrap; pointer-events:none; z-index:0; user-select:none;
}
@media (max-width:640px){
  .c-pagehead-watermark{font-size:18vw; top:calc(50% + var(--nav-h-mobile) / 2);}
  .c-pagehead{min-height:calc(18vw + var(--sec-pad) + var(--r6));}
}
/* mobile audit 2026-09-27 (#4): the ghost watermark collides with the H1
   at <=760px on every inner page that doesn't already hide it — /start/
   and /agreement/ already do this (see the #page-start / #page-agreement
   rules further down), scoped to those two only because that's where the
   2026-09-25 pass happened to look. The 2026-09-27 mobile pass found the
   same collision on plain pageheads with no intro copy (pricing., 404,
   services. etc. — shots/pricing--390x844, shots/404--360x780). Hide it
   everywhere at the same breakpoint the rest of the sheet treats as
   mobile (.c-pagehead's own padding-top switch above) instead of chasing
   it page by page — it's aria-hidden decoration, nothing is lost, and
   the two page-scoped rules below are now a harmless subset of this one. */
@media (max-width:760px){
  .c-pagehead-watermark{display:none;}
}

/* .c-price inside a .c-pagehead (mixing / mastering / mixing+mastering /
   production) used to sit in-flow after the intro paragraph, which put it
   right in the watermark's vertically-centred band and the two collided
   at every width (worst at mobile, where the watermark grows to 18vw).
   Pin it out of flow instead, right-aligned on the title row, above the
   watermark — a fixed, deliberate spot that never depends on how tall the
   intro copy or the watermark happens to be. 2026-09-23. */
.c-pagehead > .c-price{
  position:absolute; top:var(--sec-pad); right:var(--page-x);
  z-index:2; margin:0;
}
@media (max-width:640px){
  .c-pagehead > .c-price{top:auto; bottom:var(--r4);}
}
/* (2026-09-27: removed the price-page watermark nudge — it pushed the j
   descender out of the band; price pages now match every other page.) */

/* Any head with a .c-pagehead-intro (subhead copy) is short on
   headroom at mobile widths — a short h1 (mixing./mastering./FAQ.)
   leaves under 25px between the h1's baseline and the intro's first
   line, nowhere near enough for the 18vw watermark to sit without
   bleeding into the intro paragraph itself (not just the h1 it's
   meant to sit behind). Scoped down to 10vw and re-centred on the
   crumb+h1 pair alone (pulled up off the intro) whenever an intro
   follows — keeps it "behind the head text" per spec instead of
   spilling into the body copy under it. 2026-09-25. */
@media (max-width:640px){
  /* .c-pagehead prefixed to match the 3-class specificity of the
     .c-price rule above (which has no width guard, so it's still in
     play here) — without this, that rule's `top` wins the cascade on
     specificity alone and the shrink below does nothing to the
     position, only the size. */
  .c-pagehead .c-pagehead-intro ~ .c-pagehead-watermark{
    font-size:10vw;
    top:calc(50% + var(--nav-h-mobile) / 2 - 20px);
  }
}

/* --- .c-pagehead--inst: instrument-bearing heads (2026-09-23) ---
   Switches the band to a row: text stack left (flex:1), instrument
   cell right, top-aligned. Watermark is dropped entirely on these
   heads (per-brief: removed, not dimmed-behind) — the instrument
   cell is now the head's visual, a giant ghost wordmark competing
   behind it reads as clutter, not depth. min-height reverts to
   content-driven since the watermark no longer sets the band's
   vertical rhythm here. */
.c-pagehead--inst{
  flex-direction:row; align-items:flex-start; justify-content:space-between;
  gap:var(--r6); min-height:0; flex-wrap:wrap;
}
.c-pagehead--inst .c-pagehead-watermark{display:none;}
.c-pagehead-text{
  display:flex; flex-direction:column; gap:var(--r3);
  position:relative; z-index:1; flex:1 1 360px; min-width:0;
}
/* the cell: hairline frame, corner ticks, graticule instrument inside.
   Proportions follow the mounted instrument (scope/analyser 2:1, vu 3:2);
   width clamps chosen so computed height lands ~260-320px at desktop
   viewports per the brief. Top-aligned to sit level with the h1 cap-height,
   not centred in the band. */
.c-pagehead-inst{
  position:relative; flex:0 0 auto; align-self:flex-start;
  border:1px solid var(--hairline); background:var(--paper);
  margin-top:.35em; /* nudges cell top down to the h1's cap-height, not its ascent box */
}
/* Height-driven, not width-driven: 11vw mirrors the exact term the old
   watermark-only band used in its min-height formula (`11vw + sec-pad +
   r6`) — since sec-pad/r6 are the same padding this cell sits inside,
   sizing the cell to 11vw content-height reproduces that band's original
   total height almost exactly at any viewport, so swapping the watermark
   for this cell cannot grow the head. On pages whose text stack is taller
   than 11vw (mixing/mastering's intro+price lines), the text naturally
   governs row height instead and the cell just sits shorter than it —
   never the other way around. Width is derived from height via
   aspect-ratio, not set directly. */
/* -6px baked into the clamp compensates for the cell's own margin-top
   nudge above (.35em ≈ 6px at --fs-body) — that margin adds to the row's
   total cross-axis extent (margin + height) even though it isn't part of
   `height` itself, so without this the cell's true footprint would run
   ~6px past the 11vw budget and grow the head. */
.c-pagehead-inst--scope,
.c-pagehead-inst--analyser{ height:clamp(90px, calc(11vw - 6px), 254px); aspect-ratio:2/1; width:auto; }
.c-pagehead-inst--vu{ height:clamp(90px, calc(11vw - 6px), 254px); aspect-ratio:3/2; width:auto; }
/* --vec: /work/ head vectorscope (2026-09-24 v4, owner: v3's 350px fixed
   square crossed the head's bottom divider and sat on top of the first
   work tile). Size/top are now set at runtime by sizeVecCell() in
   instruments.js, which measures the head's actual inner box (nav bottom
   to the head's own bottom edge, minus a 16px inset each side) so the
   figure can never overflow the head regardless of viewport — width/
   height/top below are only the JS-off/pre-measure fallback. right stays
   pure CSS (doesn't depend on content height). No border, no background,
   no ticks/peak: bare transparent canvas. */
.c-pagehead-inst.c-pagehead-inst--vec{
  position:absolute; top:calc(var(--nav-h) + 16px); right:var(--page-x);
  border:none; background:none; margin:0;
  width:240px; height:240px;
}
@media (max-width:760px){
  /* double-class selector (not just .c-pagehead-inst--vec) so this beats
     the generic ".c-pagehead-inst{width:100%;height:auto;aspect-ratio:16/9}"
     column-stack rule below, which also matches this element (it carries
     both classes) and was silently overriding these to full-width/219px —
     the bug the owner flagged as "way too small" on mobile. */
  .c-pagehead-inst.c-pagehead-inst--vec{
    top:calc(var(--nav-h-mobile) + 16px);
    width:180px; height:180px;
  }
}
.c-pagehead-inst .tick{position:absolute; width:12px; height:12px; pointer-events:none; z-index:2;}
.c-pagehead-inst .tick.tl{top:-1px; left:-1px; border-top:1px solid var(--black); border-left:1px solid var(--black);}
.c-pagehead-inst .tick.tr{top:-1px; right:-1px; border-top:1px solid var(--black); border-right:1px solid var(--black);}
.c-pagehead-inst .tick.bl{bottom:-1px; left:-1px; border-bottom:1px solid var(--black); border-left:1px solid var(--black);}
.c-pagehead-inst .tick.br{bottom:-1px; right:-1px; border-bottom:1px solid var(--black); border-right:1px solid var(--black);}
/* static trigger/baseline — always present even with JS off, so the cell
   never reads as an empty box; instruments.js draws over/through it. */
.c-pagehead-inst--scope::after,
.c-pagehead-inst--analyser::after{
  content:""; position:absolute; left:10%; right:10%; top:50%; height:1px;
  background:var(--hairline); z-index:0;
}
.c-pagehead-inst .instrument{position:absolute; inset:0; display:block; z-index:1;}
/* peak/status tick — tiny green-ink mark, the one static (non-hover) use of
   --accent on this surface, per this lane's brief ("green-ink in small
   doses"). One hairline tick, not a fill — stays in the spirit of "hover-
   only at rest" by being the smallest possible mark, not a colour block. */
.c-pagehead-inst-peak{
  position:absolute; z-index:2; background:var(--accent); pointer-events:none;
}
.c-pagehead-inst--scope .c-pagehead-inst-peak,
.c-pagehead-inst--analyser .c-pagehead-inst-peak{
  top:8px; right:10px; width:6px; height:6px; border-radius:50%;
}
.c-pagehead-inst--vu .c-pagehead-inst-peak{
  top:14%; left:50%; width:1px; height:10px; transform:translateX(-50%);
}
/* about/mixing/mastering/pricing (2026-09-24): removing their scope/vu cell
   would let the head shrink, since on a short page (about/pricing) the cell
   — not the text — set the row's cross-axis size, and on every page the
   mobile column layout stacked the cell below the text so it added its own
   height regardless. Desktop: min-height matches the old cell's measured
   footprint (11vw ~= its height+margin-top) — a no-op on mixing/mastering,
   whose intro+price text is already taller than that. Mobile (<=760px,
   where .c-pagehead--inst switches to a column): min-height doesn't help
   two stacked-not-competing boxes, so add back the cell's exact old
   margin-top+height (24px + 192.375px, measured pre-removal, identical
   across all four pages at this breakpoint) as margin-bottom instead. */
.c-pagehead--keepheight .c-pagehead-text{
  min-height:clamp(90px, 11vw, 254px);
}
@media (max-width:760px){
  .c-pagehead--keepheight .c-pagehead-text{
    min-height:0; margin-bottom:264.375px;
  }
}
@media (max-width:760px){
  .c-pagehead--inst{flex-direction:column; align-items:stretch;}
  /* the 360px flex-basis above is a desktop ROW-width hint; in this
     column layout the same basis reads as a minimum HEIGHT, which was
     stretching the text block ~360px tall and stranding the instrument
     cell far below it. Reset to content height. */
  .c-pagehead-text{flex-basis:auto;}
  .c-pagehead-inst,
  .c-pagehead-inst--scope, .c-pagehead-inst--analyser, .c-pagehead-inst--vu{
    width:100%; height:auto; aspect-ratio:16/9; margin-top:var(--r3);
  }
  /* --vec is excluded from the selector list above — it's position:absolute
     (see its own rule), never part of this column stack. */
}

/* =================================================================
   10. .c-player — wraps the existing waveform player row (markup
   unchanged, sitewide .work-row/.player/.play-btn/.wave rules in
   theme-v2.css already give grey bars / black played / circle
   hairline button; this class only adds the surrounding rhythm so a
   player can sit outside #work — a standalone hairline-separated
   list, --page-x edge, same as everywhere else).
   ================================================================= */
.c-players{border-top:1px solid var(--hairline);}
/* No horizontal/vertical padding here — the nested .work-row (theme-v2.css)
   already carries its own --page-x / --row-pad rhythm; padding on both
   would double the left offset so rows fail to start at --page-x like
   every other row on the page. */
.c-player{padding:0; border-bottom:1px solid var(--hairline);}
.c-player:last-child{border-bottom:none;}

/* =================================================================
   11. .c-cards — testimonial grid: hairline-separated cells, stars /
   artist bold / "track · service" small caps / quote italic. No
   filled boxes.
   ================================================================= */
.c-cards{
  display:grid; grid-template-columns:1fr; border-top:1px solid var(--hairline);
}
.c-card{padding:var(--r6) var(--page-x); border-bottom:1px solid var(--hairline); display:flex; flex-direction:column; gap:var(--r2);}
.c-cards .c-card:last-child{border-bottom:none;}
.c-card-stars{display:flex; gap:4px;}
.c-card-stars svg{width:14px; height:14px; fill:var(--black);}
.c-card-quote{font-family:var(--face); font-size:clamp(17px, 1.5vw, 20px); font-style:italic; color:var(--black); line-height:1.55; max-width:60ch;}
.c-card-attr{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--grey-1);
}
.c-card-attr b{color:var(--black); font-weight:700;}
@media (min-width:900px){
  .c-cards{grid-template-columns:1fr 1fr;}
  /* Left border only, on the second column — never a right border, so a
     grid with an odd/single card never reads as a closed box. */
  .c-cards .c-card:nth-child(2n){border-left:1px solid var(--hairline);}
}

/* =================================================================
   12. Service-page tiering — .c-group / .c-group__label (a labeled
   block, e.g. "options" or "add-ons"), .c-row--option (the actual
   purchasable choice: h3-scale title left, price right, one-line meta
   under the title), .c-spec--sm (demoted spec table for secondary
   detail — smaller type, tighter rows, grey values). Ports the MONOE
   product-detail read: title+price at top, options as clear rows with
   price right, secondary detail smaller and lower.
   ================================================================= */
.c-group{border-top:1px solid var(--hairline);}
.c-group__label{
  display:block;
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink);
  padding:var(--r3) var(--page-x) var(--r2);
}
.dark .c-group{border-top:1px solid var(--hairline-inv);}
.dark .c-group__label{color:var(--on-dark-1);}
/* a .c-spec nested in a .c-group already sits under the group's own
   top hairline — drop its own, so the label isn't followed by a
   second rule right underneath it */
.c-group .c-spec{border-top:none;}

/* --option: purchasable row — the focal point of the page (MONOE's
   product title+price), so its title sits a step ABOVE the default
   --md row scale used by nav-style rows like "file prep" below it,
   between fs-h2 and the --lg index-row scale. Price right via the
   existing .c-price component. */
.c-row--option .c-row-title b{font-size:clamp(28px,3.6vw,40px);}
.c-row--option .c-price{font-size:var(--fs-label);}

/* .c-row-end — right-hand wrapper for a .c-row--option rendered as a real
   link (price + arrow together), so the row's own
   justify-content:space-between still only ever sees two flex children.
   2026-09-27: option rows on the service pages became clickable links
   into /start/ with the matching service preselected — see .c-row-arr
   for the shared hover/focus treatment (colour + nudge). */
.c-row-end{display:flex; align-items:center; gap:var(--r3); flex:none;}

/* .c-row-enq — "enquire →" affordance at the end of a service-page
   subservice row (the whole row links to /start/ with that subservice
   pre-filled). Label type, ink by default, accent on row hover/focus —
   the nested .c-row-arr keeps its shared nudge. */
.c-row-enq{
  display:inline-flex; align-items:center; gap:8px; white-space:nowrap;
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--black);
  padding-left:var(--r3); border-left:1px solid var(--hairline);
  transition:color .2s ease-out;
}
.c-row:hover .c-row-enq, .c-row:focus-visible .c-row-enq{color:var(--accent);}
@media (max-width:640px){
  .c-row-end{width:100%; justify-content:space-between;}
  .c-row-enq{border-left:none; padding-left:0;}
}

/* .c-enquiring — "enquiring about: …" line under a /start/ form's heading,
   shown when the form opened with a service/subservice pre-filled. */
.c-enquiring{
  display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 10px;
  margin-top:var(--r2); padding:var(--r2) 0; border-top:1px solid var(--hairline); border-bottom:1px solid var(--hairline);
}
.c-enquiring[hidden]{display:none;}
.c-enquiring__k{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink);
}
.c-enquiring b{
  font-family:var(--face); font-weight:var(--fw-h1); letter-spacing:var(--ls-h1);
  font-size:clamp(20px,2.2vw,26px); line-height:1.1; text-transform:lowercase; color:var(--black);
}

/* .c-row__addon — secondary "+ add-on" line nested under an option
   row's description (mixing row lists its + mastering add-on, etc.),
   instead of a separate add-ons group. Label style, demoted grey. */
.c-row__addon{
  display:block;
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--grey-1); margin-top:8px;
}

/* --sm: demoted spec table — tighter rows, smaller/grey value type.
   Used for "what you send / what you get" and for add-on line items
   (label carries the "+ …" prefix, value carries the price delta). */
.c-spec--sm .c-spec-row{grid-template-columns:130px 1fr; padding:var(--r2) var(--page-x); gap:var(--r3);}
.c-spec--sm .c-spec-label{font-size:var(--fs-small); letter-spacing:.06em;}
.c-spec--sm .c-spec-value{font-size:var(--fs-small); color:var(--grey-1); line-height:1.5;}
@media (max-width:640px){
  .c-spec--sm .c-spec-row{grid-template-columns:1fr; gap:4px;}
}

/* =================================================================
   13. .c-steps / .c-step — checkout-style progress row + step panels
   (start/index.html funnel). N labels in c-sechead label style (small
   uppercase), hairline under the row; current = --black, done =
   --grey-1 with a thin check, upcoming = --grey-2. Sticky under the
   nav at >=900px only. .c-row--option is a plain .c-row rendered as a
   full-width button, for a one-row-per-choice picker (step 1).
   ================================================================= */
.c-steps{
  display:flex; flex-wrap:wrap; gap:0 var(--r5);
  padding:0 var(--page-x);
  border-bottom:1px solid var(--hairline);
  background:var(--paper);
}
/* body.is-enquire-mode (/start/ only, toggled by start/index.html's inline
   script off the "jla:enquire" event footer-form.js dispatches): landing on
   /start/ via a quick-enquiry link (?enquire=<slug>#contact, or a legacy
   #production/#picture/#artist hash) means the visitor wants the contact
   form, not the 5-step mix & master intake — hide the progress bar so it
   doesn't read as a broken/empty wizard above the form (2026-09-27). */
body.is-enquire-mode .c-steps{display:none;}
.c-step-tab{
  display:flex; align-items:center; gap:6px;
  padding:var(--r3) 0;
  background:none; border:none; cursor:not-allowed;
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  /* mobile audit 2026-09-27 (#3): upcoming tabs were --grey-2 (2.63:1 on
     --paper at 11px uppercase — WCAG AA fail). --grey-1 is the sheet's
     documented "muted/secondary text on paper" token (already load-
     bearing body-copy contrast elsewhere) and is-done already uses it,
     so upcoming now reads the same shade as done — the checkmark glyph
     stays the done/upcoming differentiator, and is-current (--black)
     stays the one unambiguously "active" state. Same token swap in the
     dark room via --grey-1's own dark-mode value, no extra rule needed. */
  text-transform:uppercase; color:var(--grey-1);
  transition:color .2s ease-out;
}
.c-step-tab.is-done{color:var(--grey-1); cursor:pointer;}
.c-step-tab.is-current{color:var(--black); cursor:default;}
.c-step-tab:disabled{pointer-events:none;}
.c-step-tab:not(:disabled):hover, .c-step-tab:not(:disabled):focus-visible{color:var(--accent);}
.c-step-tab-check{display:inline-block; width:11px; font-size:11px; line-height:1; font-weight:400; color:var(--grey-1); visibility:hidden;}
.c-step-tab.is-done .c-step-tab-check{visibility:visible;}
.c-step-tab.is-done .c-step-tab-check::before{content:'\2713';}
.c-steps__num{
  font-size:var(--fs-label);
  margin-right:0.5em;
  color:var(--green-ink);
}
.c-step-tab.is-current .c-steps__num{color:var(--black);}
@media (min-width:900px){
  .c-steps{position:sticky; top:var(--nav-h); z-index:40;}
}
@media (max-width:899px){
  /* Below 900px the five tab labels don't fit the row and flex-wrap
     was letting one item overflow the viewport instead of cleanly
     wrapping (clipped by body{overflow-x:hidden}, e.g. "files &
     references" got cut mid-word). Scroll the row horizontally
     instead, same pattern as a checkout progress bar. */
  .c-steps{position:relative; flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none;}
  .c-steps::-webkit-scrollbar{display:none;}
  .c-step-tab{flex:0 0 auto; white-space:nowrap;}
  /* mobile audit 2026-09-27: the scrollable row's last tab ("03 files &
     references") lands flush against the viewport's right edge with no
     hint there's more to scroll to — reads like clipped/broken content,
     the same "flush to an edge" fault as a hard text cutoff even though
     it's technically scrollable. Fade the row's own right edge out via
     mask instead of adding a DOM element, so it never fights the
     scroll-container's overflow clipping. */
  .c-steps{-webkit-mask-image:linear-gradient(to right, #000 calc(100% - 28px), transparent 100%); mask-image:linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);}
}

/* Phone fix, 2026-09-28: at <=760px even the scroll+fade treatment above
   still opened on a hard-clipped third label ("03 FILES" cut flush at the
   viewport edge, 390px wide) with nothing to signal it scrolls — reads as
   broken, not "swipe for more". Compact the row instead of relying on
   scroll discovery: every step keeps its number (+ done-check) visible at
   all times, but the label text only prints for the current step — same
   "checkout progress" idea, sized to actually fit a phone. This also
   naturally stops the row from needing to scroll on any phone width
   the 391px+ testimonial/other pages test at; the >=761px scroll+mask
   rule above stays as a safety net if a future label is added/lengthened. */
@media (max-width:760px){
  .c-steps{gap:0 calc(var(--r2) - 4px); padding:0 var(--page-x);}
  .c-step-tab{gap:4px; padding:var(--r3) 0;}
  /* upcoming/current tabs don't need the done-check's reserved width once
     labels are gone too — only a done tab keeps the 10px slot, so the
     longest label ("03 files & references" as the current step) has
     room to sit on one line without the row needing to scroll even at
     360px wide. */
  .c-step-tab-check{width:0;}
  .c-step-tab.is-done .c-step-tab-check{width:11px;}
  .c-step-tab-text{display:none;}
  .c-step-tab.is-current .c-step-tab-text{display:inline;}
  .c-steps__num{margin-right:0;}
  .c-step-tab.is-current .c-steps__num{margin-right:0.4em;}
}

.c-row--option{width:100%; text-align:left; background:none; border:none; cursor:pointer; font:inherit;}

/* /start/ step 1 — service chooser (QA 2026-09-28). The rows ran inside
   the panel's own side padding + a 900px cap, so titles sat double-
   indented in the left ~60% with no hairlines (the button reset above
   strips .c-row's border-bottom). Now: full content width like the
   service-page option rows, titles on the page margin, a hairline
   between rows and under the last, both row ends right-aligned on the
   same arrow column, and title + end stay on one line on phones. */
#panel-service{padding:0;}
#panel-service .panel-inner{max-width:none;}
/* the step bar's bottom hairline is the chooser's top rule and the
   footer's top hairline closes the last row, so no rules of its own */
#panel-service .c-rows{border-top:none;}
#panel-service .c-row--option{border-bottom:1px solid var(--hairline);}
#panel-service .c-row--option:last-child{border-bottom:none;}
#panel-service .c-row--option{flex-direction:row; align-items:center; gap:var(--r3);}
#panel-service .c-row--option > .c-row-arr,
#panel-service .c-row-end{flex:none; width:auto;}
#panel-service .c-row-enq{border-left:none; padding-left:0;}
#panel-service .c-row--option:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;}

.c-step{display:none;}
.c-step.is-active{display:block;}
.c-step-actions{
  display:flex; align-items:center; justify-content:space-between; gap:var(--r3);
  margin-top:var(--r5); padding:var(--r4) var(--page-x);
  border-top:1px solid var(--hairline);
}

/* mobile/desktop audit 2026-09-27 (#1): .back-link ships with no rule of
   its own anywhere in the sheet, so every "← back" on /start/ renders as
   the browser's default grey-bevel <button> — reset it to the sitewide
   text-link pattern (same family/size/case as .c-cta, no border/fill,
   green-deep on hover like every other in-page link). All three intake
   paths (mix/production/picture), every step, light + dark room. */
.back-link{
  appearance:none; -webkit-appearance:none; background:none; border:none;
  padding:var(--r2) 0; margin:0; cursor:pointer;
  display:inline-flex; align-items:center; min-height:44px;
  font-family:var(--face); font-size:var(--fs-small); font-weight:500;
  color:var(--black); text-transform:lowercase; letter-spacing:0;
}
.back-link:hover, .back-link:focus-visible{color:var(--green-ink);}
.back-link:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}

/* =================================================================
   .c-nav-menu — hover/focus dropdown panel for the "services" and
   "work" nav items (desktop nav only; the mobile panel lists the same
   links). QA 2026-09-28: was a full-bleed band with the links hard left
   ~800px from their trigger and its bottom edge slicing the page's
   first line. Now a compact panel anchored under its own trigger: it
   hangs from the nav's bottom hairline, left edge on the trigger's
   left edge, paper surface, hairline frame (no shadow, square corners),
   one row per link with a hairline between rows. Links are ink at
   rest in nav label type (uppercase .08em 600); hover/focus/current
   turn the label accent and nudge a trailing arrow — nothing green at
   rest. Behaviour unchanged (nav.js): hover/focus-within opens,
   Escape adds .force-closed.
   ================================================================= */
.nav-item--has-menu{position:relative;}
.nav-links .c-nav-menu{
  position:absolute; left:0; top:100%; z-index:199;
  min-width:260px; width:max-content; max-width:min(360px, calc(100vw - 2 * var(--pad-x)));
  margin-top:0;
  background:var(--paper);
  border:1px solid var(--hairline); border-top:none;
  padding:0;
  display:flex; flex-direction:column; align-items:stretch; gap:0;
  opacity:0; visibility:hidden; pointer-events:none;
  transform:translateY(-4px);
  transition:opacity .14s ease-out, transform .18s ease-out, visibility 0s linear .14s;
}
.nav-links .c-nav-menu a{
  position:relative;
  display:flex; align-items:center; justify-content:space-between; gap:var(--r4);
  height:auto; min-height:48px; width:auto;
  /* left inset = the trigger's own inset, so the menu labels start on
     the same x as the word "services" / "work" above them */
  padding:0 var(--r3) 0 var(--r2);
  font-family:var(--face); font-size:var(--fs-label); font-weight:600;
  letter-spacing:.08em; text-transform:uppercase; white-space:nowrap;
  color:var(--black);
  border:none; border-top:1px solid var(--hairline);
  background:none;
  transition:color .2s ease-out;
}
.nav-links .c-nav-menu a:first-child{border-top:none;}
.nav-links .c-nav-menu a::after{
  /* trailing arrow instead of the top-bar underline: the row itself is
     the target, the arrow is the affordance (matches the site's
     .c-row arrow language). */
  content:'\2192'; position:static; display:block; flex:none;
  width:auto; height:auto; background:none; transform:translateX(-4px);
  font-weight:400; letter-spacing:0; color:var(--grey-2); opacity:0;
  transition:opacity .18s ease-out, transform .25s cubic-bezier(.22,1,.36,1), color .2s ease-out;
}
.nav-links .c-nav-menu a:hover,
.nav-links .c-nav-menu a:focus-visible{color:var(--accent); background:none;}
.nav-links .c-nav-menu a[aria-current="page"]{color:var(--green-ink); background:none;}
html[data-room="dark"] .nav-links .c-nav-menu a::after{color:#fff;}
.nav-links .c-nav-menu a:hover::after,
.nav-links .c-nav-menu a:focus-visible::after{opacity:1; transform:translateX(0); color:var(--accent);}
.nav-links .c-nav-menu a:focus-visible{outline:2px solid var(--accent); outline-offset:-4px;}

.nav-item--has-menu:hover .c-nav-menu,
.nav-item--has-menu:focus-within .c-nav-menu,
.nav-item--has-menu.is-open .c-nav-menu{
  opacity:1; visibility:visible; pointer-events:auto; transform:none;
  transition:opacity .14s ease-out, transform .18s ease-out, visibility 0s linear 0s;
}
/* Escape-key override (nav.js): forces the dropdown shut even while the
   parent link — still inside the item — holds focus and would otherwise
   keep :focus-within true. Cleared by nav.js on the next hover/focus-in. */
.nav-item--has-menu.force-closed .c-nav-menu{
  opacity:0 !important; visibility:hidden !important; pointer-events:none !important;
}
@media (prefers-reduced-motion:reduce){
  .nav-links .c-nav-menu, .nav-links .c-nav-menu a::after{transform:none; transition:none;}
}

/* =================================================================
   proto 1 — "hero = the name"
   Home-page prototype, scoped under body.proto1 so nothing here can
   leak onto the live page. See proto1-spec.md (scratchpad) for the
   full reference-to-decision map. Reuses sitewide tokens/components;
   only overrides what this variation changes.
   ================================================================= */

/* ---- hero: MONOE scale on Borelli's name-only structure ---- */
body.proto1 .hero-name{
  font-size:clamp(72px, 17vw, 272px);
  line-height:.86;
  font-weight:var(--fw-display);
  letter-spacing:-.05em;
}
body.proto1 .hero-sub{
  max-width:38ch;
  margin-top:clamp(20px, 3vw, 40px); /* clears the huge name's descenders (j/g) at proto1 scale */
  font-size:var(--fs-small);
  letter-spacing:.01em;
  color:var(--on-dark-2);
}
body.proto1 .hero-top{padding-bottom:clamp(16px,2.4vw,32px);}

/* ---- services: MONOE row list + one FWD/Inception "intent" block ----
   Golden-ratio-leaning column split (source: ToBeBold's column logic) —
   title/one-liner column vs. price column. Applied via row grid. */
body.proto1 #services-preview .c-row{
  display:grid;
  grid-template-columns:1.6fr 1fr;
  align-items:baseline;
  gap:var(--r3);
}
body.proto1 #services-preview .c-price{justify-self:end; text-align:right;}

/* the one deliberate inversion — mixing + mastering only, never alternated.
   .c-rows is already edge-to-edge (no section-level side padding) and
   .c-row supplies its own page-x inset via the sitewide shorthand, so the
   background alone bleeds full-bleed black without touching margins/
   padding — no need to fight the existing inset. */
body.proto1 #services-preview .c-row.is-flagship{
  background:var(--black);
  border-bottom-color:var(--hairline-inv);
  border-top-color:var(--hairline-inv);
}
body.proto1 #services-preview .c-row.is-flagship .c-row-title b,
body.proto1 #services-preview .c-row.is-flagship .c-price{color:var(--paper);}
body.proto1 #services-preview .c-row.is-flagship .c-row-meta-under{color:var(--on-dark-1);}
body.proto1 #services-preview .c-row.is-flagship .c-price-unit{color:var(--on-dark-2);}
body.proto1 #services-preview .c-row.is-flagship:hover .c-row-title b,
body.proto1 #services-preview .c-row.is-flagship:hover .c-price{color:var(--accent);}

@media (max-width:760px){
  body.proto1 #services-preview .c-row{grid-template-columns:1fr; gap:var(--r1);}
  body.proto1 #services-preview .c-price{justify-self:start; text-align:left;}
}

/* ---- work: CoMinVi warm-grey tonal panel (deepened after review —
   the first pass at #E7E4DB read as barely-there against --paper
   #F3F1EC; CoMinVi's panel needs to register as a clear tonal step,
   not a hairline-level tint) ---- */
body.proto1 #work{background:#DCD7C9;}
body.proto1 #work .c-sechead{border-top-color:#C9C3B2;}
body.proto1 #work .c-players{border-top-color:#C9C3B2;}
body.proto1 #work .c-player{
  border-bottom-color:#C9C3B2;
}
body.proto1 #work .work-row{background:#EFECE2; border-radius:2px;}

/* proto 2 */
/* =================================================================
   PROTO 2 — hero type-play (ToBeBold lead) + CoMinVi grey work panel.
   Scoped entirely to .p2-* so it can't leak onto the live site or any
   other prototype. Uses only tokens theme-v2.css already defines.
   ================================================================= */

/* ---------- hero: one statement, golden-ratio column split ---------- */
.p2-hero .hero-top{display:none;} /* replaces the stock hero-top block */

.p2-hero-grid{
  display:grid;
  grid-template-columns:61.8fr 38.2fr; /* golden-ratio split, per brief */
  align-items:end;
  gap:var(--r4);
  padding:var(--hero-pad-top) var(--page-x) var(--hero-pad-bottom);
}

.p2-statement{display:flex; flex-direction:column; gap:clamp(6px,1vw,14px);}

.p2-line--name{
  font-family:var(--face);
  font-weight:700;
  font-size:clamp(56px, 10.4vw, 168px);
  line-height:.92;
  letter-spacing:-.03em;
  text-transform:lowercase;
  color:var(--paper);
  user-select:none;
}

.p2-line--pitch{
  display:flex; flex-wrap:wrap; align-items:baseline;
  row-gap:.15em; column-gap:.28em;
}
.p2-w{font-family:var(--face); text-transform:lowercase; letter-spacing:-.01em;}
.p2-w--lg{font-size:clamp(28px,4.8vw,72px); font-weight:700; color:var(--paper);}
.p2-w--md{font-size:clamp(22px,3.4vw,52px); font-weight:500; color:var(--paper);}
.p2-w--sm{font-size:clamp(16px,2vw,30px); font-weight:400; color:var(--on-dark-1);}
.p2-w--outline{
  font-size:clamp(28px,4.8vw,72px); font-weight:700;
  color:transparent;
  -webkit-text-stroke:1.5px var(--paper);
  paint-order:stroke;
  margin-inline:.12em; /* fix: was crowding "production," / "and" either side */
}

/* fix: the golden-ratio split read as a stray button, not a considered
   column — a hairline boundary + a right-anchored CTA gives the minor
   column its own bounded edge (flush-right at --page-x), so the split
   reads as two columns the way MONOE/ToBeBold's own flush-left/flush-right
   sections do, not just "text, then a button". */
.p2-cta-col{
  display:flex; justify-content:flex-end; align-items:flex-end;
  height:100%;
  padding-left:var(--r4);
  border-left:1px solid var(--hairline-inv);
}
.p2-cta{margin-top:0;} /* .hero-cta already carries its own spacing; not needed in a grid cell */

@media (max-width:760px){
  .p2-hero-grid{grid-template-columns:1fr; align-items:start; gap:var(--r3);}
  .p2-cta-col{justify-content:flex-start; padding-left:0; border-left:none; padding-top:var(--r2); border-top:1px solid var(--hairline-inv);}
  .p2-cta{width:100%; justify-content:center;}
}

/* ---------- work: CoMinVi tonal grey panel ---------- */
.p2-work-panel{
  background:var(--grey-3);
  border-radius:2px;
  margin:0 var(--page-x);
  padding:var(--r4) 0;
}
.p2-work-panel .work-row{padding-left:var(--r4); padding-right:var(--r4);}
.p2-work-panel .work-row{border-top:none;}
/* fix: .c-players'/.c-player's own hairlines (component defaults, meant
   for a flush-with-the-page list) duplicated the panel's top/bottom edge
   once nested inside a bounded grey panel — drop them here only. */
.p2-work-panel .c-players{border-top:none;}
.p2-work-panel .c-player{border-bottom:none;}
@media (max-width:760px){
  .p2-work-panel{margin:0 var(--r2); padding:var(--r3) 0;}
  .p2-work-panel .work-row{padding-left:var(--r3); padding-right:var(--r3);}
}

/* proto 3 */
/* =================================================================
   PROTO 3 — hero = the wordmark as a graphic (Inception + MONOE
   logo/type interaction). "jl audio" set enormous and cropped off
   the right/bottom edge of a full-bleed black hero; "jacob lewis" +
   tagline + CTA sit small and precise, top-left on the grid, above
   the mark. Marquee runs the full width along the very bottom edge,
   under the mark, per juliaborelli.com. Also: a CoMinVi grey tonal
   panel wrapping "selected work", and FWD-weighted service rows
   (handled page-side). No stock imagery, nothing green at rest.
   ================================================================= */
.hero3{
  position:relative;
  overflow:hidden;
  background:var(--black);
  color:var(--paper);
  border-bottom:1px solid var(--hairline-inv);
  padding-top:var(--nav-h);
  min-height:clamp(520px, 82vh, 760px);
  display:flex;
  flex-direction:column;
  justify-content:space-between;
}

/* ---- small, precise lockup — top-left, on the page grid, sitting
   above the wordmark graphic (z-index), never competing with it ---- */
.hero3-top{
  position:relative; z-index:2;
  padding:clamp(28px,5vw,64px) var(--page-x) 0;
  max-width:34ch;
}
.hero3-name{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600;
  letter-spacing:.08em; text-transform:uppercase;
  color:var(--on-dark-1);
}
.hero3-sub{
  margin-top:var(--r2);
  font-family:var(--face); font-size:var(--fs-body); font-weight:400;
  color:var(--paper); line-height:1.5;
}
.hero3-cta{
  display:inline-flex; align-items:center; gap:var(--r2);
  margin-top:clamp(20px,3vw,32px);
  padding:clamp(12px,1.4vw,16px) clamp(20px,2.6vw,32px);
  font-family:var(--face); font-weight:600; font-size:var(--fs-body); letter-spacing:0; text-transform:lowercase;
  color:var(--black); background:var(--paper);
  border-radius:2px;
  transition:background .2s ease-out, color .2s ease-out;
}
.hero3-cta .arr{transition:transform .35s cubic-bezier(.22,1,.36,1);}
.hero3-cta:hover, .hero3-cta:focus-visible{background:var(--accent); color:var(--paper);}
.hero3-cta:hover .arr{transform:translateX(5px);}

/* ---- the wordmark graphic — huge, cropped bottom/right, identity
   as the image (no stock photo). Sized off viewport width so it
   always overflows the frame rather than fitting inside it. ---- */
.hero3-mark{
  position:absolute; z-index:1;
  right:clamp(-40px,-4vw,-12px);
  bottom:clamp(-18px,-1.6vw,-6px);
  font-family:var(--face);
  font-weight:700;
  letter-spacing:-.045em;
  line-height:.82;
  text-transform:lowercase;
  color:var(--paper);
  font-size:clamp(240px, 30vw, 600px);
  white-space:nowrap;
  user-select:none;
  pointer-events:none;
}

.hero3 .hero-marquee{
  position:relative; z-index:2;
  border-top:1px solid var(--hairline-inv);
  background:var(--black);
}

@media (max-width:760px){
  .hero3{min-height:clamp(420px, 70vh, 600px);}
  .hero3-top{padding-top:clamp(24px,6vw,40px); max-width:none;}
  .hero3-mark{
    right:clamp(-24px,-6vw,-8px);
    bottom:clamp(-14px,-2.4vw,-6px);
    font-size:clamp(130px, 34vw, 240px);
  }
}

/* ---- CoMinVi grey panel: a warm tonal block the "selected work"
   section sits inside of, distinct from the paper page around it.
   No icons, no imagery — just the tonal shift and the players. ---- */
.work-panel{
  background:#DAD6CB;
  border-top:1px solid var(--hairline);
  border-bottom:1px solid var(--hairline);
}
.work-panel #work{padding-top:0; padding-bottom:0;}
.work-panel .c-sechead{border-top:none; padding-top:var(--sec-pad);}
.work-panel .c-players{border-top:1px solid var(--hairline); margin-top:var(--sec-gap);}
.work-panel .c-players, .work-panel .c-player{border-color:var(--hairline);}
.work-panel .c-player{padding-bottom:var(--sec-pad);}
/* proto 4 */
/* =================================================================
   PROTOTYPE 4 — tonal panels (CoMinVi greys + MONOE type).
   Full-bleed sections stepping through the site's own greys —
   paper (hero) -> grey-3 (marquee, the first tonal band) -> grey-2
   (services, 2x2 at desktop) -> paper (selected work, kept light so
   the waveform's dark bars stay legible) -> black (testimonials).
   Everything scoped under body.proto4 / .proto4-* so it never
   touches the live site's shared classes. No icons, nothing
   spinning — CoMinVi's discipline is the grey handling and text
   sitting directly against a tonal block, nothing more.
   ================================================================= */

/* ---- hero: tonal step 1, paper (was the shared dark surface) ---- */
body.proto4 .hero{
  background:var(--paper); color:var(--black);
  border-bottom:1px solid var(--hairline);
}
body.proto4 .hero-name{color:var(--black);}
body.proto4 .hero-sub{color:var(--grey-1);}
body.proto4 .hero-cta{background:var(--black); color:var(--paper);}
body.proto4 .hero-cta:hover, body.proto4 .hero-cta:focus-visible{
  background:var(--accent); color:var(--paper);
}

/* ---- marquee: tonal step 2, grey-3 — the first tonal band ---- */
body.proto4 .hero-marquee{
  background:var(--grey-3);
  border-top:1px solid var(--hairline);
  padding:clamp(28px,4.4vw,56px) 0;
}
body.proto4 .marquee-group span{color:var(--black); font-weight:600;}
body.proto4 .marquee-group span::after{color:var(--grey-1);}

/* ---- services: tonal step 3, grey-2, 2x2 panel grid.
   --hairline resolves to --grey-2 itself, so a divider drawn in it
   would be invisible against this exact panel — every border here
   uses --grey-1 instead, the same "on-tone but readable" fix as the
   label/body copy below. ---- */
.proto4-services{background:var(--grey-2); border-top:1px solid var(--grey-1);}
.proto4-services .proto4-lbl{
  display:block;
  padding:var(--sec-pad) var(--page-x) var(--sec-gap);
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--black);
}
.proto4-svc-grid{
  display:grid; grid-template-columns:1fr;
  border-top:1px solid var(--grey-1);
}
.proto4-svc{
  display:flex; flex-direction:column; gap:var(--r3);
  padding:var(--r6) var(--page-x);
  border-bottom:1px solid var(--grey-1);
  text-decoration:none;
  transition:background .2s ease-out;
}
.proto4-svc b{
  font-family:var(--face); font-weight:var(--fw-h1); letter-spacing:var(--ls-h1);
  font-size:clamp(24px,3.2vw,40px); line-height:1.08;
  text-transform:lowercase; color:var(--black); transition:color .2s ease-out;
}
.proto4-svc p{
  font-family:var(--face); font-size:var(--fs-body); font-weight:400; color:var(--black); opacity:.66;
  max-width:36ch; line-height:1.55;
}
.proto4-price{
  display:block; margin-top:var(--r1);
  font-family:var(--face); font-weight:600; font-size:var(--fs-label); letter-spacing:.08em;
  text-transform:uppercase; color:var(--black);
}
.proto4-svc:hover, .proto4-svc:focus-visible{background:var(--grey-3);}
.proto4-svc:hover b, .proto4-svc:focus-visible b{color:var(--accent);}
.proto4-svc:hover .proto4-price, .proto4-svc:focus-visible .proto4-price{color:var(--accent);}
@media (min-width:760px){
  .proto4-svc-grid{grid-template-columns:1fr 1fr;}
  .proto4-svc{min-height:clamp(200px,20vw,260px); justify-content:center;}
  .proto4-svc:nth-child(odd){border-right:1px solid var(--grey-1);}
}

/* ---- selected work: back to paper (waveform needs a light ground);
   markup/script/data-peaks are the sitewide player, untouched. ---- */
.proto4-work{background:var(--paper); border-top:1px solid var(--hairline);}

/* ---- testimonials: tonal step 4, black. Section already carries
   .dark (covers .c-sechead label/heading colour); these fill the
   gaps .dark doesn't reach — cards, quote, attribution, stars. ---- */
.proto4-words{background:var(--black); border-top:1px solid var(--hairline-inv);}
.proto4-words .c-cards{border-top:1px solid var(--hairline-inv);}
.proto4-words .c-card{border-bottom:1px solid var(--hairline-inv);}
.proto4-words .c-cards .c-card:nth-child(2n){border-left:1px solid var(--hairline-inv);}
.proto4-words .c-card-quote{color:var(--paper);}
.proto4-words .c-card-attr{color:var(--on-dark-1);}
.proto4-words .c-card-attr b{color:var(--paper);}
.proto4-words .c-card-stars svg{fill:var(--paper);}
/* fix: #words .words-stars .star.is-filled in theme-v2.css carries an
   ID selector, which outranks the class-only override above, so the
   filled stars stayed --black (invisible on this section's black
   ground). Match its specificity (ID + 2 classes) plus this section's
   own scope class to win. */
#words.proto4-words .words-stars .star.is-filled{fill:var(--paper); stroke:var(--paper);}
/* proto 5 */
/* =================================================================
   PROTO 5 — black-first (FWD + Inception): hero/marquee/services open
   on black and stay black; work+testimonial switch to paper with a
   CoMinVi grey tonal panel; contact+footer return to black. Three
   deliberate blocks, no alternating stripes. Sources: FWD (oversized
   full-width index rows, monochrome discipline, wordmark-as-graphic),
   Inception (identity-forward black), ToBeBold (weight-contrast hero
   type play), CoMinVi (warm-grey tonal panel behind content), STEEL
   (phone-width cleanliness), juliaborelli.com (marquee under lockup),
   mickeynox.com (services first, one nav CTA).
   ================================================================= */

/* ---- hero: "jacob lewis" — ToBeBold weight contrast between the two
   words, monochrome (no colour swap, weight/opacity only) ---- */
.proto5-name{display:flex; flex-wrap:wrap; gap:.22em; align-items:baseline;}
.proto5-w{display:inline-block;}
.proto5-w--light{font-weight:300; color:var(--on-dark-1);}
.proto5-w--bold{font-weight:800; color:var(--paper);}

/* ---- services index: FWD oversized full-width rows, paper text on
   black, price right. Row scale steps up from the shared .c-row--md
   default toward hero-adjacent scale; still lowercase/no icons. ---- */
.proto5-idx.c-rows{border-top-color:var(--hairline-inv);}
.proto5-idx .c-row{border-bottom-color:var(--hairline-inv); padding-top:var(--r6); padding-bottom:var(--r6);}
.proto5-idx .c-row--xl .c-row-title b{font-size:clamp(32px,6.4vw,84px); color:var(--paper);}
.proto5-idx .c-row-meta-under{color:var(--on-dark-2);}
.proto5-idx .c-price{
  font-family:var(--face); font-weight:600; font-size:var(--fs-label); letter-spacing:.04em;
  color:var(--paper); white-space:nowrap; transition:color .2s ease-out;
}
.proto5-idx .c-price .c-price-unit{color:var(--on-dark-1); font-weight:600;}
.proto5-idx .c-row:hover .c-row-title b,
.proto5-idx .c-row:focus-visible .c-row-title b{color:var(--accent);}
.proto5-idx .c-row:hover .c-price,
.proto5-idx .c-row:focus-visible .c-price{color:var(--accent);}
@media (max-width:640px){
  .proto5-idx .c-row--xl .c-row-title b{font-size:clamp(28px,9vw,40px);}
  /* .c-row switches to flex-direction:column + align-items:flex-start
     at this breakpoint, which sizes .c-row-title to its own
     max-content width instead of stretching to the row — at the
     oversized proto5 scale that pushes real text ("mixing + mastering")
     past the viewport edge and forces the whole page to scroll
     horizontally, clipping the footer icons too. Constrain it back
     to the row's own width so long titles wrap instead of bleeding. */
  .proto5-idx .c-row-title{width:100%; max-width:100%;}
  .proto5-idx .c-row--xl .c-row-title b{overflow-wrap:break-word;}
}

/* ---- CoMinVi tonal panel: work player + testimonial card sit on a
   warm grey inset panel against the paper section, not flush to the
   page edge — the section head/label stays on paper. ---- */
.proto5-panel{
  margin:0 var(--page-x) var(--sec-pad);
  background:var(--grey-3);
  border-radius:2px;
}
.proto5-panel .c-players, .proto5-panel .c-cards{border-top:none;}
.proto5-panel .work-row{border-top:1px solid var(--grey-2);}
.proto5-panel .work-row:first-child{border-top:none;}
.proto5-panel .c-card{padding:var(--r6) var(--r6);}
@media (max-width:640px){
  .proto5-panel{margin-left:var(--r3); margin-right:var(--r3);}
}

/* fix: contact-cta returns to black in this prototype (proto5 puts
   .dark on the section), but .gform-submit is hardcoded
   background:var(--black) sitewide (every other page keeps this
   section on --paper), so the button vanished into the black ground
   here — paper text on a black button on a black section. Flip it
   for this one dark instance only. */
.contact-cta.dark .gform-submit{background:var(--paper); color:var(--black);}
.contact-cta.dark .gform-submit:hover, .contact-cta.dark .gform-submit:focus-visible{
  background:var(--accent); color:var(--paper);
}

/* proto 6 */
/* =================================================================
   HOME (REFERENCE PORT) — MONOE section skeleton + ToBeBold hero type
   Scoped to body.home only (index.html sets this class) so nothing
   here touches /work/ or any inner page reusing .hero/.work-row/etc.

   Reference: MONOE "Main page/1920" desktop mockup — black hero with
   a 2-col split (headline left ~55%, full-bleed image col right
   ~45%), continuing straight into a light "Our latest arrivals/."
   list, closing on a full-bleed dark photo block. ToBeBold's landing
   hero — one wordmark statement in mixed weight/tone, a micro
   caption directly under it, tight leading, generous negative space.
   We have no reference photography, so every image slot the two
   references fill with a photo becomes either a full-bleed black
   panel holding one large outlined word (hero) or the waveform
   player itself (closing work section) — never stock imagery.
   ================================================================= */

/* ---- hero: 2-col split (MONOE), fused mixed-weight statement (ToBeBold).
   MONOE's own hero block reads monumental — the headline column runs
   almost the full column width and the block itself is tall relative
   to the page (nav + 2-line headline + image column together run
   ~40% of the page's own width before the statement block even
   starts). We have no image, so the scale has to come from type: the
   headline is pushed to fill the column, the hero gets real vertical
   air instead of a short lockup band. ---- */
.home .hero-grid{display:block;}
.home .hero-top{padding-top:clamp(64px,10vw,152px); padding-bottom:clamp(32px,4vw,64px);}
.home .hero-name{font-size:clamp(64px, 12.5vw, 208px); line-height:.86;}
.home .hero-name .wt-reg{font-weight:500;}
.home .hero-name .wt-bold{font-weight:800;}
.home .hero-visual{display:none;}
@media (min-width:900px){
  .home .hero-grid{
    display:grid; grid-template-columns:11fr 9fr; align-items:stretch;
  }
  .home .hero-visual{
    display:flex; align-items:center; justify-content:center;
    padding:clamp(12px,1.6vw,24px);
    border-left:1px solid var(--hairline-inv);
    min-height:100%;
  }
  .home .hero-visual-word{
    font-family:var(--face); font-weight:800; letter-spacing:-.03em;
    text-transform:lowercase; line-height:.9;
    font-size:clamp(72px, 17vw, 264px);
    color:transparent;
    -webkit-text-stroke:1.5px var(--on-dark-1);
    text-stroke:1.5px var(--on-dark-1);
    user-select:none;
    text-align:center;
  }
  @supports not (-webkit-text-stroke:1px #000){
    .home .hero-visual-word{color:var(--on-dark-2);}
  }
}

/* ---- services list: closer to MONOE's "Our latest arrivals/." lead
   scale — reuse the existing .c-row--lg variant so no new CSS beyond
   the size bump is needed. ---- */

/* ---- work section: MONOE's closing full-bleed dark block. The
   waveform player is the only "image" available, so it takes the
   photo's role — same component, dark surface, on-dark type. ---- */
.home #work.dark .work-row{border-bottom-color:var(--hairline-inv);}
.home #work.dark .work-meta .v{color:var(--paper);}
.home #work.dark .work-meta .k{color:var(--on-dark-1);}
.home #work.dark .work-meta a.k:hover,
.home #work.dark .work-meta a.k:focus-visible{color:var(--accent);}
.home #work.dark .work-meta .v .dash{color:var(--on-dark-2);}
.home #work.dark .play-btn{border-color:var(--hairline-inv); color:var(--paper);}
.home #work.dark .play-btn:hover,
.home #work.dark .play-btn:focus-visible{border-color:var(--accent);}
.home #work.dark .time{color:var(--on-dark-1);}
.home #work.dark .c-players{border-top-color:var(--hairline-inv);}
.home #work.dark .c-player{border-bottom-color:var(--hairline-inv);}

/* proto 7 */
/* home (final) */
/* =================================================================
   HOME (FINAL) — proto 3's hero on proto 5's colouring/layout.
   Jacob's call after reviewing prototypes 1-6: keep proto 3's
   identity-forward wordmark hero (name/line/CTA small and precise
   top-left, "jl audio" bleeding off the right/bottom edge of a
   full-bleed black frame), but at real reading scale — proto 3 sized
   the name/line as a tiny meta label, here the name runs at the same
   --fs-h1 the rest of the site uses for a page title and the line at
   --fs-body, so the hero opens with something a client actually
   reads instead of a caption. Everything below the hero is proto 5's
   three-block colouring: services stays black (oversized FWD index,
   scoped classes shared with proto 5 — .proto5-idx/.c-row--xl —
   intentionally reused rather than forked, same intended look);
   work + testimonial sit on paper as plain hairline rows, no CoMinVi
   panel (Jacob: a grey block in the middle of the page is tacky, so
   this deliberately skips the .work-panel/.proto5-panel treatment
   both protos used); contact + footer close on black, form fields
   flipped to paper-on-black since the sitewide .gfield styling
   assumes a paper surface everywhere else. ================================================================= */

/* ---- hero: proto 3 structure, real-size type ---- */
.hf-hero{
  position:relative;
  overflow:hidden;
  background:var(--black);
  color:var(--paper);
  border-bottom:1px solid var(--hairline-inv);
  padding-top:var(--nav-h);
  /* close to proto 3's own clamp(520,82vh,760) — tried pulling this
     in to close the black space below the CTA, but the top block is
     taller now (h1 name + body line + real CTA vs. proto 3's tiny
     label), so a shorter box made the mark's top overlap the CTA
     button instead. Proto 3's generous height is load-bearing, not
     just empty air — it's the clearance the huge mark needs under a
     real-scale lockup. Left close to its original value. */
  min-height:clamp(480px, 76vh, 720px);
  display:flex;
  flex-direction:column;
  justify-content:space-between;
}
.hf-top{
  position:relative; z-index:2;
  padding:clamp(28px,5vw,64px) var(--page-x) 0;
  max-width:46ch;
}
.hf-name{
  font-family:var(--face); font-size:var(--fs-h1); font-weight:var(--fw-h1); letter-spacing:var(--ls-h1);
  line-height:.98; text-transform:lowercase; color:var(--paper);
}
.hf-sub{
  margin-top:var(--r2);
  max-width:44ch;
  font-family:var(--face); font-size:var(--fs-body); font-weight:400;
  color:var(--on-dark-1); line-height:1.5;
}
/* ---- the wordmark graphic — same treatment as proto 3's .hero3-mark,
   own class so proto 3's page is untouched. Huge, cropped bottom/right,
   identity as the image, no stock photo. (The dot-only "j" reads
   ambiguous close-up at this scale — checked against proto 3 itself,
   same artifact there: the descender sits under the opaque marquee
   strip in both. Faithful to the approved prototype, left alone.) ---- */
.hf-mark{
  position:absolute; z-index:1;
  right:clamp(-40px,-4vw,-12px);
  bottom:clamp(-18px,-1.6vw,-6px);
  font-family:var(--face);
  font-weight:700;
  letter-spacing:-.045em;
  line-height:.82;
  text-transform:lowercase;
  color:var(--paper);
  font-size:clamp(240px, 30vw, 600px);
  white-space:nowrap;
  user-select:none;
  pointer-events:none;
}
.hf-hero .hero-marquee{
  position:relative; z-index:2;
  border-top:1px solid var(--hairline-inv);
  background:var(--black);
}
@media (max-width:760px){
  .hf-hero{min-height:clamp(420px, 66vh, 580px);}
  .hf-top{padding-top:clamp(24px,6vw,40px); max-width:none;}
  .hf-mark{
    right:clamp(-24px,-6vw,-8px);
    bottom:clamp(-14px,-2.4vw,-6px);
    font-size:clamp(130px, 34vw, 240px);
  }
}

/* ---- contact form on black: .gfield assumes a paper surface
   everywhere else on the site (black text, grey-2 underline), which
   is illegible against this section's black ground — flip to paper
   text / on-dark underline here, same pairing .gform-submit already
   gets from the proto5 dark-button fix below. ---- */
.contact-cta.dark .gfield label{color:var(--on-dark-1);}
.contact-cta.dark .gfield input, .contact-cta.dark .gfield textarea{
  color:var(--paper); border-bottom-color:var(--hairline-inv);
}
.contact-cta.dark .gfield input:focus, .contact-cta.dark .gfield textarea:focus{
  border-bottom-color:var(--accent);
}

/* =================================================================
   home — one build (2026-09-22, hero fix pass)
   monoe-editorial x borelli-pacing. Signature move: a MONOE-style
   split hero — the name sits solid paper-on-black at left (legible
   at a glance, no photo clipped into the letterforms), real-hero.jpg
   (the motion-blurred engineer) runs full-bleed edge-to-edge on the
   right as its own panel, with the tonal-grey hard step (grayscale +
   one flat scrim, no gradient band) keeping the seam readable.
   Display face: Instrument Sans (a geometric/neo-grotesk close to Bw
   Modelica, distinct from Inter) for headlines; Inter stays for
   body/meta. Reduced-motion collapses every reveal to its final
   state — see the generic [data-rv] rules at the end.
   ================================================================= */
:root{
  --face-display: 'Instrument Sans', var(--face);
}

/* ---- hero: split MONOE layout — solid name/line/button at left,
   full-bleed photo panel at right, marquee tight under, fills the
   first viewport (reuses the existing .hero-marquee/.marquee-track
   machinery untouched). ---- */
.hero-one{
  position:relative; overflow:hidden; z-index:0;
  display:flex; flex-direction:column;
  height:100vh; height:100svh; min-height:640px; max-height:1080px;
  background:var(--black); color:var(--paper);
  border-bottom:1px solid var(--hairline-inv);
  padding-top:var(--nav-h);
}
.hero-one::before{
  content:'';
  position:absolute; inset:0; z-index:0;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.05 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity:.35; mix-blend-mode:screen; pointer-events:none; z-index:3;
}
.hero-one-grid{
  position:relative; flex:1 1 auto; min-height:0;
  display:grid; grid-template-columns:1fr; grid-template-rows:minmax(0,1fr);
}
.hero-one-inner{
  position:relative; z-index:2; grid-column:1; grid-row:1; height:100%;
  display:flex; flex-direction:column; justify-content:center;
  padding:var(--hero-pad-top) var(--page-x) var(--hero-pad-bottom);
}
.hero-one-name{
  font-family:var(--face-display);
  font-weight:700;
  font-size:clamp(56px, 7.8vw, 138px);
  line-height:.9;
  letter-spacing:-.03em;
  text-transform:lowercase;
  color:var(--paper);
}
.hero-one-tagline{
  margin-top:clamp(12px,1.8vw,20px);
  max-width:40ch;
  font-family:var(--face); font-size:var(--fs-body); font-weight:400;
  color:var(--on-dark-1); line-height:1.5;
}
/* content-width button, not a stretched flex item (hero-one-inner is a
   flex column; an unstyled <a> blockifies and stretches full-width by
   default, hence the explicit inline-flex + align-self here). */
.hero-one .hero-cta{
  display:inline-flex; align-self:flex-start; align-items:center; gap:var(--r2);
  margin-top:clamp(14px,2.2vw,26px);
  padding:clamp(14px,1.6vw,18px) clamp(28px,3vw,36px);
  font-family:var(--face); font-weight:600; font-size:var(--fs-body); letter-spacing:0; text-transform:lowercase;
  color:var(--paper); background:transparent;
  border:1px solid var(--hairline-inv);
  border-radius:2px;
  transition:background .2s ease-out, color .2s ease-out, border-color .2s ease-out;
}
.hero-one .hero-cta .arr{transition:transform .35s cubic-bezier(.22,1,.36,1);}
.hero-one .hero-cta:hover, .hero-one .hero-cta:focus-visible{background:var(--paper); color:var(--black); border-color:var(--paper);}
.hero-one .hero-cta:hover .arr{transform:translateX(5px);}
.hero-one .hero-marquee{position:relative; z-index:2; flex:none; padding:clamp(8px,1.1vw,12px) 0;}

/* ---- hero photo panel: full-bleed right half, tonal-grey hard-step
   scrim at the seam (flat, not a gradient band) for contrast against
   the name/line/button, which stay clear of the image entirely. ---- */
.hero-one-panel{
  display:none;
  position:relative; grid-column:2; grid-row:1; height:100%;
  overflow:hidden; border-left:1px solid var(--hairline-inv);
}
.hero-one-panel img{
  width:100%; height:100%; object-fit:cover; display:block;
  filter:grayscale(1) contrast(1.15) brightness(.82);
}
@media (min-width:900px){
  .hero-one-grid{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);}
  .hero-one-panel{display:block;}
}

/* ---- services: paper panel + hairline rules, production first, split
   instrument column on wide viewports. (2026-09-23 dark-block removal —
   was black/grain, fights the light-grey site; now the page's own paper
   surface + hairline rule, same treatment as .bio-panel.) ---- */
.svc-panel{position:relative; overflow:hidden; background:var(--paper); border-bottom:1px solid var(--hairline);}
.svc-panel::before{content:none;}
.svc-panel.dark .lbl{color:var(--grey-1);}
.svc-grid{position:relative; z-index:2; display:grid; grid-template-columns:1fr;}
.svc-rows{padding-bottom:var(--r6);}
.svc-rows .c-sechead{padding:var(--sec-pad) var(--page-x) var(--sec-gap);}
/* no margin here: .c-row already insets its own left/right edge with
   padding:var(--row-pad) var(--page-x) (same as .c-sechead's own
   padding above it), so an extra margin:var(--page-x) double-indented
   the rows past the "services" label/heading gutter at 390px (services
   index page audit). */
.svc-rows .c-rows{border-top:1px solid var(--hairline);}
.svc-rows .c-row{border-bottom-color:var(--hairline);}
.svc-rows .c-row-title b{color:var(--black);}
.svc-rows .c-row-meta-under{color:var(--grey-1);}
.svc-rows .c-price{color:var(--black);}
.svc-rows .c-price .c-price-unit{color:var(--grey-1);}
.svc-rows .c-row:hover .c-row-title b, .svc-rows .c-row:focus-visible .c-row-title b,
.svc-rows .c-row:hover .c-price, .svc-rows .c-row:focus-visible .c-price{color:var(--accent);}
.svc-image{display:none; position:relative; background:var(--paper);}
/* the static panel-services.jpg waveform render is a near-black frame —
   reads as a black block against the paper page (2026-09-23 black-block
   sweep). Hidden in favour of the live .instrument--vu canvas already in
   this same panel (data-instrument-host), which draws its own hairline
   trace straight onto --paper, no separate art asset needed. */
.svc-image img{display:none;}
/* ---- home only: 4 stacked frames crossfading per pinned service row
   (see motion.js data-svc-swap). The plain single-image .svc-image use
   on /services/ never gets the .svc-art class, so it's untouched. ---- */
.svc-image .svc-art{position:absolute; inset:0; opacity:0; transition:opacity .5s ease-out; will-change:opacity;}
.svc-image .svc-art.is-active{opacity:1;}
@media (prefers-reduced-motion:reduce){
  .svc-image .svc-art{transition:none;}
}
@media (min-width:900px){
  .svc-grid{grid-template-columns:1fr;} /* owner 2026-09-26: the right-hand image/instrument column is gone, no empty gutter */
  .svc-image{display:block; border-left:1px solid var(--hairline); min-height:100%;}
  /* fill the sticky block to a full screen so the instrument panel
     never reads as cropped where work-tiles rises over it (2026-09-22). */
  .svc-panel{min-height:100vh; min-height:100svh;}
}

/* ---- selected work: editorial tile grid, one photographic identity
   per track (grid art already scoped per song), waveform player
   unchanged on a paper card under the image.
   Sizing (2026-09-22, measured against juliaborelli.com/mickeynox.com
   — see /tiles/MEASURE.md): neither reference runs large square cover
   art — Borelli's project list carries zero imagery at all, Nox caps
   his project embeds at ~26-28vw and always balances them against a
   text column. Covers here stay square/full-colour (still the job's
   own cover art, not removed) but are capped at the same ~26vw scale
   instead of eating a full 1/3-viewport column, with real whitespace
   (28px gap) between tiles instead of a hairline-mosaic edge-to-edge
   grid. ---- */
.work-tile-grid{
  display:grid; grid-template-columns:1fr; gap:var(--r6);
  border-top:1px solid var(--hairline); border-bottom:1px solid var(--hairline);
  padding-block:var(--r6);
}
/* fix-align (2026-10-21): tiles fill their columns and the grid's outer
   edges sit on the page gutter (was: tiles capped at 26vw and centred in
   thirds, so cover edges missed the heading's left edge). 2-up on tablet. */
@media (min-width:600px){
  .work-tile-grid{grid-template-columns:repeat(2,minmax(0,1fr)); gap:28px; padding-inline:var(--page-x);}
}
@media (min-width:900px){
  .work-tile-grid{grid-template-columns:repeat(3,minmax(0,1fr)); gap:28px;}
}
.work-tile{background:var(--paper); display:flex; flex-direction:column; width:100%;}
.work-tile-img{position:relative; aspect-ratio:1/1; overflow:hidden; width:100%;}
.work-tile-img img{
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .6s cubic-bezier(.16,1,.3,1);
}
.work-tile:hover .work-tile-img img, .work-tile:focus-within .work-tile-img img{
  transform:scale(1.045);
}
.work-tile-card{padding:var(--r3) 0 0; flex:1; display:flex; align-items:center;}
#work .work-tile-card .work-row{
  width:100%; padding:0; border-bottom:none;
  grid-template-columns:1fr auto; grid-template-areas:"meta time" "wave wave";
  row-gap:var(--r2);
}
#work .work-tile-card .work-meta .v{font-size:clamp(15px,1.7vw,17px); text-wrap:balance;}
#work .work-tile-card .wave{height:40px;}
@media (max-width:760px){
  /* Root-cause fix (2026-09-26, Jacob flagged from phone: "the margins
     are so tight ... squeezes right up"). .work-tile-grid carried zero
     padding-inline below the 900px 3-col breakpoint, so tiles — cover
     art, title/time row, waveform — ran flush to the viewport edge.
     The old fix here only padded .time by 16px as a band-aid; the real
     gutter belongs on the grid so every element (image, title, player)
     shares one consistent inset, same as the rest of the site's --page-x
     rhythm. Desktop/tablet (>=768px, before the 900px 3-col switch) is
     intentionally left alone — Jacob asked for pixel-identical there. */
  .work-tile-grid{padding-inline:var(--page-x);}
}
@media (prefers-reduced-motion:reduce){
  .work-tile-img img{transition:none;}
}

/* ---- generic scroll-reveal + orchestrated load stagger for every
   [data-rv] element sitewide (nav-safe: no-JS/reduced-motion users
   always see full content — see the existing sweep script). ---- */
/* qa-fix C (2026-09-28): faster, softer — starts at 35% opacity (never a
   near-invisible ghost), 10px, .32s; tighter stagger. Same values as
   motion.css (home). */
html.js [data-rv]{
  opacity:.35; transform:translateY(10px);
  transition:opacity .32s cubic-bezier(.2,.7,.3,1), transform .32s cubic-bezier(.2,.7,.3,1);
}
html.js [data-rv].in{opacity:1; transform:none;}
html.js [data-rv="2"]{transition-delay:.04s;}
html.js [data-rv="3"]{transition-delay:.08s;}
html.js [data-rv="4"]{transition-delay:.12s;}
@media (prefers-reduced-motion:reduce){
  html.js [data-rv]{opacity:1; transform:none; transition:none;}
}

/* ---- large headline mask/line reveals: split into words/lines,
   masked under overflow:hidden, translateY 100%->0, 60ms stagger.
   Reuses the same [data-rv] viewport sweep (index.html inline script
   now also queries [data-split]) — no separate JS system. ---- */
.split-line{display:block; overflow:hidden;}
.split-line-in{display:block; will-change:transform;}
html.js [data-split] .split-line-in{
  transform:translateY(100%);
  transition:transform .7s cubic-bezier(.16,1,.3,1);
}
html.js [data-split].in .split-line-in{transform:translateY(0);}
html.js [data-split] .split-line:nth-child(2) .split-line-in{transition-delay:.06s;}
html.js [data-split] .split-line:nth-child(3) .split-line-in{transition-delay:.12s;}
html.js [data-split] .split-line:nth-child(4) .split-line-in{transition-delay:.18s;}
@media (prefers-reduced-motion:reduce){
  html.js [data-split] .split-line-in{transform:none; transition:none;}
}

@media (max-width:640px){
  .hero-one-name{font-size:clamp(56px,17vw,96px);}
}

/* =================================================================
   forms — one build (2026-09-22)
   /start/, /pricing/, /testimonial/, /thanks/, /links/ and 404 audited
   against the approved home build. None of these pages needed a new
   visual language — the shared c-pagehead/c-group/c-row--option/
   c-fieldset/c-steps vocabulary they already run on IS the home's
   rhythm (hairlines, --page-x edge, fluid clamp() type, nothing green
   at rest). Home itself only reaches for the Instrument Sans display
   face on the one literal hero name — every other heading site-wide,
   home's own included, stays on Inter — so no display-face swap was
   introduced here either; that would have been a mismatch, not a fix.

   The real gap was drift, not language: /thanks/ and 404 were each
   still carrying a full self-contained <style> block from BEFORE the
   component vocabulary existed — dead rules (.heading/.content/.lbl/
   .links/.link/.page-wrapper/.ph-watermark) plus a duplicate .contact-
   cta/.footer/.gform fork that referenced undefined custom properties
   (--viridian/--white/--mono/--sans/--gray/--mint), so hover states on
   the shared contact form/footer silently no-opped on those two pages
   only. Both blocks are now removed in favour of the one real,
   working copy already in theme-v2.css — same as /pricing/, /start/,
   and /testimonial/, which never had the fork. /start/, /pricing/ and
   /testimonial/ each still had a smaller dead rule left over the same
   way (.start-hero / .closing-sign+.sheet-footer / .tst-hero) — also
   removed, page-specific CSS should only ever contain rules the page
   actually uses.

   /thanks/ loses its bespoke full-bleed background watermark (a
   different treatment to every other page's .c-pagehead-watermark)
   for the one component every other inner page already uses — see the
   updated markup — so a page a client lands on straight after
   submitting the contact form doesn't read as a different site. It
   keeps its intentionally minimal, nav-less shell (a small "jl audio"
   link home instead of the full nav bar) since that's a content
   decision, not a style one; .mini-nav below just gives that link the
   nav-mark's own type treatment with page-edge padding instead of
   duplicating it.
   ================================================================= */
#page-thanks .mini-nav{
  display:flex; align-items:center;
  padding:var(--r3) var(--page-x) 0;
  font-family:var(--face); font-weight:500; font-size:18px; letter-spacing:-.01em;
  text-transform:lowercase; color:var(--black);
  transition:color .2s ease-out;
}
#page-thanks .mini-nav:hover, #page-thanks .mini-nav:focus-visible{color:var(--accent);}

/* =================================================================
   services — one build (2026-09-22)
   Restyles the services overview list and the four service-detail
   bodies to the home page's rhythm, reusing home's own components
   rather than inventing new ones:
   - overview services list -> home's .svc-panel/.svc-grid/.svc-rows/
     .svc-image split (same classes, same rules, second page reusing
     the home block) with grid-noise.jpg (abstract, not a specific
     client's art) as the panel image.
   - "options" rows on the four detail pages -> the same dark/grain
     treatment via a new .opt-panel wrapper (paired with the existing
     .dark utility for the border/label colour it already handles),
     recolouring .c-row-title/.c-row-meta-under/.c-row__addon/.c-price
     for the black surface — markup, add-on line and prices unchanged.
   - "what to send / what you get" columns, the turnaround line and
     the #prep accordion keep their existing paper styling (already
     built on the same tokens as home); only [data-rv] reveal hooks
     are added here so they join the sitewide scroll-reveal.
   Sechead labels on the overview page ("services"/"how it works")
   move from a plain <h2> to the home's label-only pattern (h2.lbl —
   same tag for a11y heading structure, home's small-caps look) so
   both pages read as the one site.
   ================================================================= */

/* ---- options: paper panel matching the rest of the page (2026-09-23
   dark-block removal — was a black/grain band, fights the light-grey
   site; now the same paper surface, hairline rules, existing type.
   .dark stays in the markup for legacy hooks but no longer darkens the
   surface — the .c-group__label/.c-price grey-1 overrides below were a
   leftover from when this WAS a black panel (on-dark still needed
   contrast); now that it's plain paper, labels/prices fall through to
   the sitewide --green-ink accent instead of being forced grey (green3
   pixel audit, 2026-09-23: found "options" rendering flat grey on
   /services/mixing/ etc while every other label/price on the same
   paper surface went green-ink). */
.opt-panel{
  position:relative; overflow:hidden;
  background:var(--paper);
  padding-bottom:var(--r2);
}
.opt-panel::before{content:none;}
.opt-panel > *{position:relative; z-index:1;}
/* .opt-panel keeps the "dark" class in its markup as a legacy hook, but
   the panel itself is paper now (see comment above) — the sitewide
   `.dark .c-group__label{color:var(--on-dark-1)}` rule (built for real
   black surfaces) was still matching and rendering near-white text on
   this light panel (near-invisible). Pin it back to the same green-ink
   every other label on paper gets; this selector's own specificity + its
   later position in the file both outrank that stale `.dark` rule. */
.opt-panel .c-group__label{color:var(--green-ink);}
.opt-panel .c-row-title b{color:var(--black);}
.opt-panel .c-row-meta-under{color:var(--grey-1);}
.opt-panel .c-row__addon{color:var(--grey-1);}
.opt-panel .c-row--option{border-bottom-color:var(--hairline);}
.opt-panel .c-row--option:hover .c-row-title b,
.opt-panel .c-row--option:hover .c-price{color:var(--accent);}

/* ---- services overview sechead: home's label-only heading, on the
   page's own <h2> so heading structure is unchanged. ---- */
.c-sechead h2.lbl{margin:0;}

/* =================================================================
   about+faq — one build (2026-09-22)
   Same monoe-editorial x borelli-pacing language as home: paper/
   black/warm-grey, hairline rows, label -> hairline -> rows, one
   accent-on-hover. Nothing new invented — both pages reuse home's
   tonal-grey hard-step split and the shared .c-row hover affordance.
   ================================================================= */

/* ---- about bio: MONOE split — copy solid paper-on-black at left
   (reuses .lbl/.dark colour rules already sitewide), a waveform
   render from one of Jacob's own masters full-bleed at right with
   the same tonal-grey hard-step + grain as home's hero/services
   panels. No stock imagery, no studio/gear/person shots. ---- */
/* Paper panel (2026-09-23 dark-block removal — was black/grain, fights
   the light-grey site; now the page's own paper surface + hairline
   rule). .bio-image keeps its own real photo untouched. */
.bio-panel{position:relative; overflow:hidden; background:var(--paper); border-bottom:1px solid var(--hairline);}
.bio-panel::before{content:none;}
.bio-panel.dark .lbl{color:var(--grey-1);}
.bio-grid{position:relative; z-index:2; display:grid; grid-template-columns:1fr;}
.bio-copy{
  padding:var(--sec-pad) var(--page-x) var(--r6);
  display:flex; flex-direction:column; gap:var(--r4);
}
.bio-copy .lbl{margin-bottom:var(--r1);}
.bio-copy p{
  font-family:var(--face); font-size:var(--fs-body); font-weight:400;
  color:var(--grey-1); line-height:1.55; max-width:50ch;
}
.bio-copy p:first-child{font-size:calc(var(--fs-body) + 2px); color:var(--black);}
/* live hairline scope panel (owner note 7, 2026-09-23) — replaces the old
   dark waveform-art photo. Same footprint, but a light --paper surface
   with a canvas-drawn oscilloscope-style trace (see the inline script at
   the foot of about/index.html); a static CSS graticule line is the
   no-JS fallback so the panel is never blank. */
.bio-image{
  display:none; position:relative; background:var(--paper);
  background-image:linear-gradient(to bottom, transparent calc(50% - 1px), var(--hairline) calc(50% - 1px), var(--hairline) calc(50% + 1px), transparent calc(50% + 1px));
}
.bio-scope{position:absolute; inset:0;}
.bio-scope canvas{width:100%; height:100%; display:block;}
@media (min-width:900px){
  .bio-grid{grid-template-columns:1.35fr .65fr;}
  .bio-image{display:block; border-left:1px solid var(--hairline); min-height:100%;}
}

/* ---- FAQ accordion: restyled to the home rows' hover affordance —
   title colour and the +/x glyph both shift to --accent on hover/
   focus, exactly like .c-row. Markup, IDs, and the open/close JS are
   untouched. ---- */
.c-acc-q{transition:color .2s ease-out;}
.c-acc-q:hover, .c-acc-q:focus-visible{color:var(--accent);}
.c-acc-q:hover .c-acc-plus::before, .c-acc-q:hover .c-acc-plus::after,
.c-acc-q:focus-visible .c-acc-plus::before, .c-acc-q:focus-visible .c-acc-plus::after{
  background:var(--accent);
}
.c-acc-plus::before, .c-acc-plus::after{transition:background .2s ease-out, transform .28s cubic-bezier(.4,0,.2,1);}

/* instruments */
/* ---------------------------------------------------------------
   Live canvas instruments (assets/instruments.js): VU meter, 31-band
   spectrum analyser, oscilloscope, waveform. 1px black hairlines on
   a transparent canvas only — no fills, no glow, no colour accents —
   matching parked/demo/world/world.js's plotter-line standard
   (2026-09-23 scrub-white). Each mount is invisible/inert without JS
   (no-JS fallback stays visible); instruments.js flips the host into
   its "has instrument" state once a canvas actually draws.
   --------------------------------------------------------------- */
.instrument{position:absolute; inset:0; display:none;}
.instrument canvas{width:100%; height:100%; display:block;}

/* Instrument panels — one per inner page, a hairline-bordered rectangle
   sitting in a dedicated row directly under the page head (or the first
   content row, on /services/, which has no c-pagehead). Replaces the old
   static-image VU slot in .svc-image and the numeral VU/floating c-motif
   graphics flagged as dead weight (2026-09-23). Full grid width on
   mobile; right five columns, flush to --page-x, on desktop — same
   edges the page head itself uses, so the panel sits on that grid. */
.c-instrument-row{
  border-top:1px solid var(--hairline);
  padding:var(--r5) var(--page-x);
  display:flex; justify-content:flex-end;
}
.c-panel{
  position:relative;
  width:100%; height:140px;
  border:1px solid var(--hairline);
  background:var(--paper);
  overflow:hidden;
}
.c-panel .instrument{display:block;}
@media (min-width:900px){
  .c-panel{width:41.6667%; height:200px;}
}

/* Oscilloscope — one per work tile, drawn under that tile's player
   inside the existing work-row grid (new "scope" row, full width). */
#work .work-tile-card .work-row{
  grid-template-areas:"meta time" "wave wave"; /* per-tile scope removed: one shared scope lives in the page head (owner 2026-09-24) */
}
.work-row .instrument--scope{
  display:block; position:relative; grid-area:scope; height:34px; margin-top:2px;
}
.work-row .instrument--scope canvas{border-top:1px solid var(--hairline);}

/* Hero spectrum analyser — drop-in component, feature-flagged off
   (data-instrument-hero="off") until the motion lane clears the hero
   right panel. Stays display:none while flagged off. */
.instrument--analyser{display:none;}
[data-instrument-hero]:not([data-instrument-hero="off"]) .instrument--analyser{display:block;}

@media (prefers-reduced-motion: reduce){
  .instrument canvas{ /* instruments.js renders exactly one static frame */ }
}

/* hero name: the reveal wrapper clipped the "j" descender (line-height .9 < glyph ink) */
.hero-one-name .split-line{padding-bottom:.14em; margin-bottom:-.14em;}

/* ================= FOOTER v3 — contact + footer, ONE system ====================
   Owner feedback on the v2 split (contact-cta section + separate footer-v2 band):
   "looks like ass, why's the wordmark in this, contact doesn't look like it
   pertains to the form next to it." Fix: merge into a single .site-footer block,
   one 12-col grid at --page-x. Left (cols 1-7): the contact unit — label → h2 →
   sub-line → the form itself, all in one column so heading and form read as one
   thing. Right (cols 9-12): NAVIGATION (9-10) + SOCIALS (11-12), top-aligned with
   the contact label, plain-text links (obscura-derived sibling-dim hover — see
   refs-obscura NOTES.md). No wordmark. Col 8 is the gutter between the two
   blocks — deliberately empty, does the separating obscura/vanlent do with
   whitespace instead of a divider line (see refs-vanlent NOTES.md). Markup uses
   .site-footer/.sf-grid/.sf-contact/.sf-links/.sf-col; the old .footer-v2/
   .footer-row/.footer-col/.footer-stage rules and the base .contact-cta/.cta-inner
   rules in theme-v2.css no longer match anything (left alone, out of this lane's
   scope — theme-v2.css is shared foundation, not touched here). */
.site-footer{background:var(--paper); border-top:1px solid var(--hairline); overflow:hidden;}
.sf-grid{
  display:grid;
  grid-template-columns:repeat(12,1fr);
  column-gap:var(--r5);
  padding:var(--r6) var(--page-x) var(--r6);
}
.sf-contact{grid-column:1 / 8;}
.sf-contact .footer-col-lbl{margin-bottom:var(--r1);}
.sf-contact h2{
  font-family:var(--face-display); font-weight:700; font-size:var(--fs-h2);
  letter-spacing:var(--ls-h2); line-height:1.15; text-transform:lowercase; color:var(--black);
}
.sf-sub{
  font-family:var(--face); font-size:var(--fs-small); color:var(--grey-1);
  margin-top:var(--r1); margin-bottom:var(--r4);
}
.sf-form{max-width:640px;}
@media (max-width:900px){ .sf-form{max-width:none;} }
.sf-form-row{display:grid; grid-template-columns:1fr 1fr; gap:var(--r4) var(--r4);}
.sf-message{margin-top:var(--r4);}
.sf-send-row{
  display:flex; justify-content:flex-end;
  margin-top:var(--r3);
}
.sf-submit{
  display:inline-flex; align-items:center; gap:8px; min-height:44px;
  background:var(--green-deep); border:1px solid var(--green-deep); padding:12px 22px; cursor:pointer;
  font-family:var(--face); font-weight:600; font-size:var(--fs-label); letter-spacing:.08em;
  text-transform:lowercase; color:var(--paper); transition:color .2s ease-out, background .2s ease-out, border-color .2s ease-out;
}
.sf-submit i{font-style:normal; display:inline-block; transition:transform .2s ease-out, color .2s ease-out;}
.sf-submit:hover, .sf-submit:focus-visible{background:var(--black); border-color:var(--black); color:var(--paper);}
.sf-submit:hover i, .sf-submit:focus-visible i{transform:translateX(4px);}
.sf-submit:focus-visible{outline:2px solid var(--green-light); outline-offset:2px;}

/* quiet email/instagram line under the contact form's send button —
   same small/meta look as .footer-bottom a (2026-09-28: replaces the
   "Prefer to DM? instagram" /start/ page-head line, which read as
   provocative; this sits lower-key, under the form, on every page. */
.sf-alt-contact{
  font-family:var(--face); font-size:var(--fs-small); color:var(--grey-1);
  text-transform:lowercase; margin-top:var(--r3);
}
.sf-alt-contact a{
  display:inline-block; padding:14px 0; margin:-14px 0; /* >=44px hit area, no visual change */
  color:var(--grey-1); text-decoration:underline; text-underline-offset:2px;
  transition:color .2s ease-out;
}
.sf-alt-contact a:hover, .sf-alt-contact a:focus-visible{ color:var(--accent); }

.sf-links{grid-column:9 / 13; display:grid; grid-template-columns:1fr 1fr; column-gap:var(--r4);}
.sf-col{display:flex; flex-direction:column; align-items:flex-start;}
.footer-col-lbl{
  display:block;
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink); margin-bottom:var(--r2);
}
.sf-col a{
  display:block; width:100%; text-align:left;
  font-family:var(--face); font-size:16px; color:var(--black);
  line-height:44px; text-transform:lowercase;
  transition:opacity .2s ease, color .2s ease;
}
/* sibling-dim: hovering/focusing one link in a column dims the others in that
   column, the hovered/focused one stays full-opacity (obscura hover mechanic). */
.sf-col:hover a, .sf-col:focus-within a{opacity:.4;}
.sf-col a:hover, .sf-col a:focus-visible{opacity:1; color:var(--accent);}

.footer-bottom{
  border-top:1px solid var(--hairline);
  padding:var(--r3) var(--page-x);
  font-family:var(--face); font-size:var(--fs-small); color:var(--grey-1);
}
.footer-bottom-sep{ margin:0 .5em; }
/* keep each "item ·" glued together AND give each unit its own
   break opportunity, so a wrap only ever lands BETWEEN units, never
   strands a separator dot alone at the start of a line (390px audit,
   2026-09-27; each unit now carries its trailing separator, not a
   leading one, so a break before a unit always lands on real text).
   display:inline-block is load-bearing, not decorative: plain adjacent
   <span>s with no literal whitespace between them in the markup form
   ONE unbreakable run in a plain inline formatting context (verified —
   without it, this exact markup silently overflows instead of
   wrapping). inline-block boxes are atomic participants in line layout,
   so the browser gets a guaranteed, standards-native break point before
   each one, the same way it would between adjacent images or buttons. */
.footer-bottom-unit{ white-space:nowrap; display:inline-block; }
.footer-bottom a{
  display:inline-block; padding:10px 0; margin:-10px 0;
  color:var(--grey-1); text-decoration:underline; text-underline-offset:2px;
  transition:color .2s ease-out;
}
.footer-bottom a:hover, .footer-bottom a:focus-visible{ color:var(--accent); }

@media (max-width:900px){
  .sf-grid{grid-template-columns:1fr;}
  .sf-contact{grid-column:1 / -1;}
  .sf-links{grid-column:1 / -1; margin-top:var(--r6);}
}

@media (max-width:640px){
  .sf-form-row{grid-template-columns:1fr;}
  .sf-submit{width:100%; justify-content:center;}
  .sf-send-row{justify-content:flex-start;}
  .footer-bottom a{padding:14px 4px; margin:-14px -4px;}
  .sf-col a{line-height:44px;}
}

/* =================================================================
   14. .c-motif — small incidental hairline line-drawings (lissajous
   knot, waveform torus, VU arc family, oscilloscope contour sphere,
   spectrum bar cluster). 1px black-on-paper, no fills, no text.
   Style principle borrowed from the AVA SRG hand reference (small,
   scattered, code-drawn objects — never a centrepiece), rebuilt in
   jl audio's own hairline language. Canvas is built and animated by
   assets/motifs.js; these rules only size/place the wrapper and its
   per-placement modifier decides where on the page it sits. Always
   ≤1 per viewport, always clear of running text. Hidden below 480px
   rather than shrunk — this site's margins don't have a guaranteed
   clear spot at phone width once nav/hero copy reflows.
   ================================================================= */
.c-motif{
  display:block; pointer-events:none; user-select:none; line-height:0;
  z-index:1;
}
.c-motif canvas{display:block;}
@media (max-width:480px){
  .c-motif{display:none;}
}

/* home — knot beside the testimonial quote, upper-right of the section */
#words{position:relative;}
.c-motif--home-quote{position:absolute; top:var(--r5); right:var(--page-x);}

/* home — bars beside the "featured" label (flex child of the section's c-sechead) */
.c-motif--home-featured{margin-left:auto;}

/* about / faq / work / start — these four all previously sat at
   top:var(--sec-pad); right:var(--page-x), the SAME right edge as
   .c-pagehead-watermark, so the motif's height ran straight down into
   the watermark's vertically-centred band at every width — never a
   clear spot. Sat into the gap between the h1/crumb column and the
   watermark instead, vertically centred to match the watermark's own
   alignment. 2026-09-23.

   The right offset is derived, not guessed: .c-pagehead-watermark's
   own box is `right:var(--page-x)` with a width that measures out to
   a very consistent ~0.338 × viewport width (11vw font-size on the
   same "jl audio" string on every one of these pages), so its left
   edge sits at (page-x + 0.338vw) in from the container's right edge.
   Landing the motif's right edge 20px further in than that clears the
   watermark at every width down to the floor these four still show
   at — confirmed by measuring live h1/watermark boxes at 1650/1440/
   1300/1100px (see Website git history, motifs3 lane). */
.c-motif--about, .c-motif--faq, .c-motif--work, .c-motif--start{
  /* top:50% (matching the watermark's own vertical centring) let the
     180px knot on /about/ poke ~30px above the fixed nav's bottom
     hairline — visible bleeding into the nav bar itself, not just
     "incidental" placement. Anchored from sec-pad instead, same frame
     the breadcrumb starts from, with enough extra drop to clear the
     nav at every one of these four pages. 2026-09-23. */
  position:absolute; top:calc(var(--sec-pad) + 20px);
  right:calc(var(--page-x) + 33.8vw + 20px);
}

/* services — torus beside the "how it works" label */
.c-motif--services{margin-left:auto;}

/* pricing — arcs near the price rows' head */
.c-group{position:relative;}
.c-motif--pricing{position:absolute; top:var(--r2); right:var(--page-x);}

@media (max-width:1100px){
  /* about / faq / work all carry short h1s ("about.", "work.", the
     FAQ intro sentence) with well over 400px of clearance from the
     watermark even at 1100px — safe all the way down to where
     .c-motif itself hides completely (480px). */
  .c-motif--about, .c-motif--faq, .c-motif--work{display:none;}
}
@media (max-width:1420px){
  /* start's h1 ("tell me what you need.") is the longest of the four
     and, per the derived-offset formula above, only clears the
     heading text down to ~1404px measured — hide a little above that
     floor. Still visible (clear by ~49px) at 1440px. */
  .c-motif--start{display:none;}
}

/* home "featured" head: label sits directly under the sheet hairline like
   every other sub-heading (owner 2026-09-24); the 140px bars motif that used
   to stretch this head is gone. */
#work .c-sechead{ padding-top:clamp(32px, 3.2vw, 56px); }

/* page head clears the FIXED nav: the head starts at y=0 under the bar, so
   its own top padding must include the nav height or the crumb sits 8px
   under the divider (owner 2026-09-24). */
.c-pagehead{ padding-top:calc(var(--nav-h) + var(--sec-pad)); }
@media (max-width:760px){ .c-pagehead{ padding-top:calc(var(--nav-h-mobile) + var(--sec-pad)); } }
/* 2026-09-27: the pinned .c-price used top:var(--sec-pad) without the fixed nav's height, so at
   ~1440px (where --sec-pad is small) it slid up under the nav. Offset it by the nav like the head's own padding. */
@media (min-width:641px){ .c-pagehead > .c-price{ top:calc(var(--nav-h) + var(--sec-pad)); } }

/* =================================================================
   TAP TARGETS — mobile ≥44×44 CSS px (WCAG 2.5.8). Padding only, never
   font-size — the visible glyphs/labels stay the same size, just sit in a
   bigger hit box. .sf-col a (footer nav/socials links) already reaches
   44px via line-height, so it's untouched here.
   ================================================================= */
@media (max-width:760px){
  .nav-mark{ min-height:44px; padding:8px 4px; margin:-8px -4px; }
  .work-meta a.k{ display:inline-block; padding:10px 2px; margin:-10px -2px; }
  #work .play-btn, .play-btn{ width:44px; height:44px; }
}

/* Print: pricing/service pages are the ones clients actually print/PDF —
   strip chrome that means nothing on paper. */
@media print{ .nav,.nav-panel,.site-footer form,.c-pagehead-watermark{display:none} }

/* =================================================================
   QUICK QUOTE — .c-quote, /pricing/ only. Sits inside a plain .c-group
   below the price list. Static JS in /assets/quote.js reads per-track
   prices off the price rows' data-quote-price attributes so the total
   can't drift from the list above it. The whole block ships `hidden` in
   the markup and quote.js un-hides it — a no-JS visitor never sees it.
   Reuses .field (number input) and .check-group .opt (radio, styled as
   a filled-dot variant of the existing checkbox treatment) rather than
   inventing new form components.
   ================================================================= */
.c-quote{ display:flex; flex-direction:column; gap:var(--r4); padding:var(--r4) var(--page-x) var(--r5); }
.c-quote-inputs{ display:flex; flex-wrap:wrap; gap:var(--r5) var(--r6); align-items:flex-start; }
.c-quote-tracks{ max-width:120px; margin-bottom:0; }
.c-quote-service .fset-title{ display:block; padding:0; margin:0 0 var(--r2); border:none; }
.c-quote-service .check-group{ margin-top:0; }

/* Radio variant of the sitewide checkbox — same box size/hairline, but a
   circle with a filled dot instead of a check mark. */
.check-group .opt input[type="radio"]{
  appearance:none; -webkit-appearance:none;
  width:16px; height:16px; flex:none; margin-top:0;
  border:1.5px solid var(--grey-2);
  border-radius:50%;
  background:transparent;
  position:relative;
  cursor:pointer;
  transition:border-color .2s ease-out;
}
.check-group .opt input[type="radio"]:hover{ border-color:var(--accent); }
.check-group .opt input[type="radio"]:checked{ border-color:var(--black); }
.check-group .opt input[type="radio"]:checked::after{
  content:''; position:absolute; left:3px; top:3px; width:7px; height:7px;
  border-radius:50%; background:var(--black);
}
.check-group .opt input[type="radio"]:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

.c-quote-result{
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--r3) var(--r5);
  padding-top:var(--r4); border-top:1px solid var(--hairline);
}
.c-quote-total{
  font-family:var(--face); font-size:clamp(22px,3vw,30px); font-weight:600;
  letter-spacing:-.01em; color:var(--black);
}
.c-quote-note{
  font-family:var(--face); font-size:var(--fs-small); color:var(--grey-1);
  line-height:1.5; flex:1 1 220px;
}
.c-quote-result .btn-primary{ margin-left:auto; }
@media (max-width:640px){
  .c-quote-result{ flex-direction:column; align-items:flex-start; }
  .c-quote-result .btn-primary{ margin-left:0; }
}

/* =================================================================
   /start/ ONLY — hiding the page-head watermark on mobile there
   specifically (audit finding #26: it overlaps the H1 on narrow
   screens; every other inner page keeps its watermark, this one's
   kept short below 640px).
   ================================================================= */
@media (max-width:640px){
  #page-start .c-pagehead-watermark{ display:none; }
  /* phone rhythm: ~100px dead gaps around the waveform band */
  #page-start .c-pagehead{ min-height:0; padding-bottom:var(--r3); }
  #page-start .c-motif-band{ height:96px; margin:0 0 var(--r2); }
}
/* tablet: the 11vw ghost watermark collides with the headline between the
   phone cut-off and wide desktop — hide it there (clear again at >=1280) */
@media (min-width:761px) and (max-width:1279px){
  #page-start .c-pagehead-watermark{ display:none; }
}

/* owner check 2026-09-25: the tracks input rendered ~20px wide and the
   mobile result block left a tall gap above the button. */
.c-quote-tracks input[type="number"]{ width:6ch; min-width:6ch; padding:var(--r1) var(--r2); font-family:var(--face); font-size:var(--fs-body); }
.c-quote-note{ flex:1 1 220px; min-height:0; }
@media (max-width:640px){
  .c-quote-result{ gap:var(--r3); }
  .c-quote-note{ flex:0 0 auto; }
  #page-agreement .c-pagehead-watermark{ display:none; }
}

/* pricing calculator — audit fixes 2026-09-25 */
.field input[type="number"]{ appearance:textfield; -moz-appearance:textfield; background:transparent; border:0; border-bottom:1px solid var(--hairline); border-radius:0; color:var(--black); font-family:var(--face); font-size:var(--fs-body); padding:var(--r2) 0; min-height:44px; width:6ch; }
.field input[type="number"]:focus-visible{ outline:none; border-bottom:2px solid var(--accent); }
.field input[type="number"]::-webkit-outer-spin-button, .field input[type="number"]::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
.c-quote-service{ border:0; padding:0; margin:0; min-width:0; }
.c-quote-service .fset-title{ color:var(--black); }
.c-quote .field label, .c-quote-service .fset-title{ font-size:var(--fs-small); letter-spacing:.08em; text-transform:uppercase; color:var(--black); font-weight:500; }
.c-quote .check-group .opt span{ font-size:var(--fs-small); }
.c-quote .check-group .opt{ min-height:44px; display:inline-flex; align-items:center; }
.c-cta{ display:inline-flex; align-items:center; gap:var(--r2); padding:var(--r2) var(--r4); border:1px solid var(--accent); color:var(--black); font-family:var(--face); font-size:var(--fs-small); font-weight:500; text-decoration:none; text-transform:lowercase; min-height:44px; }
.c-cta:hover{ background:var(--accent); color:var(--paper); }
.c-quote-result .c-cta{ margin-left:auto; }
@media (max-width:640px){ .c-quote-result .c-cta{ margin-left:0; } }

/* =================================================================
   .c-motif-band — the signature hairline motif, drawn live by
   /assets/motif.js (one band per inner page, 2026-09-28). Full-width
   strip between the page head and the first section; height is
   reserved here so the canvas never shifts layout. Decorative only:
   aria-hidden, no pointer events (double-click still reaches the page
   for the dark-room toggle). Colours come from --paper/--accent-line/
   --motif-back/--grey-3, so the room switch recolours it live.
   ================================================================= */
.c-motif-band{
  position:relative; display:block; overflow:hidden; pointer-events:none;
  height:clamp(132px, 15vw, 232px);
  margin:var(--r2) 0 var(--r5);
}
.c-motif-band > canvas{position:absolute; inset:0; width:100%; height:100%; display:block;}


/* =================================================================
   16. Service pages — lower sections (2026-09-28). One system for
   everything under the page head, matched to the old /pricing/ page's
   fine-print rows + h2 section titles (that page is now the pricing
   PDF, 2026-09-29 — its .pr-* CSS was removed, this shared block
   wasn't):
   .c-sec-title  — h2-scale section heading
   .c-addon      — optional extra, a sub-row attached to its option row,
                   price aligned under the option's price column
   .c-facts      — compact label/value strip (rush · revisions)
   .c-send       — "what to send": numbered, hairline-divided checklist,
                   2 columns >=900px, ink body type
   .c-files      — "file prep": PDF download rows (title … ↓), same grid
   No data-rv on any of these: content is visible on load.
   ================================================================= */
.c-sec-title{
  margin:0; padding:var(--sec-pad) var(--page-x) var(--r3);
  font-family:var(--face); font-size:var(--fs-h2); font-weight:var(--fw-h2); letter-spacing:var(--ls-h2);
  line-height:1.15; text-transform:lowercase; color:var(--black);
}
.opt-panel{padding-bottom:0;}
.opt-panel .c-sec-title{padding-bottom:var(--r1);}
.opt-panel{--enq-w:8.5rem;}
.opt-panel .c-row-enq{box-sizing:border-box; min-width:var(--enq-w); justify-content:flex-end;}
/* option price: legible figure (pricing's .pr-price), unit stays a small label */
.opt-panel .c-row--option .c-price{
  font-size:clamp(17px,1.5vw,20px); letter-spacing:0; text-transform:none; font-variant-numeric:tabular-nums;
}
.opt-panel .c-row--option .c-price .c-price-unit{
  font-size:var(--fs-label); letter-spacing:.08em; text-transform:uppercase; color:var(--grey-1);
}
.opt-panel .c-row--option{padding-top:clamp(20px,2.4vw,32px); padding-bottom:clamp(20px,2.4vw,32px);}
.opt-panel .c-row--option:last-child{border-bottom:none;}
.opt-panel .c-row--has-addon{border-bottom:none; padding-bottom:clamp(12px,1.4vw,16px);}

/* add-on parts (shared by the service sub-row and /pricing/'s .pr-addon) */
.c-addon__k{
  display:inline-flex; align-items:baseline; gap:6px; white-space:nowrap;
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink);
}
.c-addon__plus{font-size:1.25em; font-weight:500; line-height:1; letter-spacing:0;}
.c-addon__name{font-family:var(--face); font-size:var(--fs-body); font-weight:500; color:var(--black); line-height:1.4;}
.c-addon__sub{font-weight:400; color:var(--grey-1);}
.c-addon__detail{font-family:var(--face); font-size:var(--fs-small); color:var(--grey-1); line-height:1.4;}
.c-addon__price{
  font-family:var(--face); font-size:var(--fs-body); font-weight:600; color:var(--green-ink);
  white-space:nowrap; font-variant-numeric:tabular-nums;
}
.c-addon{
  position:relative;
  display:grid; grid-template-columns:auto auto minmax(0,1fr) auto; align-items:baseline;
  column-gap:var(--r3); row-gap:4px;
  padding:clamp(12px,1.4vw,16px) calc(var(--page-x) + var(--enq-w) + var(--r3)) clamp(20px,2.4vw,32px) var(--page-x);
  border-bottom:1px solid var(--hairline);
}
.c-addon:last-child{border-bottom:none;}
/* inset hairline ties the add-on to the option above it */
.c-addon::before{
  content:""; position:absolute; top:0; left:var(--page-x); right:var(--page-x);
  border-top:1px solid var(--hairline);
}
.c-addon .c-addon__price{justify-self:end;}

/* facts strip */
.c-facts{border-top:1px solid var(--hairline);}
.c-facts__grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr));
  margin:0; padding:0 var(--page-x);
}
.c-facts__cell{display:flex; flex-direction:column; gap:6px; padding:var(--r3) var(--r3) var(--r3) 0; min-width:0;}
.c-facts__cell + .c-facts__cell{border-left:1px solid var(--hairline); padding-left:var(--r3);}
.c-facts dt{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green-ink);
}
.c-facts dd{margin:0; font-family:var(--face); font-size:var(--fs-body); color:var(--black); line-height:1.45;}

/* what to send + file prep — shared row grid */
.c-send, .c-files{padding-bottom:var(--r6);}
.c-send__list, .c-files__list{
  list-style:none; margin:0; padding:0 var(--page-x);
  display:grid; grid-template-columns:minmax(0,1fr);
}
@media (min-width:900px){
  .c-send__list, .c-files__list{grid-template-columns:repeat(2, minmax(0,1fr)); column-gap:var(--r6);}
}
.c-send__list li, .c-files__list li{border-top:1px solid var(--hairline); margin:0;}
.c-send__list li{
  display:grid; grid-template-columns:2.75rem minmax(0,1fr); align-items:baseline;
  padding:clamp(14px,1.5vw,18px) 0;
}
.c-send__n{
  font-family:var(--face); font-size:var(--fs-label); font-weight:600; letter-spacing:.08em;
  color:var(--green-ink); font-variant-numeric:tabular-nums;
}
.c-send__t{
  font-family:var(--face); font-size:var(--fs-body); font-weight:400; color:var(--black);
  line-height:1.5; max-width:52ch;
}
.c-files__row{
  display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:baseline; column-gap:var(--r3);
  min-height:44px; padding:clamp(14px,1.5vw,18px) 0; box-sizing:border-box;
  text-decoration:none; color:var(--black); transition:color .2s ease-out;
}
.c-files__t{font-family:var(--face); font-size:var(--fs-body); line-height:1.5;}
.c-files__arr{
  font-family:var(--face); font-size:var(--fs-body); color:var(--green-ink);
  transition:transform .35s cubic-bezier(.22,1,.36,1);
}
.c-files__row:hover, .c-files__row:focus-visible{color:var(--accent);}
.c-files__row:hover .c-files__t, .c-files__row:focus-visible .c-files__t{text-decoration:underline; text-underline-offset:3px; text-decoration-thickness:1px;}
.c-files__row:hover .c-files__arr, .c-files__row:focus-visible .c-files__arr{transform:translateY(3px);}
.c-files__row:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}

@media (max-width:640px){
  .opt-panel .c-row--option{gap:var(--r1);}
  .c-addon{
    grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"k price" "name name" "detail detail";
    padding-right:var(--page-x);
  }
  .c-addon .c-addon__k{grid-area:k;}
  .c-addon .c-addon__name{grid-area:name;}
  .c-addon .c-addon__detail{grid-area:detail;}
  .c-addon .c-addon__price{grid-area:price;}
  .c-facts__grid{grid-template-columns:minmax(0,1fr);}
  .c-facts__cell{flex-direction:row; align-items:baseline; gap:var(--r2); padding:14px 0;}
  .c-facts__cell dt{flex:0 0 7.5rem;}
  .c-facts__cell + .c-facts__cell{border-left:none; padding-left:0; border-top:1px solid var(--hairline);}
  .c-send__list li{grid-template-columns:2.25rem minmax(0,1fr);}
}

/* cross-link under options (mastering → mixing), 2026-09-28 */
.c-xlink{margin:0; padding:var(--r2, 16px) var(--page-x) 0; font-family:var(--face); font-size:var(--fs-body);}
.c-xlink a{display:inline-flex; align-items:center; gap:.5em; min-height:44px; color:var(--black); text-decoration:none; border-bottom:1px solid var(--hairline, currentColor);}
.c-xlink a:hover, .c-xlink a:focus-visible{color:var(--green-ink, var(--black));}

/* ---- robust pass (2026-09-28): very thin windows ----
   A service option row's price + "enquire →" pair sits on one line; under
   ~300px it no longer fits, so let it wrap onto a second line inside the
   row rather than poke past the right edge. Never engages at normal sizes. */
@media (max-width:640px){
  .c-row-end{flex-wrap:wrap; row-gap:var(--r1); min-width:0;}
  .c-row-end > .c-row-enq{margin-left:auto;} /* wrapped: stays right-aligned */
}
