@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700;800&family=Inter:wght@400;500;600&display=swap');

:root{
  --bg: #0d0f0e;
  --bg-panel: #141613;
  --line: #262b27;
  --amber: #ffb000;
  --amber-dim: #7a5600;
  --green: #4fd67a;
  --red: #ff5d5d;
  --text: #e9e6dd;
  --text-dim: #8a8f89;
  --mono: 'JetBrains Mono', monospace;
  --sans: 'Inter', sans-serif;
}
*{box-sizing:border-box; margin:0; padding:0;}
html,body{
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  min-height: 100vh;
  width: 100%;
}
body{
  display:flex; flex-direction:column; align-items:center;
  padding: 32px 16px 60px;
  background-image:
    radial-gradient(circle at 50% 0%, rgba(255,176,0,0.06), transparent 60%);
}
.wrap{ width:75%; max-width: none; }

header{ margin-bottom: 22px; text-align: center; }
h1{
  font-family: var(--mono); font-weight: 800; font-size: 22px;
  letter-spacing: -0.01em; color: var(--amber);
}

.panel{
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 24px;
  margin-top: 18px;
}

/* mic control */
.control-row{ display:flex; align-items:center; gap: 14px; margin-bottom: 4px; }
button{
  font-family: var(--mono); font-weight: 700; font-size: 13px;
  letter-spacing: 0.04em; text-transform: uppercase;
  padding: 11px 20px; border-radius: 6px; cursor:pointer;
  border: 1px solid var(--amber); background: transparent; color: var(--amber);
  transition: all 0.15s ease;
}
button:hover{ background: rgba(255,176,0,0.1); }
button.active{ background: var(--amber); color: #0d0f0e; }
button:disabled{ opacity:0.4; cursor:default; }
.icon-btn{
  display:inline-flex; align-items:center; justify-content:center;
  padding: 11px 14px;
}
.icon-btn span{ display:flex; align-items:center; justify-content:center; width:100%; height:100%; }
.icon-btn svg{ display:block; width: 18px; height: 18px; }
.status{ font-family: var(--mono); font-size: 12px; color: var(--text-dim); }
.status.live::before{
  content:''; display:inline-block; width:7px; height:7px; border-radius:50%;
  background: var(--red); margin-right:7px; vertical-align:1px;
  animation: pulse 1.4s infinite;
}

/* tabs */
.tab-bar{
  display:flex; gap: 4px; margin: 22px 0 0; border-bottom: 1px solid var(--line);
}
.tab-btn{
  border: none; border-bottom: 2px solid transparent; border-radius: 0;
  background: transparent; color: var(--text-dim);
  padding: 10px 14px; font-size: 12px;
}
.tab-btn:hover{ background: transparent; color: var(--text); }
.tab-btn.active{ background: transparent; color: var(--amber); border-bottom-color: var(--amber); }
.tab-content{ display:none; padding-top: 22px; }
.tab-content.active{ display:block; }
@keyframes pulse{ 0%,100%{opacity:1;} 50%{opacity:0.25;} }

/* note readout */
.readout{
  display:flex; align-items:baseline; justify-content:center;
  gap: 10px; margin: 30px 0 6px;
}
.note-big{
  font-family: var(--mono); font-weight: 800; font-size: 76px;
  line-height:1; color: var(--text); min-width: 120px; text-align:center;
  transition: color 0.15s ease;
}
.note-oct{ font-family: var(--mono); font-size: 28px; color: var(--text-dim); font-weight: 500; }
.freq{
  text-align:center; font-family: var(--mono); font-size: 13px; color: var(--text-dim);
  margin-bottom: 26px;
}

/* cents gauge */
.gauge-wrap{ position:relative; margin: 0 auto 8px; width: 100%; max-width: 460px; }
.gauge-ticks{ display:flex; justify-content:space-between; font-family: var(--mono);
  font-size: 10px; color: var(--text-dim); margin-bottom: 6px; padding: 0 2px;}
.gauge-track{
  position:relative; height: 34px; background: #0a0b0a;
  border: 1px solid var(--line); border-radius: 4px; overflow:hidden;
}
.gauge-zone-safe{
  position:absolute; left:35%; width:30%; top:0; bottom:0;
  background: rgba(79,214,122,0.14); border-left:1px solid rgba(79,214,122,0.4);
  border-right:1px solid rgba(79,214,122,0.4);
}
.gauge-center-line{
  position:absolute; left:50%; top:0; bottom:0; width:1px; background: var(--text-dim);
}
.gauge-needle{
  position:absolute; top:2px; bottom:2px; width: 4px; border-radius: 2px;
  background: var(--amber); left:50%; transform: translateX(-50%);
  box-shadow: 0 0 10px rgba(255,176,0,0.7);
  transition: left 0.06s linear, background-color 0.15s ease;
}
.cents-label{
  text-align:center; font-family: var(--mono); font-size: 12px; color: var(--text-dim);
  margin-top: 10px;
}
.cents-label b{ color: var(--text); font-size:14px; }

/* history strip */
.history-label{
  font-family: var(--mono); font-size: 11px; color: var(--text-dim);
  letter-spacing: 0.1em; text-transform: uppercase; margin: 26px 0 8px;
}
.charts-col-left{ display:flex; flex-direction:column; gap: 18px; }
canvas#history{
  width: 100%; height: 110px; display:block;
  background: #0a0b0a; border: 1px solid var(--line); border-radius: 4px;
}
canvas#pitchCurve{
  width: 100%; height: 180px; display:block;
  background: #0a0b0a; border: 1px solid var(--line); border-radius: 4px;
}
canvas#spectrum{
  width: 100%; height: 480px; display:block;
  background: #0a0b0a; border: 1px solid var(--line); border-radius: 4px;
}

/* stats */
.stats{
  display:grid; grid-template-columns: repeat(3,1fr); gap: 10px; margin-top: 18px;
}
.stat{
  background: #0a0b0a; border:1px solid var(--line); border-radius: 6px;
  padding: 12px 14px;
}
.stat .val{ font-family: var(--mono); font-weight:700; font-size: 20px; }
.stat .lbl{ font-family: var(--mono); font-size: 10px; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 0.06em; margin-top: 3px; }

.report{
  display:none; white-space: pre-wrap; font-family: var(--mono); font-size: 11px;
  color: var(--text-dim); background: #0a0b0a; border: 1px solid var(--line);
  border-radius: 4px; padding: 10px; margin-top: 8px; max-height: 260px; overflow-y:auto;
}
.report.visible{ display:block; }

.infos-text{
  font-family: var(--mono); font-size: 11.5px; color: var(--text-dim); line-height:1.6;
}
.infos-text b{ color: var(--text); }

.options-list{ display:flex; flex-direction:column; gap:16px; }
.option-row{
  position: relative; display:flex; align-items:center; gap:10px;
  font-family: var(--mono);
}
.option-row input[type="checkbox"]{ flex-shrink:0; width:16px; height:16px; accent-color: var(--amber); }
.option-label{ flex:1; font-size: 13px; color: var(--text); cursor:pointer; }

.info-btn{
  flex-shrink:0; width:20px; height:20px; border-radius:50%; padding:0;
  border:1px solid var(--line); background:transparent; color: var(--text-dim);
  font-family: var(--mono); font-size:11px; line-height:1; cursor:pointer;
}
.info-btn:hover{ color: var(--text); border-color: var(--text-dim); }

/* Tap-to-open info bubble (no hover reliance — this menu is mainly used on
   phones). Floats below the row instead of pushing the rest of the list
   down, and spans the row's own width so it can never overflow the
   viewport sideways on a narrow phone. */
.tooltip{
  display:none; position:absolute; top: calc(100% + 6px); left:0; right:0; z-index:5;
  font-size: 11px; color: var(--text-dim); line-height:1.6;
  background: var(--bg-panel); border:1px solid var(--line); border-radius:6px; padding:10px 12px;
}
.tooltip b{ color: var(--text); }
.option-row.tooltip-open .tooltip{ display:block; }

/* Portrait (phone-like): the real problem isn't device type, it's a narrow
   tall viewport — a resized desktop window gets this too, which is correct.
   Landscape/wide screens keep the desktop rules above untouched. Sizes here
   are bumped well beyond a simple scale-up: this is meant to be read at a
   glance and tapped accurately while singing, not squinted at. */
@media (orientation: portrait){
  /* 100vh is unreliable on mobile browsers (address bar collapsing/expanding
     changes it mid-session); 100dvh tracks the actual visible viewport. A
     flex-grow chain this deep (body>wrap>panel>tab>report) also needs
     min-height:0 at every level — without it, a flex item's default
     min-height:auto can stop it from ever growing past its own content,
     which is exactly why the report box was collapsing to ~1 line instead
     of filling the tab. */
  html, body{ height: 100dvh; min-height: 0; }
  body{ padding: 20px 0 30px; }
  .wrap{ width: 100%; flex: 1; display: flex; flex-direction: column; min-height: 0; }
  header{ padding: 0 16px; }
  .panel{
    flex: 1; display: flex; flex-direction: column; min-height: 0;
    border-radius: 0; border-left: none; border-right: none; padding: 20px 16px;
  }
  /* Each tab's own content spreads across whatever vertical space is left
     after the controls and tab bar, instead of clumping at the top. */
  .tab-content.active{ flex: 1; display: flex; flex-direction: column; justify-content: space-evenly; min-height: 0; }

  /* Sizes below scale with the actual viewport (vw) instead of fixed px, so
     they land right on a small phone AND a big one instead of needing
     another guess-and-check round every time. clamp(min, preferred, max)
     keeps them from going absurd at either extreme. */
  h1{ font-size: clamp(28px, 9vw, 48px); }

  .control-row{ flex-wrap: wrap; gap: 12px; justify-content: center; }
  button{ font-size: clamp(15px, 4.2vw, 20px); padding: 16px 22px; }
  .icon-btn{ padding: 16px 20px; }
  .icon-btn svg{ width: 24px; height: 24px; }
  .status{ font-size: clamp(13px, 4vw, 18px); flex-basis: 100%; text-align: center; }

  /* Primary controls: big square touch targets, side by side filling the row.
     min-width stops them shrinking past the point where the label/icon still
     fits — below that, .control-row's flex-wrap drops them to their own
     line instead of squeezing and clipping "Start" or the play icon. */
  #toggleBtn, #replayBtn{
    flex: 1 1 0; aspect-ratio: 1 / 1; min-width: 100px;
    display: flex; align-items: center; justify-content: center;
    padding: 12px;
  }
  #toggleBtn{ font-size: clamp(26px, 9vw, 44px); }
  #replayBtn.icon-btn svg{ width: 40%; height: 40%; }

  .tab-bar{ gap: 2px; }
  .tab-btn{ font-size: clamp(20px, 8.5vw, 34px); padding: 16px 4px; flex: 1 1 auto; line-height: 1.1; }
  .tab-content{ padding-top: 28px; }

  /* Analyse: one big button. The report flows normally right under the
     status line instead of trying to exactly fill the tab's height — that
     nested-flex approach kept collapsing to ~1 line depending on the
     device. If it's long, the page scrolls; simple and it actually works. */
  #analyseBtn{ width: 100%; font-size: clamp(22px, 8vw, 38px); padding: 30px; }
  [data-tab-content="analyse"].active{ display: block; flex: none; }
  .report{ font-size: clamp(20px, 6.5vw, 30px); line-height: 1.5; max-height: none; }

  /* Options: same reasoning as Analyse above — a variable-length list of
     checkboxes doesn't work as a space-evenly flex column, it just flows and
     scrolls with the page. */
  [data-tab-content="options"].active{ display: block; flex: none; }
  .options-list{ gap: 22px; }
  .option-label{ font-size: clamp(15px, 4.2vw, 19px); }
  .info-btn{ width: 30px; height: 30px; font-size: clamp(13px, 3.5vw, 16px); }
  .tooltip{ font-size: clamp(13px, 3.8vw, 16px); padding: 12px 14px; }

  /* Direct + Fourier share the tab 50/50, each its own flex column. */
  .live-block, .spectrum-block{
    flex: 1; display: flex; flex-direction: column;
    justify-content: space-evenly; min-height: 0;
  }

  .note-big{ font-size: clamp(72px, 28vw, 150px); }
  .note-oct{ font-size: clamp(28px, 10vw, 52px); }
  .freq{ font-size: clamp(16px, 5vw, 26px); margin-bottom: 34px; }

  .gauge-wrap{ max-width: none; }
  .gauge-ticks{ font-size: clamp(12px, 4vw, 20px); }
  .gauge-track{ height: 56px; }
  .gauge-needle{ width: 6px; }
  .cents-label{ font-size: clamp(15px, 4.5vw, 24px); margin-top: 16px; }
  .cents-label b{ font-size: clamp(18px, 5.5vw, 28px); }

  .history-label{ font-size: clamp(13px, 4vw, 20px); margin: 30px 0 10px; }
  .charts-col-left{ gap: 26px; }
  canvas#history{ height: 220px; }
  canvas#pitchCurve{ height: 420px; }
  canvas#spectrum{ flex: 1; height: auto; min-height: 0; }

  .stats{ gap: 14px; margin-top: 26px; }
  .stat{ padding: 16px; }
  .stat .val{ font-size: clamp(22px, 8vw, 40px); }
  .stat .lbl{ font-size: clamp(11px, 3.2vw, 16px); }

  .infos-text{ font-size: clamp(14px, 4.5vw, 20px); line-height: 1.7; }
}
