/* Live Translator — one dark, high-contrast screen built for a phone held in one hand.
   No external fonts or requests. Sizes: translation text never below 28px, tap targets ≥ 44px. */

:root {
  --bg: #0b0d10;
  --surface: #15181d;
  --surface-2: #1f242b;
  --line: #2c333d;
  --text: #f6f8fa;
  --muted: #aab3bf;
  --faint: #8a94a1;
  --accent: #2563eb;      /* idle big button, primary buttons (white text 5.2:1) */
  --accent-text: #8fb6ff; /* accent on dark backgrounds */
  --live: #d93036;        /* listening (white text 4.7:1) */
  --her: #f2b84b;         /* her words → them (amber) */
  --them: #3fc4a4;        /* their words → her (teal) */
  --danger: #ff7a7a;
  --warn: #f2b84b;
  --radius: 18px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --sat: env(safe-area-inset-top, 0px);
  --sar: env(safe-area-inset-right, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);
  --big: clamp(150px, 48vw, 232px);
  color-scheme: dark;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html,
body {
  height: 100%;
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
  line-height: 1.35;
}

button,
input {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

button:disabled {
  cursor: default;
  opacity: 0.45;
}

:focus-visible {
  outline: 3px solid #9cc2ff;
  outline-offset: 2px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  opacity: 0;
}

.noscript {
  padding: 24px;
  font-size: 20px;
}

/* ---------- buttons ---------- */

.btn {
  min-height: 52px;
  padding: 0 22px;
  border-radius: 16px;
  border: 1px solid transparent;
  font-size: 18px;
  font-weight: 700;
  line-height: 1.1;
}

.btn-primary {
  background: var(--accent);
  color: #fff;
}

.btn-secondary {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--text);
}

.btn-quiet {
  background: transparent;
  color: var(--accent-text);
  min-height: 48px;
  padding: 0 12px;
}

.btn-wide {
  width: 100%;
}

.icon-btn {
  flex: none;
  width: 56px;
  height: 56px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--text);
  padding: 0;
}

/* ---------- screens ---------- */

.screen {
  position: fixed;
  inset: 0;
}

.center-screen {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(var(--sat) + 24px) calc(var(--sar) + 16px) calc(var(--sab) + 24px) calc(var(--sal) + 16px);
  overflow-y: auto;
}

.boot-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  text-align: center;
}

.boot-msg {
  margin: 0;
  font-size: 20px;
  color: var(--muted);
  max-width: 22em;
}

/* ---------- login ---------- */

.login-card {
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.login-logo {
  width: 72px;
  height: 72px;
  border-radius: 18px;
  align-self: center;
}

.login-title {
  margin: 4px 0 12px;
  text-align: center;
  font-size: 30px;
  font-weight: 800;
}

.login-label {
  font-size: 17px;
  font-weight: 700;
  color: var(--muted);
}

.login-input {
  min-height: 60px;
  padding: 0 16px;
  border-radius: 16px;
  border: 2px solid var(--line);
  background: var(--surface);
  font-size: 24px;
  letter-spacing: 0.05em;
}

.login-input:focus {
  border-color: var(--accent);
  outline: none;
}

.login-card .btn {
  min-height: 60px;
  font-size: 21px;
  margin-top: 4px;
}

.login-error {
  min-height: 1.4em;
  margin: 4px 0 0;
  color: var(--danger);
  font-size: 18px;
  font-weight: 600;
  text-align: center;
}

/* ---------- main layout ---------- */

.main-screen {
  display: flex;
  flex-direction: column;
  max-width: 720px;
  margin: 0 auto;
}

.topbar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(var(--sat) + 10px) calc(var(--sar) + 12px) 8px calc(var(--sal) + 12px);
}

.chip {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 1px;
  padding: 5px 14px;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  text-align: left;
}

.chip-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}

.chip-value {
  display: flex;
  align-items: center;
  gap: 4px;
  max-width: 100%;
  font-size: 20px;
  font-weight: 800;
  line-height: 1.15;
}

#lang-chip-value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chip[data-auto="true"] #lang-chip-value {
  color: var(--accent-text);
}

.chip-caret {
  flex: none;
  color: var(--muted);
}

/* Voice + Text / Text only pill: icon over its label on phones (a side-by-side pill with
   "Voice + Text" does not fit next to the language chip there), side by side from 600 px.
   A fixed width, so switching never moves the chip. */
.mode-pill {
  flex: none;
  width: 90px;
  height: 56px;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 0 2px;
  border-radius: 24px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--muted);
}

.mode-pill[aria-pressed="true"] {
  color: var(--her);
  border-color: rgba(242, 184, 75, 0.55);
  background: rgba(242, 184, 75, 0.13);
}

.mode-pill:disabled {
  opacity: 0.55;
}

.mode-pill svg {
  flex: none;
}

.mode-label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 800;
  line-height: 1.1;
}

.mode-label-short {
  display: none;
}

#speaker-btn .ico-off,
#speaker-btn[aria-pressed="false"] .ico-on {
  display: none;
}

#speaker-btn[aria-pressed="false"] .ico-off {
  display: block;
}

/* Male / female voice toggle: glyph over the voice's name, same size as the icon buttons. */
.voice-btn {
  flex-direction: column;
  gap: 2px;
  padding: 0 4px;
  color: var(--her);
}

.voice-ico {
  flex: none;
}

/* Text only: the voice choice still works (for Replay / later) but is greyed out. */
#speaker-btn[aria-pressed="false"] ~ .voice-btn,
#speaker-btn[aria-pressed="false"] ~ .voice-btn .voice-name {
  color: var(--faint);
}

.voice-btn[data-voice="male"] .voice-ico-female,
.voice-btn[data-voice="female"] .voice-ico-male {
  display: none;
}

.voice-name {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--text);
}

/* Wider screens (tablets, desktop): the pill is a real side-by-side pill. */
@media (min-width: 600px) {
  .mode-pill {
    width: auto;
    min-width: 168px;
    flex-direction: row;
    gap: 7px;
    padding: 0 16px 0 13px;
    border-radius: 999px;
  }
  .mode-label {
    font-size: 15px;
  }
}

/* Phones: the chip, the pill, the voice toggle, the currency converter and the camera share
   one row, so the bar is tight: 44 px icon buttons (the minimum tap size), 3 px gaps, a 17 px
   chip value. Sized with Helvetica-width text (Arial here; wider than the Segoe UI a desktop
   browser uses; iOS's SF Pro is in between): at 390 px and up the pill says "Voice + Text"
   and the chip still shows "Auto-detect" in full. A long language name ellipsizes before
   anything overflows. */
@media (max-width: 599px) {
  .topbar {
    gap: 3px;
    padding-left: calc(var(--sal) + 6px);
    padding-right: calc(var(--sar) + 6px);
  }
  .topbar .icon-btn {
    width: 44px;
  }
  .topbar .voice-btn {
    padding: 0;
  }
  .mode-pill {
    width: 86px;
    padding: 0;
  }
  .chip {
    padding: 5px 4px 5px 6px;
  }
  .chip-value {
    gap: 2px;
    font-size: 17px;
  }
  .chip .chip-caret {
    width: 14px;
    height: 14px;
  }
}

/* 375 px phones and narrower: the pill says just "Voice" / "Text only" under its icon. */
@media (max-width: 389px) {
  .mode-pill {
    width: 64px;
    border-radius: 20px;
  }
  .mode-label {
    display: none;
  }
  .mode-label.mode-label-short {
    display: block;
  }
}

@media (max-width: 360px) {
  .voice-name,
  .mode-label {
    font-size: 11px;
  }
  .mode-pill {
    width: 60px;
  }
  .chip-label {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .chip-value {
    font-size: 16px;
  }
}

/* 320-350 px: the smallest chip (no caret: "Their language" above it already says what it
   is) and a 58 px pill ("Text only" at 11 px) still show "Auto-detect" in full. */
@media (max-width: 350px) {
  .topbar {
    padding-left: calc(var(--sal) + 5px);
    padding-right: calc(var(--sar) + 5px);
  }
  .mode-pill {
    width: 58px;
  }
  .chip {
    padding: 5px 3px 5px 6px;
  }
  .chip-label {
    font-size: 12px;
  }
  .chip-value {
    font-size: 15px;
  }
  .chip .chip-caret {
    display: none;
  }
}

/* ---------- conversation ---------- */

.convo {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 6px calc(var(--sar) + 12px) 10px calc(var(--sal) + 12px);
}

.empty {
  margin: auto 0;
  padding: 16px 8px;
  text-align: center;
  color: var(--muted);
}

.empty-title {
  margin: 0 0 8px;
  font-size: 24px;
  font-weight: 800;
  color: var(--text);
}

.empty-text {
  margin: 0 auto;
  max-width: 24em;
  font-size: 18px;
}

.cards {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.card {
  position: relative;
  padding: 12px 16px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  border-left: 6px solid var(--them);
  background: var(--surface);
}

.card.her {
  border-left-color: var(--her);
  background: #1b1914;
}

.card.hint,
.card.pending {
  border-left-color: var(--faint);
}

.card.speaking {
  box-shadow: 0 0 0 2px var(--her);
}

/* Their English being read aloud to her: the same ring, in their colour. */
.card.them.speaking {
  box-shadow: 0 0 0 2px var(--them);
}

.card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0 0 6px;
  font-size: 14px;
  font-weight: 700;
  color: var(--muted);
}

.tag {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.01em;
}

.tag-dir {
  color: var(--text);
}

.tag-ai {
  background: var(--her);
  color: #1a1400;
}

.tag-speaking {
  color: var(--her);
  background: transparent;
  padding-left: 2px;
}

.card.them .tag-speaking {
  color: var(--them);
}

.trans {
  margin: 0;
  font-size: 34px;
  font-weight: 750;
  line-height: 1.18;
  overflow-wrap: anywhere;
  word-break: normal;
  hyphens: auto;
}

.trans[data-size="xl"] {
  font-size: 40px;
}

.trans[data-size="l"] {
  font-size: 34px;
}

.trans[data-size="m"] {
  font-size: 31px;
}

.trans[data-size="s"] {
  font-size: 28px;
}

.trans.placeholder {
  color: var(--faint);
  font-weight: 600;
}

.orig {
  margin: 8px 0 0;
  font-size: 17px;
  line-height: 1.35;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.card-hint {
  margin: 10px 0 0;
  padding: 0;
  border: 0;
  background: none;
  font-size: 17px;
  font-weight: 700;
  color: var(--accent-text);
  text-align: left;
  min-height: 44px;
}

.card-note {
  margin: 8px 0 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--warn);
}

/* "Not read aloud": information, not a warning (she spoke first; Replay reads it). */
.card-note-quiet {
  font-size: 14px;
  color: var(--faint);
}

.card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
}

.card-btn {
  min-height: 48px;
  padding: 0 18px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  font-size: 18px;
  font-weight: 750;
}

.card-btn-primary {
  background: var(--her);
  border-color: var(--her);
  color: #1a1400;
}

.partial {
  margin: 12px 4px 2px;
  font-size: 22px;
  line-height: 1.3;
  color: var(--faint);
  overflow-wrap: anywhere;
}

.partial-label {
  margin-right: 4px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* "New ↓": new translations arrived while she scrolled up to re-read. It lives in the
   fixed footer (not in the scrolling conversation), floating just above it. */
.jump-new {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%);
  min-height: 48px;
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 18px;
  font-weight: 700;
  white-space: nowrap;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}

/* ---------- bottom controls & the big button ---------- */

.controls {
  position: relative; /* anchors the "New" pill just above it */
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 6px calc(var(--sar) + 16px) calc(var(--sab) + 18px) calc(var(--sal) + 16px);
}

.status {
  min-height: 1.4em;
  max-width: 26em;
  margin: 0;
  font-size: 17px;
  font-weight: 650;
  color: var(--muted);
  text-align: center;
}

.status[data-tone="error"] {
  color: var(--danger);
}

.status[data-tone="warn"] {
  color: var(--warn);
}

/* Their English is being read to her: the phone is not listening meanwhile. */
.status[data-tone="them"] {
  color: var(--them);
}

/* "✉ Email transcript" + "New conversation" (only while not listening): a quiet row between
   the status line and the "Read their side to me" switch, so the big button keeps the eye.
   The buttons take their natural width when it fits (375 px and up: one line each) and
   shrink with their label on two lines on narrower phones; tap targets stay ≥ 44 px. */
.convo-actions {
  flex: none;
  display: flex;
  justify-content: center;
  gap: 8px;
  width: 100%;
  max-width: 460px;
}

.convo-btn {
  flex: 0 1 auto;
  min-width: 0;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--text);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.15;
  text-align: center;
}

.convo-btn-ico {
  flex: none;
  font-size: 18px;
  line-height: 1;
  color: var(--accent-text);
}

/* Email held long enough to change the address: it lights up, and letting go opens the
   sheet (on the release, so the keyboard comes up with the address selected). */
.convo-btn.is-held {
  border-color: var(--accent-text);
  background: var(--accent);
  color: #fff;
}

.convo-btn.is-held .convo-btn-ico {
  color: inherit;
}

@media (max-width: 360px) {
  .convo-btn {
    gap: 4px;
    padding: 5px 8px;
    font-size: 14px;
  }
  .convo-btn-ico {
    font-size: 16px;
  }
}

/* "Read their side to me": an iOS-style switch (track + knob) with its label beside it,
   just above the big button. The whole row is one button (the tap target, ≥ 44 px tall).
   On = teal (their side, like their cards); off = a grey track with an outline (so it is
   still visible on the dark background). Text only: greyed out, its state kept. */
.read-switch {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  max-width: 100%;
  margin: 0;
  padding: 4px 8px 4px 16px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  font-size: 17px;
  font-weight: 700;
  line-height: 1.2;
  text-align: left;
}

.read-switch-label {
  min-width: 0;
}

.read-switch[aria-checked="false"] .read-switch-label {
  color: var(--muted);
}

.read-switch-track {
  flex: none;
  position: relative;
  width: 51px;
  height: 31px;
  border-radius: 999px;
  background: #39404a;
  box-shadow: inset 0 0 0 1.5px var(--faint);
  transition: background-color 0.2s, box-shadow 0.2s;
}

.read-switch-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.35);
  transition: transform 0.2s;
}

.read-switch[aria-checked="true"] .read-switch-track {
  background: var(--them);
  box-shadow: none;
}

.read-switch[aria-checked="true"] .read-switch-knob {
  transform: translateX(20px);
}

/* Text only: nothing is read either way; the knob still shows the kept choice. */
.read-switch:disabled[aria-checked="true"] .read-switch-track {
  background: var(--faint);
}

@media (max-width: 340px) {
  .read-switch {
    gap: 10px;
    padding: 4px 6px 4px 12px;
    font-size: 16px;
  }
}

.big {
  position: relative;
  width: var(--big);
  height: var(--big);
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 12px;
  border-radius: 50%;
  border: 3px solid transparent;
  background: var(--accent);
  color: #fff;
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.5);
  transition: background-color 0.2s, transform 0.1s;
}

.big:active {
  transform: scale(0.97);
}

.big-ring {
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 4px solid var(--live);
  opacity: 0;
  pointer-events: none;
}

.big-ico {
  flex: none;
}

.big-ico-stop {
  display: none;
}

.big-label {
  max-width: 88%;
  font-size: clamp(18px, 5vw, 21px);
  font-weight: 800;
  line-height: 1.12;
  text-align: center;
}

.big-timer {
  font-size: 19px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.big-timer:empty {
  display: none;
}

.big[data-state="connecting"] {
  background: #33404f;
}

.big[data-state="live"],
.big[data-state="speaking"] {
  background: var(--live);
}

.big[data-state="live"] .big-ring {
  animation: ring 1.7s ease-out infinite;
}

.big[data-state="speaking"] .big-ring {
  border-color: var(--her);
  animation: ring 1.1s ease-out infinite;
}

.big[data-state="reconnecting"] {
  background: #5b4210;
  border-color: var(--warn);
}

.big[data-state="error"] {
  background: var(--surface-2);
  border-color: var(--danger);
}

.big[data-state="live"] .big-ico-mic,
.big[data-state="speaking"] .big-ico-mic,
.big[data-state="reconnecting"] .big-ico-mic {
  display: none;
}

.big[data-state="live"] .big-ico-stop,
.big[data-state="speaking"] .big-ico-stop,
.big[data-state="reconnecting"] .big-ico-stop {
  display: block;
}

.big[data-state="connecting"] .big-ico-mic {
  animation: breathe 1.2s ease-in-out infinite;
}

@keyframes ring {
  from {
    transform: scale(1);
    opacity: 0.75;
  }
  to {
    transform: scale(1.3);
    opacity: 0;
  }
}

@keyframes breathe {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

/* ---------- toast ---------- */

.toast {
  /* In the flow of the main screen: showing it shrinks the conversation (flex: 1)
     instead of covering the translation she is reading. */
  position: relative;
  z-index: 1;
  flex: none;
  align-self: center;
  width: calc(100% - 24px - var(--sal) - var(--sar));
  max-width: 520px;
  margin: 0 calc(var(--sar) + 12px) 6px calc(var(--sal) + 12px);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 10px 10px 16px;
  border-radius: 16px;
  background: #e9edf2;
  color: #0b0d10;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  font-size: 17px;
  font-weight: 650;
  animation: drop 0.18s ease-out;
}

.toast-text {
  flex: 1 1 auto;
  min-width: 0;
  padding: 4px 0;
}

.toast-action {
  flex: none;
  min-height: 44px;
  min-width: 72px;
  padding: 0 14px;
  border-radius: 12px;
  border: 0;
  background: #0b0d10;
  color: #fff;
  font-size: 17px;
  font-weight: 800;
}

@keyframes drop {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ---------- language picker (bottom sheet) ---------- */

/* padding-top: a sheet never reaches under the status bar (viewport-fit=cover with a
   black-translucent bar). With the keyboard up, a lifted sheet capped at 100% of the room
   left would otherwise grow to y=0 and put its title and Close under the clock. */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-top: calc(var(--sat) + 8px);
  background: rgba(0, 0, 0, 0.62);
}

.sheet {
  width: 100%;
  max-width: 560px;
  height: min(88vh, 760px);
  height: min(88dvh, 760px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px calc(var(--sar) + 16px) calc(var(--sab) + 10px) calc(var(--sal) + 16px);
  border-radius: 22px 22px 0 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-bottom: 0;
  animation: slideup 0.2s ease-out;
}

@keyframes slideup {
  from {
    transform: translateY(24px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* "Send transcripts to": a short sheet (its height is its content). app.js lifts it above
   the iOS keyboard (padding on the backdrop, from visualViewport). 100% = the room left
   above the keyboard (the fixed backdrop's padded content box): with the phone sideways
   the sheet is taller than that room, and without this cap it ran off the top of the
   screen (title and field cut, out of scroll reach); capped, it scrolls inside. */
.sheet-compact {
  height: auto;
  max-height: min(88vh, 560px);
  max-height: min(88dvh, 560px);
  max-height: min(88dvh, 560px, 100%);
  overflow-y: auto;
  gap: 12px;
  padding-top: 18px;
}

.email-note {
  margin: 0;
  font-size: 15px;
  line-height: 1.35;
  color: var(--muted);
}

.email-error {
  margin: 0;
  font-size: 16px;
  font-weight: 650;
  color: var(--danger);
}

.email-error:empty {
  display: none;
}

.sheet-actions {
  display: flex;
  gap: 10px;
}

.sheet-actions .btn {
  flex: 1 1 0;
  min-width: 0;
}

/* "Send transcripts to": "Save & open Mail" (the first Email tap) is far longer than
   "Cancel". Each button gets its label's width plus an equal share of the rest, so the label
   stays on one line from 375 px; at 320 px it wraps into two even lines. */
.sheet-compact .sheet-actions .btn {
  flex: 1 1 auto;
  padding: 0 14px;
  text-wrap: balance;
}

.sheet-title {
  margin: 0;
  font-size: 24px;
  font-weight: 800;
}

.search {
  width: 100%;
  min-height: 52px;
  padding: 0 16px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  font-size: 18px; /* ≥16px so iOS does not zoom */
  -webkit-appearance: none;
  appearance: none;
}

.search:focus {
  outline: 2px solid var(--accent);
  outline-offset: 0;
}

.lang-list {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.lang-item {
  width: 100%;
  min-height: 58px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  text-align: left;
}

.lang-name {
  flex: none; /* never squeezed: the grey native/description text shrinks instead */
  max-width: 70%;
  font-size: 20px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lang-native {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 17px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lang-check {
  flex: none;
  width: 24px;
  color: var(--accent-text);
  font-size: 22px;
  font-weight: 900;
  text-align: center;
}

.lang-item[aria-current="true"] .lang-name {
  color: var(--accent-text);
}

.lang-item.auto .lang-name {
  color: var(--accent-text);
}

.lang-heading {
  padding: 14px 10px 4px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.picker-empty {
  margin: 16px 0;
  color: var(--muted);
  font-size: 18px;
  text-align: center;
}

/* ---------- currency converter (bottom sheet) ---------- */

/* A compact sheet: taller than the email one (the five quick amounts fit without scrolling
   on a phone held upright); above the iOS keyboard (converter.js lifts it) it scrolls. */
.fx-sheet {
  max-height: min(92vh, 680px);
  max-height: min(92dvh, 680px);
  max-height: min(92dvh, 680px, 100%);
  gap: 10px;
  padding-top: 12px;
}

.fx-amount {
  width: 100%;
  min-height: 64px;
  padding: 0 16px;
  border-radius: 16px;
  border: 2px solid var(--line);
  background: var(--surface-2);
  font-size: 34px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  -webkit-appearance: none;
  appearance: none;
}

.fx-amount:focus {
  border-color: var(--accent);
  outline: none;
}

.fx-amount::placeholder {
  color: var(--faint);
}

.fx-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 8px;
}

.fx-cur {
  min-width: 0;
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 1px;
  padding: 5px 12px;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  text-align: left;
}

.fx-cur-code {
  display: flex;
  align-items: center;
  gap: 3px;
  font-size: 22px;
  font-weight: 800;
  line-height: 1.1;
}

.fx-cur-name {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}

.fx-swap {
  width: 48px;
  height: auto;
  min-height: 56px;
}

.fx-result {
  margin: 0;
  font-size: 40px;
  font-weight: 800;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.fx-result[data-size="m"] {
  font-size: 32px;
}

.fx-result[data-size="s"] {
  font-size: 26px;
}

/* The amount as it was read, grouped ("₫1,250,000"), above the result: small and muted. Its
   line is kept when empty, so the result does not jump. */
.fx-echo {
  display: block;
  min-height: 20px;
  font-size: 15px;
  font-weight: 650;
  line-height: 20px;
  color: var(--muted);
}

.fx-approx {
  margin-right: 6px;
  font-size: 0.7em;
  font-weight: 700;
  color: var(--muted);
}

.fx-quick {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line);
}

.fx-quick-btn {
  width: 100%;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 4px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  font-size: 17px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  text-align: left;
}

.fx-quick-from {
  color: var(--muted);
}

.fx-quick-to {
  font-weight: 800;
  text-align: right;
}

.fx-note {
  margin: -4px 0 0;
  font-size: 15px;
  color: var(--muted);
}

.fx-note[data-tone="warn"] {
  color: var(--warn);
}

/* The rates provider's required credit ("Rates By Exchange Rate API"), right under the date
   line and the result, so it is on screen with the converted amount even when the sheet has
   to scroll: small, but a real link (it opens in Safari; the app stays as it is). */
.fx-credit {
  margin: -10px 0 0;
  font-size: 13px;
}

.fx-credit a {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  color: var(--accent-text);
}

/* The currency picker opens over the converter. */
.fx-picker {
  z-index: 31;
}

.fx-item-code {
  min-width: 3.2em;
}

/* ---------- photo results (full screen) ---------- */

.fullsheet {
  position: fixed;
  inset: 0;
  z-index: 35;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  animation: slideup 0.2s ease-out;
}

.fullsheet-head {
  flex: none;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
  padding: calc(var(--sat) + 14px) calc(var(--sar) + 16px) 10px calc(var(--sal) + 16px);
  border-bottom: 1px solid var(--line);
}

.photo-langs {
  font-size: 17px;
  font-weight: 700;
  color: var(--muted);
}

.fullsheet-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 8px calc(var(--sar) + 16px) 16px calc(var(--sal) + 16px);
}

.photo-status {
  margin: 10px 0;
  font-size: 19px;
  font-weight: 650;
  color: var(--muted);
}

.photo-status[data-tone="error"] {
  color: var(--danger);
}

.photo-status[data-busy]::after {
  content: '';
  display: inline-block;
  width: 18px;
  height: 18px;
  margin-left: 10px;
  vertical-align: -3px;
  border: 3px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: photo-spin 0.9s linear infinite;
}

@keyframes photo-spin {
  to {
    transform: rotate(360deg);
  }
}

.photo-blocks {
  margin: 0;
  padding: 0;
  list-style: none;
}

.photo-block {
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}

.photo-trans {
  margin: 0;
  font-size: 26px;
  font-weight: 750;
  line-height: 1.22;
  overflow-wrap: anywhere;
}

.photo-orig {
  margin: 6px 0 0;
  font-size: 16px;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.fullsheet-foot {
  flex: none;
  display: flex;
  gap: 12px;
  padding: 10px calc(var(--sar) + 16px) calc(var(--sab) + 14px) calc(var(--sal) + 16px);
  border-top: 1px solid var(--line);
}

.fullsheet-foot .btn {
  flex: 1 1 0;
  min-height: 58px;
  font-size: 20px;
}

/* ---------- "Show them" ---------- */

.showthem {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: #000;
  color: #fff;
  padding: calc(var(--sat) + 12px) calc(var(--sar) + 14px) calc(var(--sab) + 12px) calc(var(--sal) + 14px);
}

.showthem-inner {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0; /* shrinks to leave room for the footer, so fitShowThem() measures that */
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: transform 0.25s ease;
}

.showthem.rotated .showthem-inner {
  transform: rotate(180deg);
}

.showthem-tag {
  flex: none;
  margin: 0;
  font-size: 18px;
  font-weight: 800;
  color: var(--her);
  text-align: center;
}

.showthem-box {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  overflow-y: auto; /* only scrolls if even the minimum size does not fit */
  overscroll-behavior: contain;
  scrollbar-width: none;
}

.showthem-box::-webkit-scrollbar {
  display: none;
}

.showthem-text {
  margin: auto 0; /* safe vertical centering (no clipping when it overflows) */
  width: 100%;
  font-size: 56px;
  font-weight: 800;
  line-height: 1.15;
  text-align: center;
  overflow-wrap: normal; /* app.js sizes the text so whole words fit */
}

.showthem-text.breakable {
  overflow-wrap: anywhere;
}

.showthem-hint {
  flex: none;
  margin: 0;
  font-size: 15px;
  color: var(--faint);
  text-align: center;
}

.showthem-foot {
  flex: none;
  display: flex;
  justify-content: center;
}

.showthem-rotate {
  min-height: 56px;
  padding: 0 22px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: #1b1f25;
  color: #fff;
}

.showthem-rotate[aria-pressed="true"] {
  color: var(--her);
  border-color: var(--her);
}

/* ---------- tap to resume ---------- */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: calc(var(--sat) + 24px) calc(var(--sar) + 20px) calc(var(--sab) + 24px) calc(var(--sal) + 20px);
  background: rgba(11, 13, 16, 0.95);
  text-align: center;
}

.overlay-text {
  margin: 0;
  max-width: 22em;
  font-size: 19px;
  color: var(--muted);
}

.big-resume {
  --big: clamp(170px, 55vw, 240px);
}

/* ---------- small / short / large screens ---------- */

@media (max-height: 640px) {
  :root {
    --big: clamp(136px, 43vw, 180px);
  }
  .empty-title {
    font-size: 21px;
  }
  .empty-text {
    font-size: 16px;
  }
}

@media (max-width: 340px) {
  /* 320 px phones: the circle is ~137 px; keep icon + label + timer inside it */
  .big-ico {
    width: 32px;
    height: 32px;
  }
  .big-label {
    font-size: 16px;
  }
}

@media (max-height: 480px) {
  /* phone in landscape: keep the conversation readable */
  :root {
    --big: 112px;
  }
  /* "Read their side to me" sits beside the big button (on its left, next to it) instead
     of above it: stacked, it would take ~50 px from a conversation that is already short.
     The button stays centred when there is room (on a 667 px wide phone it moves ~10 px
     right rather than wrap the label); the status line keeps its own row above both. */
  .controls {
    display: grid;
    grid-template-columns: minmax(max-content, 1fr) auto minmax(0, 1fr);
    grid-template-areas:
      "status status status"
      "switch big actions";
    align-items: center;
    justify-items: center;
    column-gap: 16px;
    row-gap: 6px;
  }
  .status {
    grid-area: status;
  }
  .read-switch {
    grid-area: switch;
    justify-self: end;
  }
  .read-switch-label {
    white-space: nowrap;
  }
  .big {
    grid-area: big;
  }
  /* Email / New conversation: stacked on the RIGHT of the big button (the column that was
     empty), so they take nothing from the conversation's height. */
  .convo-actions {
    grid-area: actions;
    justify-self: start;
    flex-direction: column;
    align-items: stretch;
    width: auto;
    max-width: 240px;
    gap: 6px;
  }
  .big-ico {
    width: 30px;
    height: 30px;
  }
  .big-label {
    font-size: 15px;
  }
  .big-timer {
    font-size: 15px;
  }
  .empty-text {
    display: none;
  }
  /* The currency converter sideways: the keyboard leaves ~150 px above it, so the amount
     and the result share the row under the title (amount left, result right); the pair,
     the date, the credit and the quick amounts follow below. */
  .fx-sheet {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-content: start;
    column-gap: 16px;
  }
  .fx-sheet > * {
    grid-column: 1 / -1;
  }
  .fx-sheet > .fx-amount,
  .fx-sheet > .fx-result {
    grid-row: 2;
  }
  .fx-sheet > .fx-amount {
    grid-column: 1;
  }
  .fx-sheet > .fx-result {
    grid-column: 2;
    align-self: center;
    font-size: 32px;
  }
  .fx-result[data-size="m"] {
    font-size: 26px;
  }
  .fx-result[data-size="s"] {
    font-size: 22px;
  }
}

@media (min-width: 768px) {
  .trans[data-size="xl"] {
    font-size: 44px;
  }
  .showthem-text {
    font-size: 72px;
  }
}

@media (hover: hover) {
  .btn:hover,
  .icon-btn:hover,
  .card-btn:hover,
  .chip:hover,
  .lang-item:hover {
    filter: brightness(1.15);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .big[data-state="live"] .big-ring,
  .big[data-state="speaking"] .big-ring {
    opacity: 1;
    transform: scale(1.06);
  }
  .photo-status[data-busy]::after {
    animation: none;
    border-right-color: currentColor;
    opacity: 0.5;
  }
}
