/* ============================================================
 * style_recorder.css — Recorder UI
 * ============================================================
 *
 * Built on platform features that reached Baseline by 2026 — Popover API, CSS
 * anchor positioning, @property, @starting-style, container queries, oklch() —
 * so there is no positioning library, no utility framework and no build step.
 * Each one is wrapped in @supports or degrades on its own, so an older engine
 * gets a plainer but fully working UI rather than a broken one.
 *
 * COLOUR: RECORDING RED IS ITS OWN COLOUR
 * --------------------------------------
 * The control cluster already uses red twice — muted mic (.is-off) and end-call
 * (.hex-end-call). A third red that looked like either of those would be actively
 * dangerous: "you are being recorded" must never be mistaken for "your mic is
 * off". Recording therefore gets a distinct, hotter, more saturated red, defined
 * once here in oklch so the hue stays perceptually stable.
 *
 * And colour is never the only signal — the glyph and the text label change too
 * (WCAG 1.4.1). See _paint_record_button() in recorder_ui.js.
 * ============================================================ */

:root {
  /* Perceptually uniform, so it stays vivid against the dark glass without
     drifting toward the muted/end-call reds. */
  --rec-red:        oklch(63% 0.24 25);
  --rec-red-dim:    oklch(63% 0.24 25 / 0.16);
  --rec-red-glow:   oklch(70% 0.26 25 / 0.55);
  --rec-green:      oklch(72% 0.17 155);
  --rec-amber:      oklch(78% 0.16 85);

  --rec-surface:    oklch(18% 0.015 260 / 0.92);
  --rec-surface-2:  oklch(24% 0.02 260 / 0.7);
  --rec-border:     oklch(100% 0 0 / 0.12);
  --rec-text:       oklch(96% 0 0);
  --rec-text-dim:   oklch(96% 0 0 / 0.62);

  --rec-radius:     14px;
  --rec-ease:       cubic-bezier(0.4, 0, 0.2, 1);
}

/* Animatable custom property — lets the pulse ring animate a real value rather
   than swapping keyframed box-shadows. Registered so it interpolates. */
@property --rec-pulse {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

/* ── The Record button in the hex cluster ─────────────────────────────────── */

#hex-record .hex-svg { color: var(--rec-text); transition: color 0.2s var(--rec-ease); }

#hex-record.is-recording {
  background: var(--rec-red-dim);
  border-color: color-mix(in oklch, var(--rec-red) 55%, transparent);
}
#hex-record.is-recording .hex-svg   { color: var(--rec-red); }
#hex-record.is-recording .hex-label { color: var(--rec-red); }

/* The pulse. Guarded by prefers-reduced-motion below. */
#hex-record.is-recording::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: 0 0 0 var(--rec-pulse) var(--rec-red-glow);
  animation: rec-pulse 1.8s var(--rec-ease) infinite;
}

@keyframes rec-pulse {
  0%   { --rec-pulse: 0px;  opacity: 0.85; }
  70%  { --rec-pulse: 10px; opacity: 0; }
  100% { --rec-pulse: 0px;  opacity: 0; }
}

/* Focus ring. The hex buttons set outline:none and had NO focus indicator at
   all, which makes the whole cluster unusable by keyboard. :focus-visible shows
   it for keyboard users without putting a ring on every mouse click. */
.hex-btn:focus-visible,
#hex-record:focus-visible {
  outline: 2px solid oklch(80% 0.15 230);
  outline-offset: 3px;
  border-radius: var(--btn-radius, 11px);
}

/* The hex buttons shrink to 28px on phones — below the 44px minimum touch
   target. An invisible pseudo-element restores a thumb-sized hit area without
   changing the visual size. */
@media (pointer: coarse) {
  .hex-btn::before {
    content: '';
    position: absolute;
    inset: 50% auto auto 50%;
    translate: -50% -50%;
    width: max(44px, 100%);
    height: max(44px, 100%);
  }
}

/* Adding a 9th button can overflow the column on a short screen (portrait) or
   the row on a phone in landscape, where there was no flex-wrap at all. */
.hex-cluster {
  flex-wrap: wrap;
  max-height: 100dvh;
  overflow-y: auto;
  scrollbar-width: none;
}
.hex-cluster::-webkit-scrollbar { display: none; }

/* ── Persistent "recording in progress" banner ────────────────────────────── */

#rec-banner {
  position: fixed;
  top: max(8px, env(safe-area-inset-top));
  left: 50%;
  translate: -50% 0;
  z-index: 980;                       /* above video, below the hex menu (950)… */
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: min(560px, calc(100vw - 24px));
}
#rec-banner[hidden] { display: none; }

.rec-banner-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 999px;
  background: var(--rec-surface);
  border: 1px solid color-mix(in oklch, var(--rec-red) 35%, transparent);
  backdrop-filter: blur(20px) saturate(1.3);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
  box-shadow: 0 6px 24px oklch(0% 0 0 / 0.45);
  color: var(--rec-text);
  font-size: 13px;
  line-height: 1.3;
}

.rec-banner-dot {
  flex: 0 0 auto;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--rec-red);
  box-shadow: 0 0 0 0 var(--rec-red-glow);
  animation: rec-dot 1.6s ease-out infinite;
}
@keyframes rec-dot {
  0%   { box-shadow: 0 0 0 0 var(--rec-red-glow); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

.rec-banner-text  { flex: 1 1 auto; min-width: 0; }
.rec-banner-text strong { font-weight: 650; }

.rec-banner-action {
  flex: 0 0 auto;
  border: 1px solid var(--rec-border);
  background: var(--rec-surface-2);
  color: var(--rec-text);
  font: inherit;
  font-weight: 600;
  padding: 5px 12px;
  min-height: 32px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.18s var(--rec-ease), border-color 0.18s var(--rec-ease);
}
.rec-banner-action:hover {
  background: color-mix(in oklch, var(--rec-red) 30%, transparent);
  border-color: var(--rec-red);
}
.rec-banner-action:focus-visible {
  outline: 2px solid oklch(80% 0.15 230);
  outline-offset: 2px;
}

/* ── The panel ────────────────────────────────────────────────────────────── */

#rec-panel {
  position: fixed;
  z-index: 960;
  width: min(380px, calc(100vw - 24px));
  max-height: min(70dvh, 560px);
  overflow-y: auto;
  padding: 14px;
  border-radius: var(--rec-radius);
  background: var(--rec-surface);
  border: 1px solid var(--rec-border);
  backdrop-filter: blur(24px) saturate(1.4);
  -webkit-backdrop-filter: blur(24px) saturate(1.4);
  box-shadow: 0 16px 48px oklch(0% 0 0 / 0.55);
  color: var(--rec-text);
  container-type: inline-size;        /* children respond to the PANEL, not the viewport */

  /* Fallback placement for engines without anchor positioning. */
  top: 50%;
  right: 84px;
  translate: 0 -50%;
}
#rec-panel[hidden] { display: none; }

/* The panel used to anchor to the Record button via CSS anchor positioning (position-anchor:
   --rec-anchor on #hex-record). The flower redesign RETIRED #hex-record — the record control is
   now the settings flower, which lives at the BOTTOM edge of the screen — so anchoring left the
   panel (and its close button) rendered below the fold and unreachable. The reliable base position
   above (fixed, vertically centred on the right) is used in all cases now: always on-screen, no
   dependency on an anchor element that may move or not exist. */

/* Entry animation. @starting-style is what makes a display:none -> block
   transition actually animate; allow-discrete lets `display` participate. */
#rec-panel {
  opacity: 1;
  scale: 1;
  transition: opacity 0.2s var(--rec-ease),
              scale 0.2s var(--rec-ease),
              display 0.2s allow-discrete;
}
@starting-style {
  #rec-panel.is-open { opacity: 0; scale: 0.96; }
}

.rec-panel-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.rec-panel-title { font-weight: 650; font-size: 15px; flex: 1 1 auto; }
.rec-panel-timer {
  font-variant-numeric: tabular-nums;
  color: var(--rec-red);
  font-weight: 650;
}
.rec-panel-dest {
  background: none; border: none; cursor: pointer;
  color: var(--rec-text-dim); font-size: 16px;
  min-width: 32px; min-height: 32px; border-radius: 8px;
}
.rec-panel-dest:hover { color: var(--rec-text); background: var(--rec-surface-2); }

.rec-rec-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--rec-red);
  animation: rec-dot 1.6s ease-out infinite;
}

/* ── Live consent grid ────────────────────────────────────────────────────── */

.rec-peer-list { list-style: none; margin: 0 0 12px; padding: 0; }

.rec-peer {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  border-radius: 10px;
  background: var(--rec-surface-2);
  margin-bottom: 5px;
  font-size: 13px;
}
.rec-peer-self { border: 1px dashed var(--rec-border); }
.rec-peer-name  { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.rec-peer-state {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 3px 8px;
  border-radius: 999px;
}
/* Each state carries a word, not just a colour. */
.rec-peer-state.in   { color: var(--rec-red);   background: var(--rec-red-dim); }
.rec-peer-state.wait { color: var(--rec-amber); background: color-mix(in oklch, var(--rec-amber) 16%, transparent); }
.rec-peer-state.out  { color: var(--rec-text-dim); background: oklch(100% 0 0 / 0.06); }

.rec-panel-note {
  font-size: 11.5px;
  color: var(--rec-text-dim);
  line-height: 1.45;
  margin: 0 0 12px;
}

/* ── Library ──────────────────────────────────────────────────────────────── */

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

.rec-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 10px;
  align-items: start;
  padding: 10px;
  border-radius: 12px;
  background: var(--rec-surface-2);
  margin-bottom: 8px;
}

/* Container query: when the panel itself is narrow, stack instead of columns.
   Responds to the PANEL's width, not the viewport's — which is the whole point. */
@container (max-width: 320px) {
  .rec-item { grid-template-columns: auto 1fr; }
  .rec-item-actions { grid-column: 1 / -1; justify-content: flex-end; }
}

.rec-item-icon {
  font-size: 20px;
  line-height: 1;
  background: none;
  border: 1px solid transparent;
  border-radius: 10px;
  cursor: pointer;
  padding: 6px;
  min-width: 40px; min-height: 40px;
  transition: background 0.15s var(--rec-ease);
}
.rec-item-icon:hover { background: oklch(100% 0 0 / 0.08); border-color: var(--rec-border); }

.rec-item-main { min-width: 0; }

.rec-item-name {
  width: 100%;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 7px;
  color: var(--rec-text);
  font: inherit;
  font-weight: 600;
  font-size: 13.5px;
  padding: 4px 6px;
  text-overflow: ellipsis;
}
.rec-item-name:hover { border-color: var(--rec-border); }
.rec-item-name:focus {
  outline: none;
  border-color: oklch(80% 0.15 230);
  background: oklch(0% 0 0 / 0.3);
}

.rec-item-meta {
  font-size: 11px;
  color: var(--rec-text-dim);
  padding: 2px 6px 6px;
  font-variant-numeric: tabular-nums;
}
.rec-item-excluded {
  color: var(--rec-amber);
  cursor: help;
  border-bottom: 1px dotted currentColor;
}

.rec-item-audio { width: 100%; height: 32px; }

.rec-item-actions { display: flex; gap: 4px; }
.rec-item-actions button {
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--rec-text-dim);
  cursor: pointer;
  font-size: 13px;
  min-width: 32px; min-height: 32px;
  transition: color 0.15s var(--rec-ease), background 0.15s var(--rec-ease);
}
.rec-item-actions button:hover {
  color: var(--rec-text);
  background: oklch(100% 0 0 / 0.08);
  border-color: var(--rec-border);
}
.rec-item-actions button:focus-visible {
  outline: 2px solid oklch(80% 0.15 230);
  outline-offset: 1px;
}

.rec-empty {
  text-align: center;
  color: var(--rec-text-dim);
  font-size: 13px;
  padding: 28px 12px;
  line-height: 1.6;
}
.rec-empty-sub { font-size: 11.5px; opacity: 0.75; }

/* ── Consent dialog ───────────────────────────────────────────────────────── */

.rec-consent-dialog {
  border: none;
  padding: 0;
  border-radius: 18px;
  background: transparent;
  color: var(--rec-text);

  /* A <dialog> in the top layer is centred by the UA's `margin: auto`. But
     style_common.css:1 has `* { margin: 0 }`, which wins over the UA sheet and
     pins the dialog to the top-left corner. Restore centring explicitly.
     inset:0 + margin:auto is the reliable way to do this for a top-layer box. */
  inset: 0;
  margin: auto;
  width: min(440px, calc(100vw - 32px));
  max-width: min(440px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
}
.rec-consent-dialog::backdrop {
  background: oklch(0% 0 0 / 0.66);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.rec-consent-body {
  padding: 24px;
  border-radius: 18px;
  background: var(--rec-surface);
  border: 1px solid var(--rec-border);
  box-shadow: 0 24px 64px oklch(0% 0 0 / 0.6);
}

.rec-consent-icon { display: flex; justify-content: center; margin-bottom: 14px; }
.rec-consent-dot {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--rec-red-dim);
  border: 2px solid var(--rec-red);
  position: relative;
}
.rec-consent-dot::after {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  translate: -50% -50%;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--rec-red);
  animation: rec-dot 1.6s ease-out infinite;
}

.rec-consent-title {
  font-size: 18px;
  font-weight: 650;
  text-align: center;
  margin: 0 0 12px;
  line-height: 1.3;
  text-wrap: balance;                 /* no orphaned last word */
}

.rec-consent-text {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--rec-text-dim);
  margin: 0 0 12px;
  text-wrap: pretty;
}
.rec-consent-text strong { color: var(--rec-text); font-weight: 620; }

/* The honest-limitation notice. Visually distinct so it reads as a caveat
   rather than marketing copy — it is the most important text in the dialog. */
.rec-consent-caveat {
  font-size: 12px;
  line-height: 1.5;
  color: var(--rec-text-dim);
  background: oklch(0% 0 0 / 0.32);
  border-left: 3px solid var(--rec-amber);
  border-radius: 0 8px 8px 0;
  padding: 10px 12px;
  margin: 0 0 18px;
}
.rec-consent-caveat code {
  font-size: 11px;
  background: oklch(100% 0 0 / 0.1);
  padding: 1px 4px;
  border-radius: 4px;
}

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

.rec-btn {
  flex: 1 1 0;
  font: inherit;
  font-weight: 600;
  font-size: 14px;
  padding: 11px 16px;
  min-height: 44px;
  border-radius: 11px;
  cursor: pointer;
  border: 1px solid var(--rec-border);
  transition: background 0.18s var(--rec-ease), border-color 0.18s var(--rec-ease);
}
.rec-btn:focus-visible { outline: 2px solid oklch(80% 0.15 230); outline-offset: 2px; }

/* Decline is NOT styled as the scary/secondary option. Declining is a
   first-class, legitimate choice and must not be visually discouraged — a
   consent flow that nudges toward "yes" is not really consent. */
.rec-btn-decline {
  background: var(--rec-surface-2);
  color: var(--rec-text);
}
.rec-btn-decline:hover { background: oklch(100% 0 0 / 0.12); }

.rec-btn-allow {
  background: color-mix(in oklch, var(--rec-red) 88%, black);
  border-color: var(--rec-red);
  color: oklch(99% 0 0);
}
.rec-btn-allow:hover { background: var(--rec-red); }

.rec-btn-stop {
  width: 100%;
  background: color-mix(in oklch, var(--rec-red) 88%, black);
  border-color: var(--rec-red);
  color: oklch(99% 0 0);
}
.rec-btn-stop:hover { background: var(--rec-red); }

.rec-consent-timeout {
  font-size: 11px;
  color: var(--rec-text-dim);
  text-align: center;
  margin: 12px 0 0;
}

.rec-dest-input {
  width: 100%;
  font: inherit;
  font-size: 13px;
  padding: 11px 12px;
  min-height: 44px;
  border-radius: 10px;
  border: 1px solid var(--rec-border);
  background: oklch(0% 0 0 / 0.35);
  color: var(--rec-text);
  margin-bottom: 12px;
}
.rec-dest-input:focus {
  outline: none;
  border-color: oklch(80% 0.15 230);
}

/* Screen-reader-only live region. */
.rec-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Motion & contrast preferences ────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  #hex-record.is-recording::after,
  .rec-banner-dot,
  .rec-rec-dot,
  .rec-consent-dot::after {
    animation: none;
  }
  /* The state is still unmistakable without motion: colour + glyph + label. */
  #hex-record.is-recording::after {
    box-shadow: 0 0 0 3px var(--rec-red-glow);
  }
  #rec-panel { transition: none; }
}

@media (prefers-contrast: more) {
  .rec-banner-row,
  .rec-consent-body,
  #rec-panel {
    background: oklch(12% 0 0 / 0.98);
    border-width: 2px;
  }
}

/* Landscape phones: keep the panel from swallowing the screen. */
@media (max-height: 480px) and (orientation: landscape) {
  #rec-panel { max-height: 88dvh; width: min(320px, calc(100vw - 100px)); }
  .rec-item-audio { height: 28px; }
}

/* ── PWA install affordance ───────────────────────────────────────────────────
   Offered on the join screen only — never over a live call, where an install
   prompt would be an interruption rather than an offer. */
.pwa-install-btn {
  position: fixed;
  bottom: max(16px, env(safe-area-inset-bottom));
  right: 16px;
  z-index: 900;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 10px 16px;
  min-height: 44px;
  border-radius: 999px;
  cursor: pointer;
  color: var(--rec-text);
  background: var(--rec-surface);
  border: 1px solid var(--rec-border);
  backdrop-filter: blur(20px) saturate(1.3);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
  box-shadow: 0 6px 24px oklch(0% 0 0 / 0.4);
  transition: background 0.18s var(--rec-ease), border-color 0.18s var(--rec-ease);
}
.pwa-install-btn:hover {
  background: var(--rec-surface-2);
  border-color: oklch(80% 0.15 230);
}
.pwa-install-btn:focus-visible {
  outline: 2px solid oklch(80% 0.15 230);
  outline-offset: 2px;
}
.pwa-install-btn[hidden] { display: none; }

/* Running as an installed app: no install button, and respect the safe areas of
   a notched device in standalone mode (there is no browser chrome to protect us). */
.pwa-standalone .pwa-install-btn { display: none; }

/* Panel close button.
   The panel originally had NO close control — once open it stayed open, covering the
   call, with no way to dismiss it. Closing the panel never stops a recording; the
   banner keeps the recording visible and Stop stays available there. */
.rec-panel-close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--rec-text-dim);
  font-size: 15px;
  line-height: 1;
  min-width: 32px;
  min-height: 32px;
  border-radius: 8px;
  margin-left: 2px;
  transition: color 0.15s var(--rec-ease), background 0.15s var(--rec-ease);
}
.rec-panel-close:hover {
  color: var(--rec-text);
  background: oklch(100% 0 0 / 0.1);
}
.rec-panel-close:focus-visible {
  outline: 2px solid oklch(80% 0.15 230);
  outline-offset: 2px;
}

/* iOS install instructions.
   Apple provides no programmatic install API, so on iPhone/iPad the only thing that
   works is showing the user where the button actually is. */
.pwa-steps {
  margin: 0 0 16px;
  padding-left: 20px;
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--rec-text-dim);
}
.pwa-steps li { margin-bottom: 8px; }
.pwa-steps strong { color: var(--rec-text); font-weight: 620; }
.pwa-step-sub { font-size: 11.5px; opacity: 0.7; }

/* ── Notification / ringtone settings ─────────────────────────────────────────
   Bell button in the top-right corner stack, alongside the other corner controls. */
.notif-settings-btn {
  position: fixed;
  /* Slots in as the 4th button of the top-right corner stack (the others sit at
     12 / 58 / 104px on a 46px pitch).
     z-index MUST beat the hex menu's 950: the floating cluster is vertically
     centred and its box begins right where this button ends, so at 940 the cluster
     swallowed the clicks and the bell was simply unclickable. Caught by the browser
     test, not by looking at it. */
  top: 150px;
  right: 12px;
  z-index: 960;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 11px;
  cursor: pointer;
  color: var(--rec-text);
  background: oklch(18% 0.015 260 / 0.85);
  border: 1px solid var(--rec-border);
  backdrop-filter: blur(20px) saturate(1.3);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
  transition: background 0.18s var(--rec-ease), border-color 0.18s var(--rec-ease);
}
.notif-settings-btn:hover {
  background: oklch(26% 0.02 260 / 0.9);
  border-color: oklch(80% 0.15 230 / 0.5);
}
.notif-settings-btn:focus-visible {
  outline: 2px solid oklch(80% 0.15 230);
  outline-offset: 3px;
}
/* 44px touch target without changing the visual size. */
@media (pointer: coarse) {
  .notif-settings-btn::before {
    content: '';
    position: absolute;
    inset: 50% auto auto 50%;
    translate: -50% -50%;
    width: 44px; height: 44px;
  }
}

.rt-dialog .rec-consent-body { max-height: 80dvh; overflow-y: auto; }

.rt-section-label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--rec-text-dim);
  margin: 14px 0 6px;
}

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

.rt-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 11px;
  background: var(--rec-surface-2);
  border: 1px solid transparent;
  margin-bottom: 6px;
}
.rt-item.is-selected {
  border-color: oklch(80% 0.15 230 / 0.6);
  background: oklch(80% 0.15 230 / 0.1);
}

.rt-play {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  min-width: 34px;
  border-radius: 50%;
  border: 1px solid var(--rec-border);
  background: oklch(0% 0 0 / 0.3);
  color: var(--rec-text);
  cursor: pointer;
  font-size: 11px;
  display: grid;
  place-items: center;
  transition: background 0.15s var(--rec-ease);
}
.rt-play:hover { background: oklch(80% 0.15 230 / 0.25); }
.rt-play:focus-visible { outline: 2px solid oklch(80% 0.15 230); outline-offset: 2px; }

.rt-meta { flex: 1 1 auto; min-width: 0; }
.rt-name { font-size: 13.5px; font-weight: 600; }
.rt-desc {
  font-size: 11px;
  color: var(--rec-text-dim);
  line-height: 1.35;
  margin-top: 1px;
}

.rt-choose {
  flex: 0 0 auto;
  font: inherit;
  font-size: 11.5px;
  font-weight: 650;
  padding: 6px 12px;
  min-height: 32px;
  border-radius: 999px;
  cursor: pointer;
  color: var(--rec-text);
  background: oklch(0% 0 0 / 0.35);
  border: 1px solid var(--rec-border);
  transition: background 0.15s var(--rec-ease);
}
.rt-choose:hover { background: oklch(80% 0.15 230 / 0.3); }
.rt-choose:focus-visible { outline: 2px solid oklch(80% 0.15 230); outline-offset: 2px; }
.rt-item.is-selected .rt-choose {
  background: oklch(80% 0.15 230 / 0.35);
  border-color: oklch(80% 0.15 230 / 0.7);
}

.rt-del {
  flex: 0 0 auto;
  background: none;
  border: none;
  color: var(--rec-text-dim);
  cursor: pointer;
  font-size: 13px;
  min-width: 32px; min-height: 32px;
  border-radius: 8px;
}
.rt-del:hover { color: var(--rec-red); background: var(--rec-red-dim); }

.rt-empty {
  font-size: 12px;
  color: var(--rec-text-dim);
  padding: 10px;
  text-align: center;
}

.rt-add-row { display: flex; gap: 8px; margin: 12px 0 6px; }

.rt-add-btn {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  padding: 11px 10px;
  min-height: 44px;
  border-radius: 11px;
  cursor: pointer;
  color: var(--rec-text);
  background: var(--rec-surface-2);
  border: 1px dashed var(--rec-border);
  transition: background 0.15s var(--rec-ease), border-color 0.15s var(--rec-ease);
}
.rt-add-btn:hover {
  background: oklch(100% 0 0 / 0.09);
  border-color: oklch(80% 0.15 230 / 0.6);
}
.rt-add-btn:focus-visible { outline: 2px solid oklch(80% 0.15 230); outline-offset: 2px; }
.rt-add-btn.is-recording {
  border-style: solid;
  border-color: var(--rec-red);
  background: var(--rec-red-dim);
  color: var(--rec-red);
}
.rt-add-ico { font-size: 15px; }

.rt-rec-status {
  font-size: 12px;
  color: var(--rec-text-dim);
  text-align: center;
  padding: 6px 0 2px;
  font-variant-numeric: tabular-nums;
}

/* Phones: the corner stack is smaller (30px buttons, ending at ~112px), so the bell
   moves up to match. The hex cluster starts far lower here (~271px), so there is
   plenty of room. */
@media (max-width: 768px) {
  .notif-settings-btn {
    top: 117px;
    width: 30px;
    height: 30px;
    border-radius: 9px;
  }
  .notif-settings-btn svg { width: 17px; height: 17px; }
}

/* ── Ringtone dialog: close button + review step ──────────────────────────────
   The dialog had no X, and recording auto-saved with no chance to hear it. Both fixed. */
.rec-consent-body { position: relative; }

.rt-close {
  position: absolute;
  top: 12px;
  right: 12px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--rec-text-dim);
  font-size: 15px;
  line-height: 1;
  width: 34px;
  height: 34px;
  min-width: 34px;
  border-radius: 9px;
  display: grid;
  place-items: center;
  transition: color 0.15s var(--rec-ease), background 0.15s var(--rec-ease);
}
.rt-close:hover { color: var(--rec-text); background: oklch(100% 0 0 / 0.1); }
.rt-close:focus-visible { outline: 2px solid oklch(80% 0.15 230); outline-offset: 2px; }

/* Review panel — hear it, name it, then decide. */
.rt-review {
  margin: 12px 0;
  padding: 12px;
  border-radius: 12px;
  background: oklch(80% 0.15 230 / 0.08);
  border: 1px solid oklch(80% 0.15 230 / 0.4);
}
.rt-review[hidden] { display: none; }

.rt-review-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}
.rt-review-title { font-size: 13px; font-weight: 650; flex: 1 1 auto; }
.rt-review-len {
  font-size: 11px;
  color: var(--rec-text-dim);
  font-variant-numeric: tabular-nums;
}

.rt-review-audio { width: 100%; height: 34px; margin-bottom: 8px; }

.rt-review-name {
  width: 100%;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 9px 10px;
  min-height: 40px;
  border-radius: 9px;
  border: 1px solid var(--rec-border);
  background: oklch(0% 0 0 / 0.35);
  color: var(--rec-text);
  margin-bottom: 8px;
}
.rt-review-name:focus { outline: none; border-color: oklch(80% 0.15 230); }

.rt-review-actions { display: flex; gap: 8px; }

.rt-btn-ghost, .rt-btn-primary {
  flex: 1 1 0;
  font: inherit;
  font-size: 13px;
  font-weight: 650;
  padding: 10px 12px;
  min-height: 44px;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.15s var(--rec-ease), border-color 0.15s var(--rec-ease);
}
.rt-btn-ghost {
  color: var(--rec-text);
  background: var(--rec-surface-2);
  border: 1px solid var(--rec-border);
}
.rt-btn-ghost:hover { background: oklch(100% 0 0 / 0.12); }
.rt-btn-primary {
  color: oklch(99% 0 0);
  background: oklch(62% 0.16 230);
  border: 1px solid oklch(72% 0.16 230);
}
.rt-btn-primary:hover { background: oklch(70% 0.17 230); }
.rt-btn-ghost:focus-visible, .rt-btn-primary:focus-visible {
  outline: 2px solid oklch(85% 0.12 230); outline-offset: 2px;
}

/* ── #11 PWA install guide: compact, no-scroll, 4 steps + video link ─────────
   The guide must fit on the device without forcing a scroll. .pwa-compact tightens the hero
   and steps so the whole 4-step flow + video link + button sits within the viewport. */
.pwa-compact {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: calc(100dvh - max(24px, env(safe-area-inset-top)) - max(24px, env(safe-area-inset-bottom)));
}
.pwa-compact .pwa-hero { margin: 0; }
.pwa-compact .pwa-phone { transform: scale(0.8); transform-origin: center top; }
.pwa-compact .rec-consent-title { font-size: 19px; margin: 0; }
.pwa-compact .rec-consent-text { font-size: 13.5px; line-height: 1.4; margin: 0; }
.pwa-compact .pwa-steps-v2 { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; }
.pwa-compact .pwa-step { padding: 8px 11px; }
.pwa-compact .pwa-step-sub { font-size: 11px; }

.pwa-video-link {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; align-self: center;
  background: none; border: none; cursor: pointer; padding: 7px 12px; border-radius: 10px;
  color: var(--lg-accent, #6aa8ff); font: inherit; font-size: 13px; font-weight: 650; min-height: 40px;
}
.pwa-video-link:hover { background: oklch(60% 0.14 255 / 0.12); }
.pwa-video-link:focus-visible { outline: 2px solid var(--lg-accent, #6aa8ff); outline-offset: 2px; }
.pwa-video-link.is-soon { color: inherit; opacity: 0.6; cursor: default; }

/* On shorter screens (iPhone SE and down, landscape, split-view), drop the decorative phone hero
   and tighten steps so the 4-step guide fits without scrolling — never clip, never force a scroll. */
@media (max-height: 720px) {
  .pwa-compact .pwa-hero { display: none; }
  .pwa-compact { gap: 8px; }
  .pwa-compact .pwa-step { padding: 7px 10px; }
  .pwa-compact .pwa-step-sub { font-size: 10.5px; }
}

/* ── R-P5: the floating glass video player ─────────────────────────────────── */
.yv-player {
  position: fixed;
  /* Reset the UA popover defaults (inset:0; margin:auto; padding:0.25em; border; background)
     so the player centres exactly and drag/resize can position it freely in the top layer. */
  inset: auto;
  margin: 0;
  padding: 0;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(340px, 92vw);
  height: auto;
  /* The clip is PORTRAIT (iPhone capture): without a viewport cap its intrinsic height
     overflows the screen and the header (the drag handle) lands off-canvas. */
  max-height: min(78dvh, calc(100dvh - 40px));
  z-index: 1500;
  display: flex;
  flex-direction: column;
  border-radius: 18px;
  overflow: hidden;
  background: oklch(20% 0.02 262 / 0.78);
  -webkit-backdrop-filter: blur(18px) saturate(1.5);
  backdrop-filter: blur(18px) saturate(1.5);
  border: 1px solid oklch(100% 0 0 / 0.25);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.3), 0 24px 60px -20px oklch(0% 0 0 / 0.8);
  color: #fff;
}
/* A modal <dialog>: showModal() reveals it in the TOP LAYER, and a 2nd showModal() stacks it
   above the install guide's own modal dialog. (dialog:not([open]) is display:none by UA.) */
.yv-player[open] { display: flex; }
.yv-player.yv-fallback { display: flex; }
.yv-player::backdrop { background: oklch(0% 0 0 / 0.4); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
.yv-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 8px 8px 14px; cursor: grab; touch-action: none;
  color: #fff; font-size: 13px; font-weight: 700;
}
.yv-head:active { cursor: grabbing; }
.yv-player video { width: 100%; flex: 1 1 auto; min-height: 0; max-height: 100%; object-fit: contain; background: #000; display: block; }
.yv-bar { display: flex; align-items: center; gap: 8px; padding: 8px 10px; }
.yv-b {
  min-width: 40px; min-height: 40px; border-radius: 11px; cursor: pointer;
  border: 1px solid oklch(100% 0 0 / 0.25); background: oklch(100% 0 0 / 0.12);
  color: #fff; font-size: 14px; font-weight: 700;
}
.yv-b:hover { background: oklch(100% 0 0 / 0.2); }
.yv-speed { font-size: 12px; font-variant-numeric: tabular-nums; min-width: 46px; padding: 0 8px; }
.yv-speed.is-slow { color: #ffd9a3; border-color: oklch(80% 0.12 70 / 0.5); }
.yv-speed.is-fast { color: #a9e5ff; border-color: oklch(80% 0.12 230 / 0.5); }
.yv-seek { flex: 1 1 auto; min-width: 0; accent-color: #6aa8ff; }

/* Bidirectional speed control — a slider (+ −/+ steppers) that snaps to the discrete steps and
   moves in EITHER direction directly, instead of the old cycle-through-every-speed button. */
.yv-speed-wrap { position: relative; flex: 0 0 auto; }
.yv-speed-pop {
  position: absolute;
  bottom: calc(100% + 10px);
  right: -6px;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  width: 208px;
  padding: 12px 14px 13px;
  border-radius: 15px;
  background: oklch(24% 0.02 262 / 0.94);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  backdrop-filter: blur(20px) saturate(1.4);
  border: 1px solid oklch(100% 0 0 / 0.22);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.28), 0 16px 40px -14px oklch(0% 0 0 / 0.7);
  animation: yv-speed-in 0.16s cubic-bezier(0.22, 1, 0.36, 1);
}
.yv-speed-pop[hidden] { display: none; }
/* A little pointer down to the speed chip. */
.yv-speed-pop::after {
  content: ''; position: absolute; top: 100%; right: 14px;
  border: 7px solid transparent; border-top-color: oklch(24% 0.02 262 / 0.94);
}
@keyframes yv-speed-in { from { opacity: 0; transform: translateY(6px) scale(0.97); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .yv-speed-pop { animation: none; } }

.yv-speed-cap {
  font-size: 10px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  color: oklch(100% 0 0 / 0.6);
}
.yv-speed-track { display: flex; align-items: center; gap: 8px; width: 100%; }
.yv-speed-step {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 8px; cursor: pointer;
  display: grid; place-items: center; line-height: 1;
  font-size: 17px; font-weight: 700; color: #fff;
  background: oklch(100% 0 0 / 0.12); border: 1px solid oklch(100% 0 0 / 0.22);
}
.yv-speed-step:hover { background: oklch(100% 0 0 / 0.22); }
.yv-speed-step:active { transform: scale(0.92); }
.yv-speed-range {
  flex: 1 1 auto; min-width: 0; height: 22px; margin: 0; cursor: pointer;
  accent-color: var(--brand-bright, #6aa8ff);
}
.yv-speed-val {
  font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; color: #fff;
  min-width: 3ch; text-align: center;
}
.yv-err { color: #ffd7d0; font-size: 12px; padding: 6px 12px; }
.yv-grip {
  position: absolute; right: 2px; bottom: 2px; width: 22px; height: 22px;
  cursor: nwse-resize; touch-action: none; z-index: 5;
  background: linear-gradient(135deg, transparent 55%, oklch(100% 0 0 / 0.5) 56%, transparent 62%, oklch(100% 0 0 / 0.5) 68%, transparent 74%, oklch(100% 0 0 / 0.5) 80%, transparent 86%);
}
.yv-grip::before { content: ''; position: absolute; inset: -11px; }
