/* Layout: one column, 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. */
:root { --gap-section: 28px; --gap: 16px; }

header.top { padding: 20px 0 12px; }
h1.brand { margin: 0; font-size: clamp(18px, 3.75vw, 22.5px); line-height: 1.1; letter-spacing: -.01em; }
.tools { display: flex; align-items: center; gap: 10px; }

.intro { margin: 0 0 24px; }
.intro .lede { margin: 0 0 6px; font-size: 14.4px; line-height: 1.4; }
.status { margin: 0; min-height: 1.5em; color: var(--muted); font-size: 14px; }
.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 */

.app { display: grid; gap: var(--gap-section); }

/* Scope: one rounded box, a divider in the middle, "Left" / "Right" in the top corners (drawn in app.js). */
/* The scope is a window, not a button: sunk into the panel. The inner shadow sits on a layer ABOVE the canvas, so the trace
   looks like it lives behind glass, like the scale in a radio's tuning window. */
.window { position: relative; border-radius: 12px; 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); }
.scope { display: block; width: 100%; height: 150px; border: 0; background: linear-gradient(180deg, var(--glass-a), var(--glass-b)); }

/* Channel: one rounded segmented control */
.channels { display: grid; grid-template-columns: repeat(3, 1fr); border: 1px solid var(--line); border-radius: 999px;  /* pill: the end caps are true half circles */ overflow: hidden; background: var(--panel); box-shadow: var(--shadow); }
.channels button { font: inherit; font-size: 17px; font-weight: 600; padding: 16px 8px; 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: 999px 0 0 999px; }
.channels button:last-child { border-radius: 0 999px 999px 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; }

/* Sliders: two equal columns, labels with their value on the right */
.sliders { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-section); align-items: start; }
.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 { 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: 13px; padding: 4px 12px; border-radius: 999px; 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: 12px; }

/* 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: 12px; padding-left: 12px; border-left: 1px solid var(--line); }
.noise-group { display: inline-flex; align-items: center; gap: 8px; }
.radio { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 15px; }
.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%); }      /* light grey ring, white inside, orange dot in the middle */
.radio input:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Dropdowns (noise type, language) */
.select { position: relative; display: inline-block; }
.select select { appearance: none; -webkit-appearance: none; font: inherit; font-size: 13px; color: var(--ink); background: var(--panel); border: 1px solid var(--line); border-radius: 999px; 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: 13px; font-weight: 600; }

/* Phase: Slurp-style switch (inspired by the Drams library): orange = in phase (good), grey = out of phase (the fault).
   The knob slides and stays a perfect circle, like a physical switch.
   The explanation lives in a hover / keyboard-focus tooltip (data-tip) instead of a line of text. */
.phase-row { display: flex; align-items: center; gap: 10px; }
.phase-text { width: 104px; font-weight: 600; font-size: 14px; white-space: nowrap; }   /* fixed: "in phase" / "out of phase" must not shift the row */
.phase[data-state="out"] .phase-text { color: var(--muted); }
.slurp { position: relative; flex: none; width: 66px; height: 33px; padding: 0; border: 0; border-radius: 999px; cursor: pointer; background: var(--sw-off); transition: background .25s; box-shadow: inset 0 1px 2px rgba(0,0,0,.18); }
.slurp[aria-checked="true"] { background: var(--accent); }
.slurp-knob { position: absolute; top: 3px; left: 3px; width: 27px; height: 27px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff, var(--sw-knob) 70%);
  box-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); }
.slurp[aria-checked="true"] .slurp-knob { left: 36px; }
.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; }
[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: 12px; line-height: 1.4; font-weight: 400; letter-spacing: 0; text-indent: 0; pointer-events: none; box-shadow: 0 6px 18px rgba(0,0,0,.25);
}
.phase[data-tip]:hover::after, .phase[data-tip]:has(:focus-visible)::after { left: auto; right: 0; }
/* On a phone the phase group wraps under the sound row, at the LEFT edge: the tooltip must open to the right, and never be wider than the screen */
@media (max-width: 559px) {
  .phase[data-tip]:hover::after, .phase[data-tip]:has(:focus-visible)::after { left: 0; right: auto; }
  [data-tip]:hover::after, [data-tip]:has(:focus-visible)::after { max-width: min(250px, calc(100vw - 40px)); }
}

@media (max-width: 559px) {
  :root { --track: .08em; }                        /* less tracking on small screens: the mode row must stay on one line */
  .signal > * + * { margin-left: 8px; padding-left: 8px; }
  .radio { font-size: 14px; gap: 7px; }
  .noise-group { gap: 6px; }
  .sliders { grid-template-columns: 1fr; gap: var(--gap-section); }
  .channels button { padding: 14px 6px; font-size: 16px; }
}

/* Tracking on the control labels (tone, sweep, noise, left, both, right, in phase ...) */
.channels button, .radio span, .phase-text, .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 */

/* Room between the instrument and the text below it */
.app + .prose { margin-top: 64px; }

/* A select's automatic width ignores letter-spacing in some browsers: give the two dropdowns room explicitly */
.select.lang select { min-width: 74px; }
#noise-type { min-width: 104px; }
@media (max-width: 559px) { #noise-type { min-width: 92px; } }      /* after the base rule, so it wins on phones */

/* 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: 13px; 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 */

/* 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; }
}

/* 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 */
@media (max-width: 559px) { .lede br { display: none; } }

/* Status line sits between the scope and the channel buttons: pull it closer to both than the normal section gap */
.app > .status { margin: calc(var(--gap-section) * -.5) 0; }

/* Explanation text below the instrument: 90% size, tighter lines (the legal pages keep the base size) */
.prose p, .prose li, .prose details p, .prose summary { font-size: 14.4px; line-height: 1.45; }
