/* ---------------------------------------------------------------
   audio-id — global + page styles
   Parity target: audio-location-system.vercel.app
   Original shipped this as globals.css + shared.module.css +
   two page.module.css files. Flattened here, scoped by body class.
   --------------------------------------------------------------- */

/* ---------- globals ---------- */

:root {
  --bg: #000;
  --panel: #0a0a0a;
  --panel2: #161616;
  --border: #333;
  --text: #fff;
  --muted: #888;
  --accent: #fff;
  --accent2: #fff;
  --good: #fff;
  --warn: #fff;
}

* { box-sizing: border-box; margin: 0; padding: 0 }

html, body { max-width: 100vw; overflow-x: hidden }

html { color-scheme: dark; height: 100% }

body {
  background: var(--bg);
  min-height: 100%;
  color: var(--text);
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-family: ui-monospace, SF Mono, Menlo, Consolas, monospace;
}

a { color: inherit; text-decoration: none }

code { background: #1a1a1a; border-radius: 0; padding: 1px 5px; font-size: 11.5px }

/* ---------- home ---------- */

/* One system in place of four breakpoints of one-off overrides.
   Vertical rhythm is driven by viewport HEIGHT, because height is the binding
   constraint here: the page must never scroll and the selector must sit on the
   centre line. Type is driven by width. Everything below reads from this scale;
   there are no loose pixel values further down. */
body.home {
  --measure: 27rem;                          /* one reading column, ~432px */

  --step-0: clamp(11px,  2.8vw, 12px);       /* support: list, example */
  --step-1: clamp(12px,  3.1vw, 13.5px);     /* body: the paragraph */
  --step-2: clamp(12.5px, 3.4vw, 15px);      /* tagline */
  --step-3: clamp(25px,  7.2vw, 36px);       /* the wordmark */

  --gap-tight: clamp(4px,  0.7vh,  7px);     /* within a thought */
  --gap-mid:   clamp(9px,  1.6vh, 15px);     /* between thoughts */
  --gap-zone:  clamp(16px, 3.2vh, 32px);     /* between the three zones */

  --pad-block:  clamp(14px, 2.6vh, 28px);
  --pad-inline: clamp(14px, 4vw,   24px);

  /* A three-step grey ramp so hierarchy is carried by colour as well as size:
     #fff headline, --dim body, --muted support. */
  --dim: #a8a8a8;
}

/* Rows: spacer, selector, spacer. The two 1fr rows always resolve equal, so the
   selector lands on the exact vertical centre by construction. */
body.home .main {
  grid-template-rows: 1fr auto 1fr;
  justify-items: center;
  align-items: center;
  gap: var(--gap-zone);
  min-height: 100dvh;
  /* Optical, not mathematical: slightly more room beneath the block than above,
     because the eye reads the centre of mass as high when it is measured evenly. */
  padding: var(--pad-block) var(--pad-inline) calc(var(--pad-block) * 1.2);
  text-align: center;
  display: grid;
}

body.home .brand { align-self: end }
body.home .about { align-self: start }

/* ---- zone 1: identity ---- */

.brand {
  flex-direction: column;
  align-items: center;
  gap: var(--gap-tight);
  width: 100%;
  max-width: var(--measure);
  display: flex;
}

body.home .title {
  color: var(--text);
  /* Letterspaced out, not in. A monospace wordmark reads as deliberate when
     opened up; tightening it just looks like a rendering error. */
  letter-spacing: .05em;
  font-size: var(--step-3);
  font-weight: 700;
  line-height: 1.05;
  text-wrap: balance;
}

.tagline {
  color: var(--dim);
  letter-spacing: .02em;
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.35;
  text-wrap: balance;
}

/* Left-aligned, unlike the wordmark above it. Five lines of centred monospace
   gives the eye no fixed left edge to return to on each line; the identity is
   centred, the reading matter is not. */
.lede {
  color: var(--dim);
  width: 100%;
  max-width: var(--measure);
  margin-top: var(--gap-mid);
  text-align: left;
  font-size: var(--step-1);
  line-height: 1.55;
  text-wrap: pretty;
}

/* ---- zone 2: the choice ---- */

/* Same max-width as the copy, so the page has ONE alignment spine rather than
   the three different measures it had before. */
.buttons {
  justify-content: center;
  gap: clamp(8px, 2.4vw, 12px);
  width: 100%;
  max-width: var(--measure);
  display: flex;
}

.modeLink {
  background: var(--panel);
  border: 1px solid var(--border);
  flex: 1 1 0;
  min-width: 0;
  color: var(--text);
  cursor: pointer;
  border-radius: 0;
  flex-direction: column;
  align-items: center;
  gap: var(--gap-tight);
  padding: clamp(12px, 2.2vh, 20px) 12px;
  transition: border-color .2s ease, background-color .2s ease, transform .2s ease;
  display: flex;
}

.modeLink:hover {
  background: var(--panel2);
  border-color: var(--accent2);
  transform: translateY(-2px);
}

/* Pressed feedback — without it the link feels like a picture of a button. */
.modeLink:active { transform: translateY(0) scale(.985) }

.modeLink:focus-visible {
  outline: 2px solid var(--accent2);
  outline-offset: 2px;
}

.modeLink .icon { color: var(--dim); transition: color .2s ease; display: flex }
.modeLink .icon svg { width: clamp(22px, 6vw, 30px); height: auto }
.modeLink:hover .icon { color: var(--text) }

.modeText { flex-direction: column; gap: 1px; display: flex }
.modeText b { color: var(--text); font-size: clamp(13px, 3.6vw, 15px); font-weight: 700 }
.modeText span { color: var(--muted); font-size: clamp(10px, 2.6vw, 11.5px) }

/* ---- zone 3: detail ---- */

.about {
  flex-direction: column;
  gap: var(--gap-mid);
  width: 100%;
  max-width: var(--measure);
  text-align: left;
  display: flex;
}

/* Marker instead of a full-height rule, so the list and the example below it
   are no longer the same visual object. */
.benefits {
  list-style: none;
  gap: var(--gap-tight);
  display: grid;
}

.benefits li {
  color: var(--muted);
  padding-left: 14px;
  font-size: var(--step-0);
  line-height: 1.45;
  position: relative;
}

.benefits li::before {
  content: "";
  background: var(--muted);
  width: 6px;
  height: 1px;
  position: absolute;
  top: .68em;
  left: 0;
}

.benefits b { color: var(--text) }

/* The example is a callout, so it keeps the rule the list gave up. */
.scenario {
  border-left: 2px solid var(--border);
  color: var(--muted);
  padding-left: 12px;
  font-size: var(--step-0);
  line-height: 1.55;
  text-wrap: pretty;
}

.scenario b { color: var(--text) }

/* Landscape phones cannot stack: 360px of height is less than the copy alone.
   Copy on the left, the choice on the right, both centred against each other.
   The fluid scale above already shrinks every gap at this height. */
@media (max-height: 480px) and (min-width: 560px) and (orientation: landscape) {
  body.home .main {
    grid-template-columns: 1fr minmax(190px, 230px);
    grid-template-rows: auto auto;
    align-content: center;
    gap: var(--gap-mid) clamp(16px, 3vw, 28px);
    max-width: 62rem;
    margin: 0 auto;
  }
  /* Placed explicitly rather than by document order: the selector sits between
     the copy blocks in the markup but beside them here. */
  /* Left-align the identity too: in two columns a centred wordmark over
     left-aligned copy reads as a mistake rather than a choice. */
  body.home .brand {
    grid-column: 1; grid-row: 1; align-self: end; max-width: none;
    align-items: flex-start; text-align: left;
  }
  body.home .about { grid-column: 1; grid-row: 2; align-self: start; max-width: none }
  .buttons {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: center;
    flex-direction: column;
    max-width: none;
  }
}

/* Floor: viewports too short to hold the centre line and too narrow for the
   landscape layout. Release the symmetry rather than shrink type further. */
@media (max-height: 460px) and (max-width: 559px) {
  body.home .main { grid-template-rows: auto auto auto; align-content: center }
  body.home .brand { align-self: auto }
  body.home .about { align-self: auto }
}

/* ---------- shared (transmitter + receiver) ---------- */

.iconRow { justify-content: center; align-items: center; gap: 6px; display: inline-flex }

.header {
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  display: flex;
}

.header h1 { color: var(--muted); flex: 1; margin: 0; font-size: 15px; font-weight: 600 }

.backLink {
  background: var(--panel2);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  border-radius: 0;
  padding: 8px 14px;
  font-size: 14px;
}

.copyBtn { font-family: inherit; line-height: normal; margin-left: auto }

body.tx .main,
body.rx .main { max-width: 720px; margin: 0 auto; padding: 14px 16px 40px }

.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 0;
  margin-bottom: 14px;
  padding: 14px;
}

.card h2 {
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
  margin: 0 0 10px;
  font-size: 13px;
}

.cardHeaderRow {
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  display: flex;
}

.cardHeaderRow h2 { margin: 0 }

.hint { color: var(--muted); margin: 0 0 8px; font-size: 11.5px }

.idgrid { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 8px; display: grid }

.idbtn {
  background: var(--panel2);
  border: 1px solid var(--border);
  color: var(--text);
  text-align: center;
  cursor: pointer;
  border-radius: 0;
  padding: 8px 6px;
  font-size: 12px;
}

.idbtn b { font-size: 13px; display: block }
.idbtn span { color: var(--muted); font-size: 10px }
.idbtn.audible { background: #1f1a08; border-color: #4a3f12 }
.idbtn.audible span { color: #b8962e }
.idbtn.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset }

.legend { align-items: center; gap: 8px; margin: 0 0 10px; display: flex }
.legend .swatch { background: #1f1a08; border: 1px solid #4a3f12; flex-shrink: 0; width: 10px; height: 10px }
.idbtn:disabled { opacity: .35; cursor: not-allowed }

.stopbtn {
  border: 1px solid var(--text);
  width: 100%;
  color: var(--text);
  cursor: pointer;
  background: #1a1a1a;
  border-radius: 0;
  margin-top: 10px;
  padding: 9px;
  font-size: 12.5px;
  font-weight: 700;
}

.fsbtn {
  background: var(--panel2);
  border: 1px solid var(--border);
  width: 100%;
  color: var(--text);
  cursor: pointer;
  border-radius: 0;
  margin-top: 8px;
  padding: 8px;
  font-size: 12.5px;
}

.statustext { color: var(--muted); min-height: 16px; margin-top: 8px; font-size: 12.5px }

.wavecanvas {
  border: 1px solid var(--border);
  background: #050505;
  border-radius: 0;
  width: 100%;
  height: 64px;
  margin-top: 10px;
  display: block;
}

.shortcutHint { color: var(--muted); text-align: center; margin-top: 4px; font-size: 11px }

.shortcutHint kbd {
  border: 1px solid var(--border);
  background: #1a1a1a;
  border-radius: 0;
  padding: 1px 6px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 10.5px;
}

/* ---------- mode toggle (both pages; tx uses a wider gap below) ---------- */

.modeToggle { gap: 8px; margin-bottom: 10px; display: flex }
body.tx .modeToggle { margin-bottom: 12px }

.modeBtn {
  background: var(--panel2);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  border-radius: 0;
  flex: 1;
  padding: 8px;
  font-size: 12.5px;
}

.modeBtn.active {
  background: var(--accent2);
  border-color: var(--accent2);
  color: #000;
  font-weight: 700;
}

/* ---------- transmitter ---------- */

.debugBox {
  background: #050505;
  border-radius: 0;
  justify-content: center;
  align-items: center;
  width: 100%;
  max-height: 120px;
  margin-top: 12px;
  padding: 18px;
  display: flex;
  position: relative;
}

.debugLine {
  color: #fff;
  white-space: nowrap;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 26px;
  font-weight: 700;
  line-height: 1.15;
}

.groupLabel {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin: 14px 0 8px;
  font-size: 11.5px;
}

.patternRow { flex-wrap: wrap; gap: 10px; margin-bottom: 10px; display: flex }

.patternRow label { min-width: 120px; color: var(--muted); flex: 1; font-size: 11.5px; display: block }

.patternRow input {
  background: var(--panel2);
  border: 1px solid var(--border);
  width: 100%;
  color: var(--text);
  border-radius: 0;
  margin-top: 4px;
  padding: 8px;
  font-size: 13px;
}

.volRow { align-items: center; gap: 10px; margin-top: 10px; display: flex }

.volRow label { color: var(--muted); min-width: 48px; font-size: 11.5px }

.volRow output {
  color: var(--muted);
  min-width: 36px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
}

.volRow input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  flex: 1;
  height: 24px;
  margin: 0;
  cursor: pointer;
}

.volRow input[type="range"]::-webkit-slider-runnable-track { height: 2px; background: var(--border) }
.volRow input[type="range"]::-moz-range-track { height: 2px; background: var(--border) }

.volRow input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px;
  height: 12px;
  margin-top: -5px;
  background: var(--text);
  border: 1px solid var(--text);
  border-radius: 0;
}

.volRow input[type="range"]::-moz-range-thumb {
  width: 12px;
  height: 12px;
  background: var(--text);
  border: 1px solid var(--text);
  border-radius: 0;
}

.volRow input[type="range"]:focus-visible { outline: 2px solid var(--text); outline-offset: 2px }

.qrWrap { justify-content: center; padding: 2px 0; display: flex }

.qrCanvas {
  image-rendering: pixelated;
  background: #fff;
  max-width: 100%;
  height: auto;
  display: block;
}

.qrUrl {
  color: var(--muted);
  text-align: center;
  word-break: break-all;
  margin-top: 10px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11.5px;
}

/* ---------- receiver ---------- */

.startBtn {
  background: var(--accent2);
  border: 1px solid var(--accent2);
  color: #000;
  cursor: pointer;
  border-radius: 0;
  width: 100%;
  padding: 12px;
  font-size: 14px;
  font-weight: 700;
}

.bigreadout { text-align: center; gap: 10px; margin-bottom: 4px; display: flex }

.bigreadout .col {
  background: var(--panel2);
  border: 1px solid var(--border);
  border-radius: 0;
  flex: 1;
  padding: 12px 8px;
}

.bigreadout .col .val { font-size: 26px; font-weight: 700 }
.bigreadout .col .lbl { color: var(--muted); margin-top: 2px; font-size: 11px }

.pairline { color: var(--muted); text-align: center; margin-top: 6px; font-size: 12px }

.lastDetected {
  color: var(--muted);
  text-align: center;
  border-top: 1px dashed var(--border);
  margin-top: 8px;
  padding-top: 8px;
  font-size: 11.5px;
}

.statusline {
  color: var(--muted);
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  font-size: 12.5px;
  display: flex;
}

.statusline .ok { color: var(--good); font-weight: 700 }
.statusline .err { color: var(--accent); font-weight: 700; text-decoration: underline }

.statusDot { background: currentColor; flex-shrink: 0; width: 8px; height: 8px }
.err .statusDot { background: 0 0; border: 1px solid }

.retryBtn {
  background: var(--panel2);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  border-radius: 0;
  padding: 4px 10px;
  font-size: 11.5px;
}

.dbMeter { margin-top: 10px }
.dbMeterBar { background: #161616; border-radius: 0; height: 14px; overflow: hidden }

.dbMeterBar i {
  background: var(--accent2);
  width: 0%;
  height: 100%;
  transition: width 50ms linear;
  display: block;
}

.dbMeterBar i.dbMeterFillHot { background: var(--good) }
.dbMeterBar i.dbMeterFillLoud { background: #ff3b3b }

.dbMeterText {
  color: var(--muted);
  margin-top: 6px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11px;
}

.dbMeterControls { flex-wrap: wrap; gap: 14px; margin-top: 6px; display: flex }

.meters { margin-top: 10px }

.meterrow {
  color: var(--muted);
  align-items: center;
  gap: 8px;
  margin: 6px 0;
  font-size: 11.5px;
  display: flex;
}

.meterrow .dot { background: #333; border-radius: 0; flex-shrink: 0; width: 10px; height: 10px }
.meterrow .dot.on { background: var(--good); box-shadow: 0 0 6px var(--good) }
.meterrow .lbl { flex-shrink: 0; width: 64px }
.meterrow .bar { background: #161616; border-radius: 0; flex: 1; height: 6px; overflow: hidden }
.meterrow .bar i { background: var(--accent2); width: 0%; height: 100%; display: block }

.displayBox {
  aspect-ratio: 1;
  background: #000;
  border-radius: 0;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  max-height: 260px;
  display: flex;
  position: relative;
  overflow: hidden;
}

.displayBox.displayBoxActive {
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  max-height: none;
  aspect-ratio: unset;
  z-index: 1000;
  cursor: pointer;
  border-radius: 0;
  position: fixed;
  inset: 0;
}

.displayLabel {
  color: #ffffffb3;
  text-transform: uppercase;
  letter-spacing: .12em;
  margin-bottom: .3em;
  font-family: ui-monospace, Menlo, Consolas, monospace;
}

.displayAudioId {
  color: #fff;
  text-shadow: 0 .05em .4em #000000a6;
  white-space: nowrap;
  text-overflow: ellipsis;
  max-width: 92%;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-weight: 800;
  line-height: 1;
  overflow: hidden;
}

.tagList { flex-direction: column; gap: 8px; margin-bottom: 10px; display: flex }
.tagRow { align-items: center; gap: 8px; display: flex }

.tagRow select {
  background: var(--panel2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 0;
  flex-shrink: 0;
  padding: 7px 8px;
  font-size: 12.5px;
}

.tagArrow { color: var(--muted); flex-shrink: 0; font-size: 12px }

.tagRow input[type=text] {
  background: var(--panel2);
  border: 1px solid var(--border);
  min-width: 0;
  color: var(--text);
  border-radius: 0;
  flex: 1;
  padding: 7px 10px;
  font-size: 12.5px;
}

.tagRemoveBtn {
  border: 1px solid var(--text);
  color: var(--text);
  cursor: pointer;
  background: #1a1a1a;
  border-radius: 0;
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  width: 30px;
  height: 30px;
  font-size: 14px;
  display: flex;
}

.emptyTags { color: var(--muted); padding: 4px 0 8px; font-size: 11.5px }

.tagOnlyToggle {
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  display: flex;
}

.tagOnlyToggle input {
  width: 13px;
  height: 13px;
  accent-color: var(--text);
  cursor: pointer;
  flex-shrink: 0;
}

.log {
  border: 1px solid var(--border);
  color: #9a9a9a;
  white-space: pre-wrap;
  background: #0a0a0a;
  border-radius: 0;
  height: 150px;
  padding: 8px 10px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11px;
  overflow-y: auto;
}

.log div { color: var(--muted); border-bottom: 1px dashed #1a1a1a; padding: 2px 0 }

/* ---------- launch gate (transmitter, ?a= / ?ap=) ---------- */

.gate {
  z-index: 1000;
  background: #000000d9;
  justify-content: center;
  align-items: center;
  padding: var(--pad-inline);
  display: flex;
  position: fixed;
  inset: 0;
}

.gate[hidden] { display: none }

.gateCard {
  background: var(--panel);
  border: 1px solid var(--border);
  width: 100%;
  max-width: 360px;
  text-align: center;
  padding: 22px 18px;
}

.gateKicker {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .12em;
  margin-bottom: 8px;
  font-size: 11px;
}

.gateLabel {
  color: var(--text);
  margin-bottom: 16px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 20px;
  font-weight: 800;
}

.gateBtn {
  border: 1px solid var(--text);
  width: 100%;
  color: var(--text);
  cursor: pointer;
  background: #1a1a1a;
  border-radius: 0;
  padding: 14px;
  font-size: 14px;
  font-weight: 700;
}

.gateNote { color: var(--muted); margin: 12px 0 0; font-size: 11.5px }
