/* GENERATED from shared/tokens.json (+ site overrides) by tools/build.py. Do not edit. */
:root{--bg:#ecebe7;--panel:#f6f5f2;--ink:#1c1c1a;--muted:#77756e;--line:#d6d4cd;--accent:#ff611a;--accent-ink:#fff;--accent-glow:rgba(255, 97, 26, .28);--glass-a:#f7f6f3;--glass-b:#e8e7e2;--sw-off:#cfcfcf;--sw-knob:#e9e9e9;--ring:#bdbbb4;--radio-fill:#fff;--bevel:rgba(255,255,255,.9);--shadow:0 1px 0 #fff inset, 0 1px 2px rgba(0,0,0,.12);--shadow-in:inset 0 1px 3px rgba(0,0,0,.18), inset 0 -1px 1px rgba(255,255,255,.6);--press-in:inset 0 2px 4px rgba(0,0,0,.2), inset 0 -1px 1px rgba(255,255,255,.12);--window-in:inset 0 3px 9px rgba(0,0,0,.30), inset 0 0 0 1px rgba(0,0,0,.09), inset 0 -2px 4px rgba(255,255,255,.55);--switch-in:inset 0 1px 2px rgba(0,0,0,.18);--knob-shadow:0 .8px 1.2px -.6px rgba(0,0,0,.26), 0 2.1px 2.9px -1.2px rgba(0,0,0,.25), 0 4.6px 6.2px -1.9px rgba(0,0,0,.24), 0 10px 14px -2.5px rgba(0,0,0,.2);--thumb-shadow:0 .8px 1.2px -.6px rgba(0,0,0,.26), 0 2.1px 2.9px -1.2px rgba(0,0,0,.25), 0 4.6px 6.2px -1.9px rgba(0,0,0,.2);--tip-shadow:0 6px 18px rgba(0,0,0,.25);--font:"Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif;--fs-base:16px;--lh-base:1.55;--fs-brand:clamp(18px, 3.75vw, 22.5px);--lh-brand:1.1;--fs-h1:clamp(28px, 6vw, 40px);--fs-h2:20px;--fs-lede:14.4px;--lh-lede:1.4;--fs-prose:14.4px;--lh-prose:1.45;--fs-ui:14px;--fs-display:56px;--fs-btn:18px;--fs-control:17px;--fs-radio:15px;--fs-small:13px;--fs-label:12px;--track:.12em;--wrap-max:640px;--gutter:20px;--gap-section:28px;--gap:16px;--gap-intro:24px;--gap-prose:64px;--header-pad-top:20px;--header-pad-bottom:12px;--radius:14px;--radius-window:12px;--radius-pill:999px;--scope-h:150px;--ctrl-pad-y:16px;--ctrl-pad-x:8px;--signal-gap:12px;--radio-gap:8px;--noise-gap:8px;--noise-select-w:104px;--switch-h:33px;--btn-pad-y:18px;}
@media (max-width:559px){:root{--fs-control:16px;--fs-radio:14px;--track:.08em;--ctrl-pad-y:14px;--ctrl-pad-x:6px;--signal-gap:8px;--radio-gap:7px;--noise-gap:6px;--noise-select-w:92px;}}
:root[data-theme="dark"]{--bg:#161615;--panel:#1f1f1d;--ink:#ecebe7;--muted:#8d8b84;--line:#333330;--glass-a:#1a1a18;--glass-b:#242422;--sw-off:#3d3d39;--sw-knob:#d6d3cc;--ring:#8a8880;--bevel:rgba(255,255,255,.07);--shadow:0 1px 0 rgba(255,255,255,.05) inset, 0 1px 2px rgba(0,0,0,.6);--shadow-in:inset 0 1px 3px rgba(0,0,0,.7), inset 0 -1px 1px rgba(255,255,255,.05);--window-in:inset 0 3px 10px rgba(0,0,0,.85), inset 0 0 0 1px rgba(0,0,0,.55), inset 0 -1px 3px rgba(255,255,255,.06);}

/* Base layer, shared by every utility site: reset, page frame, plain elements.
   RULE: no literal colours, sizes or spacings in here. Everything reads the tokens (tokens.css, generated from tokens.json). */
* { box-sizing: border-box; }
html { color-scheme: light; }                       /* native controls follow the chosen theme, not the OS */
html[data-theme="dark"] { color-scheme: dark; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: var(--fs-base)/var(--lh-base) var(--font);
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration-color: var(--accent); text-underline-offset: 3px; }
.wrap { max-width: var(--wrap-max); margin: 0 auto; padding: 0 var(--gutter); }
header.top { display: flex; justify-content: space-between; align-items: center; padding: var(--header-pad-top) 0 var(--header-pad-bottom); }
.brand { font-weight: 700; letter-spacing: .02em; text-decoration: none; }
h1.brand { margin: 0; font-size: var(--fs-brand); line-height: var(--lh-brand); letter-spacing: -.01em; }
h1 { font-size: var(--fs-h1); line-height: 1.1; letter-spacing: -.01em; margin: 28px 0 6px; }
.lede { color: var(--muted); margin: 0 0 24px; font-size: var(--fs-lede); line-height: var(--lh-lede); }
.lede strong { color: var(--ink); font-weight: 600; }      /* the one strong sentence that says what the page is for */
.label { font-size: var(--fs-label); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 0 0 8px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* Text below the instrument, FAQ */
section.prose { margin: 36px 0; }
section.prose h2 { font-size: var(--fs-h2); margin: 28px 0 8px; }
section.prose p, section.prose li { color: var(--muted); }
section.prose strong { color: var(--ink); }
.prose p, .prose li, .prose details p, .prose summary { font-size: var(--fs-prose); line-height: var(--lh-prose); }
details { border-top: 1px solid var(--line); padding: 12px 0; }
details:last-of-type { border-bottom: 1px solid var(--line); }
summary { cursor: pointer; font-weight: 600; }
details p { margin: 8px 0 0; color: var(--muted); }

footer.bottom { padding: 28px 0 40px; color: var(--muted); font-size: 13px; display: flex; gap: 16px; flex-wrap: wrap; }
footer.bottom nav { display: flex; gap: 16px; margin-left: auto; }
footer.bottom a { color: var(--muted); }

/* Round icon button (theme toggle) and the focus ring shared by controls */
.icon-btn {
  width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); cursor: pointer; box-shadow: var(--shadow);
  display: grid; place-items: center; font-size: 16px;
}
.icon-btn:active { box-shadow: var(--shadow-in); }
.icon-btn:focus-visible, .dial:focus-visible, .seg button:focus-visible, input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* Sliders: no outline anywhere, just an orange fill (up to the knob) and a grey fill (after it). The fill position comes
   from --pct, which the page script keeps in sync with the value (WebKit/Blink have no ::progress part). */
input[type=range] { -webkit-appearance: none; appearance: none; width: 100%; height: 22px; margin: 0; background: transparent; cursor: pointer; --pct: 50%; }
input[type=range]::-webkit-slider-runnable-track { height: 8px; border-radius: var(--radius-pill); border: 0; background: linear-gradient(to right, var(--accent) var(--pct), var(--sw-off) var(--pct)); }
input[type=range]::-moz-range-track { height: 8px; border-radius: var(--radius-pill); border: 0; background: var(--sw-off); }
input[type=range]::-moz-range-progress { height: 8px; border-radius: var(--radius-pill); background: var(--accent); }
input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; margin-top: -6px; border: 0; border-radius: 50%; background: radial-gradient(circle at 50% 50%, var(--accent) 0 3.4px, transparent 3.9px), radial-gradient(circle at 35% 30%, #fff, var(--sw-knob) 70%); box-shadow: var(--thumb-shadow); }
input[type=range]::-moz-range-thumb { width: 20px; height: 20px; border: 0; border-radius: 50%; background: radial-gradient(circle at 50% 50%, var(--accent) 0 3.4px, transparent 3.9px), radial-gradient(circle at 35% 30%, #fff, var(--sw-knob) 70%); box-shadow: var(--thumb-shadow); }
input[type=range]:focus { outline: none; }
input[type=range]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 5px var(--accent-glow); }      /* keyboard focus: a soft glow, not a stroke */
input[type=range]:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 5px var(--accent-glow); }
input[type=range]:disabled { opacity: 1; }

/* Generic building blocks for sites that need them (not used by every page) */
.brand i { display: inline-block; width: .6em; height: .6em; border-radius: 50%; background: var(--accent); margin-right: .45em; }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow); }
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius-pill); padding: 3px; background: var(--bg); }
.seg button {
  border: 0; background: transparent; color: var(--muted); font: inherit; font-size: 14px;
  padding: 6px 14px; border-radius: var(--radius-pill); cursor: pointer;
}
.seg button[aria-pressed="true"] { background: var(--ink); color: var(--bg); }

/* Component layer, shared by every utility site: the controls of the Braun-style panel.
   RULE: no literal colours, sizes, radii, shadows or spacings that are design decisions: they come from the tokens.
   (Fixed geometry that is part of a component's drawing, like a radio dot, may stay literal.)
   Order matters: tokens.css, base.css, components.css, then the site's own CSS. */

/* Status line: orange while it is a prompt or a highlighted value */
.status { margin: 0; min-height: 1.5em; color: var(--muted); font-size: var(--fs-ui); }
.status-hl, .status-warn { color: var(--accent); }
.status-prompt { color: var(--accent); font-weight: 700; }                /* "Press a button to start" at launch, until the first sound */

/* Window: not a button but a pane sunk into the panel. The inner shadow sits on a layer ABOVE the content, so a trace
   looks like it lives behind glass, like the scale in a radio's tuning window. */
.window { position: relative; border-radius: var(--radius-window); overflow: hidden; box-shadow: 0 1px 0 var(--bevel); }
.window::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; box-shadow: var(--window-in); }

/* Segmented control: one rounded pill, N equal buttons (the pressed one is pushed in) */
.channels { display: grid; grid-template-columns: repeat(3, 1fr); border: 1px solid var(--line); border-radius: var(--radius-pill);  /* pill: the end caps are true half circles */ overflow: hidden; background: var(--panel); box-shadow: var(--shadow); }
.channels button { font: inherit; font-size: var(--fs-control); font-weight: 600; padding: var(--ctrl-pad-y) var(--ctrl-pad-x); border: 0; background: transparent; color: var(--ink); cursor: pointer; transition: background .15s, color .15s; }
.channels button + button { border-left: 1px solid var(--line); }
/* The end buttons carry the pill's rounding themselves, so an inner shadow follows the curve instead of a square corner */
.channels button:first-child { border-radius: var(--radius-pill) 0 0 var(--radius-pill); }
.channels button:last-child { border-radius: 0 var(--radius-pill) var(--radius-pill) 0; }
.channels button:hover { background: var(--bg); }
.channels button:active { box-shadow: var(--shadow-in); }
.channels button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); box-shadow: var(--press-in); }   /* the chosen button is pushed in */
.channels button:focus-visible { outline: 2px solid var(--accent); outline-offset: -5px; }

/* Field: a category label with its value on the right, then the control */
.field .label { display: flex; justify-content: space-between; margin: 0 0 10px; }
.field .label span { color: var(--ink); font-weight: 400; text-transform: none; letter-spacing: 0; font-variant-numeric: tabular-nums; }   /* the value stays regular, the category name is bold */
.field.off { opacity: .4; }
.field.off .chips { pointer-events: none; }

/* Chips: small push buttons */
.chips { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.chip { border: 1px solid var(--line); background: var(--panel); color: var(--ink); font: inherit; font-size: var(--fs-small); padding: 4px 12px; border-radius: var(--radius-pill); cursor: pointer; box-shadow: var(--shadow); }
.chip:active { box-shadow: var(--shadow-in); }
.chip:hover { border-color: var(--muted); }
.chip:focus-visible { outline: none; border-color: var(--ink); }
.hint { color: var(--muted); font-size: var(--fs-label); }

/* Radio: light grey ring, white inside, accent dot in the middle */
.radio { display: inline-flex; align-items: center; gap: var(--radio-gap); cursor: pointer; font-size: var(--fs-radio); }
.radio input { appearance: none; -webkit-appearance: none; flex: none; width: 19px; height: 19px; margin: 0; border: 1.5px solid var(--ring); border-radius: 50%; background-color: var(--radio-fill); cursor: pointer; transition: border-color .15s; }
.radio input:hover { border-color: var(--muted); }
.radio input:checked { background-image: radial-gradient(circle, var(--accent) 0 38%, transparent 43%); }
.radio input:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Dropdowns */
.select { position: relative; display: inline-block; }
.select select { appearance: none; -webkit-appearance: none; font: inherit; font-size: var(--fs-small); color: var(--ink); background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-pill); padding: 7px 28px 7px 12px; cursor: pointer; box-shadow: var(--shadow); }
.select select:disabled { opacity: .4; cursor: default; }
.select select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.select::after { content: ""; position: absolute; right: 12px; top: 50%; margin-top: -2px; border: 4px solid transparent; border-top-color: var(--muted); border-bottom: 0; pointer-events: none; }
.select.lang select { padding: 6px 28px 6px 12px; font-size: var(--fs-small); font-weight: 600; }
/* A select's automatic width ignores letter-spacing in some browsers: give the dropdowns room explicitly */
.select.lang select { min-width: 74px; }

/* Switch (Slurp style, inspired by the Drams library): accent = on, grey = off. The knob slides and stays a perfect circle,
   like a physical switch. Its size follows --switch-h (the width is twice the height). */
.slurp { position: relative; flex: none; width: calc(var(--switch-h) * 2); height: var(--switch-h); padding: 0; border: 0; border-radius: var(--radius-pill); cursor: pointer; background: var(--sw-off); transition: background .25s; box-shadow: var(--switch-in); }
.slurp[aria-checked="true"] { background: var(--accent); }
.slurp-knob { position: absolute; top: 3px; left: 3px; width: calc(var(--switch-h) - 6px); height: calc(var(--switch-h) - 6px); border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff, var(--sw-knob) 70%); box-shadow: var(--knob-shadow); }
.slurp[aria-checked="true"] .slurp-knob { left: calc(var(--switch-h) + 3px); }
.slurp-knob { transition: left .2s cubic-bezier(.3,.7,.25,1); }          /* a physical switch: the knob slides, it never changes shape */
.slurp:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Tooltip: hover or keyboard focus, text from the data-tip attribute */
[data-tip] { position: relative; }
[data-tip]:hover::after, [data-tip]:has(:focus-visible)::after {
  content: attr(data-tip); position: absolute; left: 0; bottom: calc(100% + 10px); width: max-content; max-width: 250px; z-index: 5;
  padding: 8px 11px; border-radius: 10px; background: var(--ink); color: var(--bg); font-size: var(--fs-label); line-height: 1.4; font-weight: 400; letter-spacing: 0; text-indent: 0; pointer-events: none; box-shadow: var(--tip-shadow);
}
@media (max-width: 559px) {
  [data-tip]:hover::after, [data-tip]:has(:focus-visible)::after { max-width: min(250px, calc(100vw - 40px)); }
}

/* Tracking on the control labels */
.channels button, .radio span, .chip, .select select { letter-spacing: var(--track); }
.channels button { text-indent: var(--track); }          /* the trailing space after the last letter would push the word off-centre */

/* Primary button: one big pill; aria-pressed="true" = pushed in, accent coloured (e.g. Start / Stop) */
.btn-primary { display: block; width: 100%; font: inherit; font-size: var(--fs-btn); font-weight: 600; padding: var(--btn-pad-y) var(--ctrl-pad-x); border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--panel); color: var(--ink); box-shadow: var(--shadow); cursor: pointer; letter-spacing: var(--track); text-indent: var(--track); transition: background .15s, color .15s; }
.btn-primary:hover { background: var(--bg); }
.btn-primary:active { box-shadow: var(--shadow-in); }
.btn-primary[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); box-shadow: var(--press-in); }
.btn-primary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Big readout number and a − value + stepper */
.display-num { font-size: var(--fs-display); line-height: 1; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.stepper { display: inline-flex; align-items: center; gap: 10px; }
.stepper output { min-width: 2ch; text-align: center; font-size: var(--fs-radio); font-variant-numeric: tabular-nums; }
.chip.sq { min-width: 36px; padding: 4px 0; text-align: center; font-size: var(--fs-radio); line-height: 1.2; }

/* Speaker test: only what is specific to this page. Layout is one column and one grid: every section is a direct child of
   .app and gets the same vertical gap; inside a section, items sit on the same left edge.
   Design values come from the shared tokens (shared/tokens.json, overridden in speaker/tokens.json); components are in
   shared/components.css. No literal colours or design sizes belong in this file. */

.tools { display: flex; align-items: center; gap: 10px; }
.intro { margin: 0 0 var(--gap-intro); }
.intro .lede { margin: 0 0 6px; }
.app { display: grid; gap: var(--gap-section); }
.app > .status { margin: calc(var(--gap-section) * -.5) 0; }      /* the status line sits between the scope and the buttons: closer to both than the normal gap */
.scope { display: block; width: 100%; height: var(--scope-h); border: 0; background: linear-gradient(180deg, var(--glass-a), var(--glass-b)); }

/* Sliders: two equal columns */
.sliders { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-section); align-items: start; }

/* Mode row: signal radios (with faint dividers) on the left, the phase switch on the right, one line */
.mode { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 22px 16px; }
.mode .label { margin: 0 0 10px; }      /* same category label as Frequency / Volume */
.signal { display: flex; flex-wrap: wrap; align-items: center; row-gap: 12px; }
.signal > * + * { margin-left: var(--signal-gap); padding-left: var(--signal-gap); border-left: 1px solid var(--line); }
.noise-group { display: inline-flex; align-items: center; gap: var(--noise-gap); }
#noise-type { min-width: var(--noise-select-w); }

/* Phase: orange = in phase (good), grey = out of phase (the fault). The explanation lives in a hover / keyboard-focus tooltip. */
.phase-row { display: flex; align-items: center; gap: 10px; }
.phase-text { width: 104px; font-weight: 600; font-size: var(--fs-ui); white-space: nowrap; letter-spacing: var(--track); }   /* fixed: "in phase" / "out of phase" must not shift the row */
.phase[data-state="out"] .phase-text { color: var(--muted); }
.phase[data-tip]:hover::after, .phase[data-tip]:has(:focus-visible)::after { left: auto; right: 0; }

/* Room between the instrument and the text below it */
.app + .prose { margin-top: var(--gap-prose); }

/* Exact frequency: a chip with a number field inside */
.chip-hz { display: inline-flex; align-items: center; gap: 6px; padding: 0 12px; cursor: text; box-shadow: var(--shadow-in); }   /* an entry field is recessed, not a push button */
.chip-hz input { width: 58px; padding: 4px 0; border: 0; background: transparent; color: var(--ink); font: inherit; font-size: var(--fs-small); letter-spacing: var(--track); text-align: right; outline: none; -moz-appearance: textfield; appearance: textfield; }
.chip-hz input::-webkit-inner-spin-button, .chip-hz input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.chip-hz input::placeholder { color: var(--muted); }
/* no stroke change while typing in the exact field: the caret is the focus indicator */
.chip-hz:has(input:disabled) { opacity: .5; cursor: default; }
.chip-hz:has(input[aria-invalid="true"]) input { color: var(--accent); }   /* the typed text is not a number */
.chips-bass { display: inline-flex; gap: 8px; }          /* the tooltip belongs to the two bass buttons only, not to the exact field */

/* Phones */
@media (max-width: 559px) {
  .sliders { grid-template-columns: 1fr; gap: var(--gap-section); }
  .phase[data-tip]:hover::after, .phase[data-tip]:has(:focus-visible)::after { left: 0; right: auto; }   /* the phase group wraps under the sound row at the LEFT edge: the tooltip opens to the right */
  .lede br { display: none; }       /* the lede has a soft break after its first clause; on a phone the line is too narrow for it, so the text just flows */
}

/* Longer labels in some languages ("varredura", "balayage", "scansione"): tighten the sound row on phones so it stays on one line */
@media (max-width: 559px) {
  :is(:lang(pt), :lang(fr), :lang(it), :lang(de), :lang(tr)) .radio { font-size: 13.5px; gap: 6px; }
  :is(:lang(pt), :lang(fr), :lang(it), :lang(de), :lang(tr)) .signal > * + * { margin-left: 6px; padding-left: 6px; }
  :is(:lang(pt), :lang(fr), :lang(it), :lang(de), :lang(tr)) .noise-group { gap: 5px; }
  :is(:lang(pt), :lang(fr), :lang(it), :lang(de), :lang(tr)) #noise-type { min-width: 76px; padding: 6px 22px 6px 10px; font-size: 12px; letter-spacing: .02em; }
  :is(:lang(pt), :lang(fr), :lang(it), :lang(de), :lang(tr)) .radio span { letter-spacing: .05em; }
  :is(:lang(pt), :lang(fr), :lang(it), :lang(de), :lang(tr)) .select::after { right: 9px; }
}

/* Landing pages (left-right test, headphone test, ...): their own heading, and the list of the other tests */
h1.page-h1 { margin: 0 0 8px; font-size: var(--fs-h1); line-height: 1.15; letter-spacing: -.01em; }
a.brand { color: var(--ink); font-size: var(--fs-brand); line-height: var(--lh-brand); }
ul.more { margin: 0; padding-left: 1.2em; }
ul.more li { margin: 4px 0; }
