/**
 * css/shell/listen.css
 * Listen screen: the "now reading" card, the transport (prev / play / next /
 * speed + scrubber), and the settings rows that host the app's own <select>
 * elements.
 *
 * Hosting the real selects rather than drawing custom dropdowns is deliberate:
 * a native <select> on Android opens the platform's own picker, which is a
 * better list for 179 voices than anything worth hand-rolling, and it keeps
 * the app's change handlers untouched.
 *
 * Dependencies: css/shell/tokens.css, css/shell/screens.css.
 */

/* ============================================================
   NOW READING
   ============================================================ */
.ts-now-label {
  font-size: 0.8125rem;
  color: var(--ts-text-dim);
}
/* The sentence being spoken, in the same colour the read-along uses on the
   page, so the two obviously refer to each other. */
.ts-now-line {
  font-size: 0.9375rem;
  line-height: 1.45;
  color: #f2d675;
  /* Two lines, not three. Three made the card height depend on how wide the
     screen is — the same sentence wraps to two lines at 500px and three at
     412px — so the screen fitted in testing and scrolled on a real phone.
     Two lines is still plenty to recognise the place, and is the same height
     everywhere. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ts-now-body { padding: 0.75rem 1rem 0.875rem; }

/* ============================================================
   TRANSPORT
   ============================================================ */
.ts-transport {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  padding: 0.875rem 1rem 0.5rem;
}

.ts-tbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem; height: 3rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ts-text);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.ts-tbtn:active { background: var(--ts-surface-2); }
.ts-tbtn svg { width: 2rem; height: 2rem; }
.ts-tbtn:disabled { opacity: 0.3; cursor: default; }

.ts-tbtn-main {
  width: 4.5rem; height: 4.5rem;
  background: var(--ts-accent);
  color: var(--ts-accent-ink);
}
.ts-tbtn-main:active { background: var(--ts-accent); filter: brightness(0.94); }
.ts-tbtn-main svg { width: 2.25rem; height: 2.25rem; }
.ts-tbtn-main:disabled { opacity: 0.45; }

.ts-speed-pill {
  min-width: 3.25rem;
  padding: 0.4375rem 0.625rem;
  border: 1px solid var(--ts-border);
  border-radius: 0.5rem;
  background: transparent;
  color: var(--ts-text);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* ---- scrubber ---------------------------------------------------------- */
.ts-scrub {
  padding: 0 1rem 1rem;
}
.ts-scrub .ts-slider::-webkit-slider-thumb { background: var(--ts-accent); }
.ts-scrub .ts-slider::-moz-range-thumb { background: var(--ts-accent); }
/* The filled portion is drawn on the track itself via a gradient the script
   updates, because a range input has no styleable "played" segment. */
.ts-scrub .ts-slider::-webkit-slider-runnable-track {
  background: linear-gradient(to right, var(--ts-accent) var(--ts-fill, 0%), var(--ts-track) var(--ts-fill, 0%));
}
.ts-scrub .ts-slider::-moz-range-track {
  background: linear-gradient(to right, var(--ts-accent) var(--ts-fill, 0%), var(--ts-track) var(--ts-fill, 0%));
}

/* ============================================================
   HOSTED <select> CONTROLS
   ============================================================ */
.ts-select-host {
  flex: none;
  max-width: 60%;
  display: inline-flex;
  align-items: center;
}
.ts-select-host select {
  max-width: 100%;
  padding: 0.25rem 0.125rem;
  border: 0;
  background: transparent;
  color: var(--ts-text);
  font-size: 0.9375rem;
  font-family: inherit;
  text-align: right;
  text-align-last: right;
  cursor: pointer;
  /* Keep the platform's own chevron: it signals "this opens a picker" in the
     way the platform's users already recognise. */
}
.ts-select-host select option { color: #111; }

/* ============================================================
   ADVANCED — expandable block of the less-used settings
   ============================================================ */
.ts-advanced-row .ts-row-value { color: var(--ts-text-dim); font-size: 0.875rem; }
.ts-advanced .ts-row { padding-left: 1rem; }
.ts-advanced[hidden] { display: none; }

/* ============================================================
   SAVE AUDIO
   ============================================================ */
.ts-save-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0 1rem 0.875rem;
}
.ts-save-list .ts-ghostbtn:disabled { opacity: 0.45; cursor: default; }

/* Engine status (loading a voice, downloading a model, recording progress),
   mirrored from the app's own #ttsProgress strip. */
.ts-now-status {
  margin-top: 0.25rem;
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--ts-text-dim);
}

/* ============================================================
   COMPACT LAYOUT — fit the whole screen without scrolling

   On a 384x832 phone the usable band between the app bar and the tab bar is
   about 660px. Laid out at the shared row sizes this screen needed ~830 and
   the Save audio card fell off the bottom. These overrides trim each block
   rather than dropping a control: nothing here is hidden, only tightened.
   ============================================================ */
#tsScreenListen .ts-card { margin-bottom: 0.5rem; }

/* Now reading: two lines of sentence is enough to recognise the place. */
#tsScreenListen .ts-now-body { padding: 0.625rem 0.875rem 0.75rem; }
#tsScreenListen .ts-now-line { font-size: 0.875rem; -webkit-line-clamp: 2; }
#tsScreenListen .ts-now-status { font-size: 0.875rem; }

/* Transport: the main button stays comfortably tappable (56px is well above
   the 48px minimum) while giving back ~20px. */
#tsScreenListen .ts-transport { gap: 1rem; padding: 0.75rem 1rem 0.5rem; }
#tsScreenListen .ts-tbtn { width: 2.75rem; height: 2.75rem; }
#tsScreenListen .ts-tbtn svg { width: 1.75rem; height: 1.75rem; }
#tsScreenListen .ts-tbtn-main { width: 3.5rem; height: 3.5rem; }
#tsScreenListen .ts-tbtn-main svg { width: 1.75rem; height: 1.75rem; }
#tsScreenListen .ts-scrub { padding: 0 1rem 0.625rem; }

/* Settings rows: five of them, so every pixel here counts five times over.
   2.75rem keeps each row above the 44px touch-target guideline. */
#tsScreenListen .ts-row { min-height: 2.75rem; padding: 0.5rem 0.875rem; }
#tsScreenListen .ts-row-label { font-size: 0.875rem; }
#tsScreenListen .ts-row-icon { width: 1.25rem; height: 1.25rem; }
#tsScreenListen .ts-select-host select { font-size: 0.875rem; }
#tsScreenListen .ts-switch { width: 2.75rem; height: 1.625rem; }
#tsScreenListen .ts-switch::after { width: 1.25rem; height: 1.25rem; }
#tsScreenListen .ts-switch[aria-checked="true"]::after { transform: translateX(1.125rem); }

/* Save audio: side by side rather than stacked — two short labels do not each
   need a full-width row, and this recovers a whole button's height. */
#tsScreenListen .ts-card-title { padding: 0.625rem 0.875rem 0.375rem; font-size: 0.875rem; }
#tsScreenListen .ts-save-list {
  flex-direction: row;
  /* Wrap, or the full-width third button below squeezes these two to slivers
     instead of dropping onto its own line. */
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0 0.875rem 0.75rem;
}
#tsScreenListen .ts-save-list .ts-ghostbtn {
  flex: 1 1 0;
  min-width: 0;
  padding: 0.625rem 0.5rem;
  font-size: 0.8125rem;
}
#tsScreenListen .ts-save-list .ts-ghostbtn span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* "Save what you have heard" only appears once there is something to save, so
   it takes the full width on its own line when it does. */
#tsScreenListen #tsSaveHeard { flex-basis: 100%; }

/* ============================================================
   HOSTED PLAY / STOP — the app's own #listenBtn and #ttsStop

   These are the real buttons, moved into the transport, so their labels are
   whatever the engine sets ("🔊 Listen", "⏸ Pause", "▶ Resume", "⏹ Stop") and
   their disabled states are the engine's own. Only their appearance is the
   shell's; their behaviour is untouched.
   ============================================================ */
#tsTransport {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 0.875rem 0.5rem;
}

#tsTransport #listenBtn {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  min-height: 3rem;
  margin: 0;
  padding: 0.75rem 0.5rem;
  border: 0;
  border-radius: 0.75rem;
  background: var(--ts-accent);
  color: var(--ts-accent-ink);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
#tsTransport #listenBtn:disabled { opacity: 0.5; cursor: default; }

/* Stop is deliberately its own always-present button rather than a state of
   the play button: "I want this to stop now" should never require working out
   which state the single control is currently in. */
#tsTransport #ttsStop {
  flex: 0 1 auto;
  width: auto;
  min-width: 0;
  min-height: 3rem;
  margin: 0;
  padding: 0.75rem 1rem;
  border: 1px solid rgba(239, 68, 68, 0.5);
  border-radius: 0.75rem;
  background: rgba(239, 68, 68, 0.14);
  color: #f87171;
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
#tsTransport #ttsStop:disabled { opacity: 0.45; cursor: default; }

/* Read-only position bar (there is no audio file to seek). */
.ts-progressbar {
  height: 0.25rem;
  border-radius: 999px;
  background: var(--ts-track);
  overflow: hidden;
}
.ts-progressbar-fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--ts-accent);
  transition: width 0.2s linear;
}


/* "Speech engine" should keep its own line; the engine name shrinks instead. */
#tsScreenListen .ts-row-label { white-space: nowrap; }
#tsScreenListen .ts-select-host { max-width: 62%; }
#tsScreenListen .ts-select-host select {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ============================================================
   FITTING ON ONE SCREEN

   The Listen screen is the one screen a reader uses without reading it —
   they press play, then look away. Making them scroll to reach Stop or the
   speed control is therefore worse here than anywhere else in the app.
   Measured with scripts/dev-listen-measure.js against the worst case (the
   now-reading line filled to its clamp), not the empty one.

   Scoped to this screen: Format and Display are genuinely long lists of
   settings and are expected to scroll, so their rows keep the roomier
   default. Rows stay above the 44px touch-target guideline at 52px.
   ============================================================ */
/* The rows already have a tighter rule further up this file; do NOT restate
   .ts-row here — an equal-specificity rule later in the file silently wins
   and makes every row TALLER, which is how this screen regressed once. */

/* The generous bottom gutter exists so the tab bar never crowds the last
   control. Half of it is enough once the cards themselves are this tight. */
#tsScreenListen { padding-bottom: calc(var(--ts-bottom-reserve) + 0.5rem); }

/* Last of the headroom, so the screen still fits when the engine's status
   line ("Downloading voice…") appears inside the first card mid-load.
   Appended at the end of the file deliberately: an equal-specificity rule
   earlier in the file would otherwise win and silently undo this. */
#tsScreenListen .ts-card { margin-bottom: 0.375rem; }

/* ============================================================
   THE SAME SCREEN IN THE WEB APP
   The web app on a phone runs this layout too, over base styles that have
   drifted from the Android app's in two places this screen shows:
   - .tts-listen/.tts-stop carry order:2 there (for the desktop toolbar), so
     the speed pill jumped in front of Listen; and
   - .tts-voice has appearance:none there, drawing its own arrow as a
     background -- which .ts-select-host select { background: transparent }
     above then wipes, leaving the drop-downs with no arrow at all.
   Both are restated here so the screen is the same in both apps. In the
   Android app nothing changes: its base styles already say this.
   ============================================================ */
body.ts-shell #tsTransport > * { order: 0; }
body.ts-shell .ts-select-host select {
  -webkit-appearance: auto;
  appearance: auto;
}

/* The web app's Listen and Stop wrap their icon in a 28px circle
   (<span class="tts-btn-icon">); the Android app's markup is plain "🔊 Listen".
   Under this layout the icon is plain text in both, so the buttons match. */
body.ts-shell #tsTransport .tts-btn-icon {
  display: inline;
  width: auto;
  height: auto;
  margin: 0;
  padding: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  font-size: inherit;
}
