/* ==========================================================================
   ASK BY VOICE — the full-screen voice UI (Peter, 31 Jul 2026)
   --------------------------------------------------------------------------
   Full viewport, dark, calm. Back chevron top left; four-dot cluster in the
   centre reflecting state (idle still · listening reacts to the mic level ·
   thinking slow pulse · speaking moving); stop / big white mic / close along
   the bottom. Mobile-first; behaves on desktop. States are driven by
   [data-state] set in js/ask-voice.js; --level (0–1) is the live mic level.
   ========================================================================== */

.voice {
  position: fixed;
  inset: 0;
  z-index: 99990;                 /* over the app + ask panel; under the guide */
  /* LIGHT, the Sana way (Peter, 31 Jul: "black background and just flat
     cards" — shadows cannot exist on black; the dashboard-card look needs
     the soft light canvas the cards float on) */
  background: #f4f4f6;
  color: var(--color-text, #111);
  display: flex;
  flex-direction: column;
  font-family: inherit;
}

.voice__top {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 14px 16px 0;
  flex: none;
}
.voice__back {
  background: none;
  border: none;
  color: var(--color-text, #111);
  cursor: pointer;
  padding: 8px;
  border-radius: 10px;
  line-height: 0;
}
.voice__title { font-size: var(--text-base); color: rgba(17, 17, 17, 0.85); }
.voice__spacer { flex: 1; }

.voice__mid {
  flex: 1;
  min-height: 0;
  position: relative;   /* the B + state line float over the thread */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  /* NO reserved strip at the bottom (Peter, 31 Jul, third ask): the cards run
     right down BEHIND the floating controls — the empty band the old padding
     left under them read as 'the microphone has a background'. */
  padding: 0 20px;
  /* the room the floating B + state line need at the head of the thread */
  --voice-head: 128px;
  overflow: hidden;
}

/* THE THREAD — the whole conversation, WhatsApp-shaped (Peter, 31 Jul night):
   your line, her line, her answer card embedded under it, newest at the
   bottom, full history a scroll up. One plane; nothing scrolls inside it. */
.voice__thread {
  position: relative;   /* offsetTop anchors for the auto-slide */
  flex: 1;
  min-height: 0;
  width: min(560px, 100%);
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 22px;   /* air between speakers (Peter, 31 Jul) */
  /* head-room clears the floating B at rest; scrolled content passes
     BEHIND it. the tail-room lets the last card's links scroll clear of
     the floating mic */
  padding-top: var(--voice-head, 128px);
  padding-bottom: 140px;
}
.voice__thread .voice__answer { align-self: stretch; }

/* ---- the liquid blob (replaces the four dots — Peter, 31 Jul, 2nd pass) ----
   Not the logo: "something very fluid, pulsating in and out, as if it was
   made out of liquid and the liquid was slowly moving." The black ball's edge
   runs through slowly-morphing turbulence (in the inline SVG) so the surface
   undulates; these rules do the PULSE — a deep slow breath at rest,
   level-reactive while listening, quicker while she thinks and speaks. */
/* The B FLOATS over the thread (Peter, 31 Jul night: the static band was
   cropping the text) — the conversation slides up BEHIND it. The frost is a
   SEPARATE layer under the glyph (::before): big enough to catch the pulse
   at full swell, and masked so the glass fades to NOTHING at the edge — no
   hard rim (Peter's two calls). The B itself stays crisp on top. */
.voice__orb {
  width: 58px;   /* 40% down from 96 (Peter, 31 Jul) */
  height: 58px;
  color: var(--color-text, #111);
  flex: none;
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 15;
}
.voice__orb::before {
  content: '';
  position: absolute;
  inset: -30px;   /* disc radius ~59px — the B at its biggest pulse is ~42px */
  border-radius: 50%;
  z-index: -1;
  background: radial-gradient(circle, rgba(244, 244, 246, 0.85) 35%, rgba(244, 244, 246, 0) 70%);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  -webkit-mask-image: radial-gradient(circle, #000 40%, transparent 70%);
  mask-image: radial-gradient(circle, #000 40%, transparent 70%);
}
.voice__orb svg { width: 100%; height: 100%; overflow: visible; display: block; transition: transform .12s ease, opacity .3s ease; }
/* idle — pulsating in and out, liquid slowly moving */
.voice[data-state="idle"] .voice__orb svg { animation: voiceOrbIdle 4.2s ease-in-out infinite; }
@keyframes voiceOrbIdle { 0%, 100% { transform: scale(0.92); } 50% { transform: scale(1.08); } }
/* listening — bulges with the input level */
.voice[data-state="listening"] .voice__orb svg { transform: scale(calc(1 + var(--level, 0) * 0.45)); }
/* thinking — a quicker, deeper pulse */
.voice[data-state="thinking"] .voice__orb svg { animation: voiceOrbThink 1.1s ease-in-out infinite; }
@keyframes voiceOrbThink { 0%, 100% { transform: scale(0.94); opacity: 0.75; } 50% { transform: scale(1.1); opacity: 1; } }
/* speaking — bulging in and out with the voice */
.voice[data-state="speaking"] .voice__orb svg { animation: voiceOrbSpeak 0.85s ease-in-out infinite; }
@keyframes voiceOrbSpeak { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }
/* trouble states — dimmed and still */
.voice[data-state="denied"] .voice__orb svg,
.voice[data-state="offline"] .voice__orb svg,
.voice[data-state="nothing"] .voice__orb svg { opacity: 0.3; animation: none; }
@media (prefers-reduced-motion: reduce) {
  .voice__orb svg { animation: none !important; transform: none !important; }
  .voice__orb path { filter: none; }
}

.voice__state {
  font-size: var(--text-base);
  color: rgba(17, 17, 17, 0.72);
  text-align: center;
  margin: 0;
  max-width: 420px;
  line-height: 1.5;
  /* floats with the B; its frost is the same soft-edged layer — the text
     stays crisp, the glass fades out */
  position: absolute;
  top: 96px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 15;
  white-space: nowrap;
  padding: 3px 18px;
}
.voice__state::before {
  content: '';
  position: absolute;
  inset: -8px -22px;
  border-radius: 999px;
  z-index: -1;
  background: radial-gradient(ellipse closest-side, rgba(244, 244, 246, 0.85) 45%, rgba(244, 244, 246, 0) 100%);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  -webkit-mask-image: radial-gradient(ellipse closest-side, #000 50%, transparent 100%);
  mask-image: radial-gradient(ellipse closest-side, #000 50%, transparent 100%);
}
.voice__state:empty { display: none; }
/* the written conversation, the Sana way (Peter, 31 Jul, second pass: "the
   text is much bigger… include her in the sentence"): HER words the big
   centre text, her face inline in the sentence, each word grey until spoken
   (.vk → .vk.on — the karaoke in ask-voice.js); YOUR words the same type
   with your face trailing. */
.voice__line { margin: 0; font-size: 17px; line-height: 1.5; color: var(--color-text, #111); }
/* YOUR words are styled exactly like HERS — same big type, black; the two
   faces are what tell the speakers apart (Peter, 31 Jul: "my dictation
   should operate and be styled just like when Mariana talks") */
.voice .voice__line--you,
.voice .voice__line--her {
  font-size: clamp(24px, 6.4vw, 31px);
  line-height: 1.32;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--color-text, #111);
}
.voice__line--her .vk { color: rgba(17, 17, 17, 0.26); transition: color .25s ease; }
.voice__line--her .vk.on { color: var(--color-text, #111); }
.voice__dim { color: rgba(17, 17, 17, 0.26); }
.voice__avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
}
.voice__avatar--b, .voice__face--b { background: var(--color-text, #111); display: inline-flex; align-items: center; justify-content: center; }
/* .voice__face below sets inline-block and outranks the line above by order, so the B sat top-left (Peter, 5 Sep) */
.voice__face.voice__face--b, .voice__avatar.voice__avatar--b { display: inline-flex; }
.voice__avatar--b img, .voice__face--b img { width: 55%; height: 55%; filter: invert(1); display: block; }
.voice__earlier { max-height: none; overflow: visible; margin: 0 0 18px; }
.voice__face:not(.voice__face--b) { box-shadow: 0 0 0 1px #fff; }   /* a 1px white ring on your face (Peter, 4 Sep) */
.voice__face {
  display: inline-block;   /* base.css blocks imgs — inline keeps her in the sentence */
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  vertical-align: -7px;
  margin: 0 2px;
}
/* THE AVATAR HEADS EACH MESSAGE (Peter, 31 Jul night — "a better divider
   between the chats"): a face that OPENS a line sits centred above it.
   The greeting keeps her face inside the sentence (it isn't first). */
.voice__line > .voice__face:first-child {
  display: block;
  margin: 0 auto 6px;
}
/* the speaker's face PULSES while their words are running (Peter, 31 Jul
   night) — is-live rides the karaoke cursor / the reveal */
.voice__line.is-live > .voice__face:first-child { animation: voiceFacePulse 1.15s ease-in-out infinite; }
/* the B heading a line: the rule above (0,3,0) beat the B's flex centring, so the mark sat top-left
   inside the padding (Peter, 5 + 7 Sep, twice). Same slot, the disc centred, the B centred in it. */
.voice__line > .voice__face--b:first-child { display: flex; padding: 0; margin: 18px auto; }
@keyframes voiceFacePulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.18); } }
@media (prefers-reduced-motion: reduce) {
  .voice__line.is-live > .voice__face:first-child { animation: none; }
}

/* ---- the prompt cards (the Sana skill cards, carrying our chips) -----------
   Three of the screen's suggested questions, fanned like a hand of cards,
   rising in one after another when the screen opens. Brand-coloured the way
   Sana's are brand-blue — ours take the Bullet yellow. They leave the moment
   a conversation starts (.is-talking). */
.voice__cards {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  margin-top: 22px;
  transition: opacity .35s ease, visibility .35s;
}
.voice.is-talking .voice__cards { opacity: 0; visibility: hidden; height: 0; margin: 0; overflow: hidden; }
.voice__card {
  width: 150px;
  min-height: 138px;
  margin: 0 -8px;
  padding: 16px 15px;
  border: none;
  border-radius: 22px;
  background: var(--color-hilite-strong, #ffe135);
  color: var(--color-text, #111);
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 6px;
  box-shadow: 0 14px 30px -14px rgba(17, 17, 17, 0.35);
  z-index: var(--i, 0);
  /* THE FLICK (Peter, 31 Jul: "like a card being flicked into position"):
     each card starts below the bottom of the screen, swung the WRONG way,
     and flies up into its slot in the fan — the entrance curve's overshoot
     gives the flick its snap; one card after another */
  opacity: 0;
  transform: translateY(75vh) rotate(calc(var(--r, 0deg) * -2.5));
  transition: transform .65s cubic-bezier(0.16, 1, 0.3, 1), opacity .3s ease, box-shadow .3s ease;
  transition-delay: calc(var(--i, 0) * 0.14s);
}
.voice__cards.is-in .voice__card { opacity: 1; transform: translateY(var(--dy, 0px)) rotate(var(--r, 0deg)); }
.voice__cards.is-in .voice__card:hover { transition-delay: 0s; box-shadow: 0 20px 36px -14px rgba(17, 17, 17, 0.45); z-index: 5; }
.voice__card-lead { font-size: 11px; font-weight: 500; color: rgba(17, 17, 17, 0.55); }
.voice__card-q { font-size: 15px; font-weight: 600; line-height: 1.3; }
.voice__card:focus-visible { outline: 2px solid var(--color-text, #111); outline-offset: 3px; z-index: 5; }
/* phones: the fan tightens so all three stay on screen */
@media (max-width: 480px) {
  .voice__card { width: 124px; min-height: 124px; margin: 0 -12px; padding: 14px 13px; }
  .voice__card-q { font-size: 13px; }
}
@media (prefers-reduced-motion: reduce) {
  .voice__card { transition: none; }
  .voice__cards .voice__card { opacity: 1; }
}

/* ---- answers: the normal component, embedded in the thread ----------------
   A new card lands with a small WhatsApp-style rise; the plane itself does
   the moving — nothing slides behind or over anything (Peter, 31 Jul). */
.voice__answer { animation: voiceCardIn .35s cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes voiceCardIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .voice__answer { animation: none; } }
.voice__answer {
  background: var(--color-surface, #fff);
  color: var(--color-text, #111);
  border-radius: var(--radius-lg, 14px);
  padding: 18px 20px;
}
/* ---- bottom bar ------------------------------------------------------------ */
.voice__bar {
  /* FLOATING (Peter, 31 Jul: "the microphone has a background that hides
     everything underneath") — the buttons hover over the canvas and the
     cards slide beneath them through a soft fade, no hard band. */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 44px;
  /* the extra bottom room keeps the Push-to-talk caption clear of the edge */
  padding: 34px 0 calc(44px + env(safe-area-inset-bottom, 0px));
  /* NO background at all (Peter, 31 Jul, twice) — the buttons float clean
     and the cards are fully visible beneath them. */
  background: none;
  pointer-events: none;
  /* ALWAYS ON TOP (Peter, 31 Jul, third time: "the microphone is hidden") —
     a tall answer card was painting OVER the mic; the plane slides beneath
     the buttons, never over them. */
  z-index: 20;
}
.voice__bar button { pointer-events: auto; }
.voice__side {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid rgba(17, 17, 17, 0.22);
  background: #fff;
  color: rgba(17, 17, 17, 0.75);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.voice__side:hover { border-color: rgba(17, 17, 17, 0.5); }
/* the mic with its caption — "Push to talk" lives under the button (Peter,
   31 Jul: the floating "Tap the mic to talk" state line is gone) */
.voice__micwrap { position: relative; display: inline-flex; }
.voice__pushlabel {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  font-size: var(--text-sm, 13px);
  color: rgba(17, 17, 17, 0.6);
  white-space: nowrap;
  pointer-events: none;
}
.voice__mic {
  width: 76px;
  height: 76px;
  border-radius: 50%;
  border: none;
  background: var(--color-text, #111);
  color: #fff;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 12px 32px -8px rgba(17, 17, 17, 0.4);
}
.voice__mic svg { width: 30px; height: 30px; }
.voice[data-state="listening"] .voice__mic { box-shadow: 0 0 0 calc(6px + var(--level, 0) * 22px) rgba(17, 17, 17, 0.08), 0 12px 32px -8px rgba(17, 17, 17, 0.4); }
.voice__back:focus-visible, .voice__side:focus-visible, .voice__mic:focus-visible { outline: 2px solid var(--color-text, #111); outline-offset: 3px; }

/* ---- the mic button inside the ask box ------------------------------------
   Sits INSIDE the pill beside Ask (Peter, 14 Aug) — no button chrome of its
   own, just the glyph with a round hover. */
.ask-mic {
  flex: none;
  width: 40px;
  height: 40px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  border-radius: var(--radius-full);
}
.ask-mic:hover { background: var(--color-bg-subtle); }
.ask-mic svg { width: 20px; height: 20px; }
.ask-float .ask-mic { width: 38px; height: 38px; }

/* The line flag (voice-line learning cycle, 12 Aug W3 — built 27 Aug): a tiny
   ⚑ on each of HER lines, invisible until the line is hovered (or tapped, on
   touch), so the thread stays clean. Flagged = green tick, stays put. */
/* IN-FLOW after her last word, faintly there ALWAYS (Peter, 27 Aug: "I don't
   see this" — v1 hung it outside the line inside overflow:hidden, hover-only:
   invisible twice over). */
.voice__flag {
  display: inline-block;
  border: none;
  background: none;
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  color: currentColor;
  opacity: 0.45;
  margin-left: 8px;
  padding: 0 4px;
  transition: opacity 0.15s ease;
  vertical-align: baseline;
}
.voice__flag:hover, .voice__flag:focus-visible, .voice__flag.is-flagged { opacity: 1; }
.voice__flag.is-flagged { cursor: default; }


/* ============================================================================
   THE ORANGE COAT (Peter, 27 Aug: "make the bg this orange and the white
   text, white B"). One variable holds the orange — swap --voice-orange when
   Peter names the exact hex (his swatch never attached; this is the
   product's own orange from the celebration palette). Scoped to .voice, so
   the 60 rules above keep their geometry and only the colours turn.
   ========================================================================== */
.voice {
  --voice-orange: #e8732c;
  background: var(--voice-orange);
  color: #fff;
}
.voice__orb { color: #fff; }
.voice__orb::before {
  background: radial-gradient(circle, rgba(232, 115, 44, 0.85) 35%, rgba(232, 115, 44, 0) 70%);
}
/* karaoke on orange: unspoken words are white at half strength, spoken full */
.voice .voice__line { color: rgba(255, 255, 255, 0.92); }
.voice .voice__line--her .vk { color: rgba(255, 255, 255, 0.55); }
.voice .voice__line--her .vk.on { color: #fff; }
.voice .voice__line--you { color: #fff; }
/* the side controls + labels go white */
.voice .voice__side, .voice .voice__back, .voice .voice__mic { color: #fff; border-color: rgba(255, 255, 255, 0.5); }
.voice .voice__pushlabel, .voice .voice__state { color: rgba(255, 255, 255, 0.8); }
/* the answer + prompt cards STAY white cards — flat cards floating on the
   orange, the Sana way; their own text stays dark and readable */
/* THE MUTE IS UNMISSABLE (Peter: "make that obvious in the design"):
   held = the button fills dark with a slash, the whole canvas dims a beat */
.voice .voice__mic.is-muted {
  background: rgba(0, 0, 0, 0.45);
  border-color: #fff;
  position: relative;
}
.voice .voice__mic.is-muted::after {
  content: '';
  position: absolute;
  left: 10%;
  top: 46%;
  width: 80%;
  height: 3px;
  background: #fff;
  border-radius: 2px;
  transform: rotate(-45deg);
}
.voice:has(.voice__mic.is-muted) { background: color-mix(in srgb, var(--voice-orange) 72%, #000); }


/* ============================================================================
   PETER'S 27 AUG ROUND TWO — on top of the orange coat above.
   ========================================================================== */
/* 1. "Listening" loses the white halo — plain white text on the orange */
.voice .voice__state { color: rgba(255, 255, 255, 0.85); }
.voice .voice__state::before { display: none; }

/* 2. THE CARDS, the reference style (his screenshot; our copy): white card,
   green tick badge, bold dark line, the little lead as a caption at the foot */
.voice .voice__card {
  background: #fff;
  color: var(--color-text, #111);
  width: 158px;
  min-height: 150px;
  border-radius: 20px;
  gap: 10px;
}
.voice__card-tick {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: #22c55e;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: 700;
  flex: none;
}
.voice .voice__card-q { font-size: 15px; font-weight: 700; line-height: 1.3; color: #111; }
.voice .voice__card-lead { margin-top: auto; font-size: 11px; color: rgba(17, 17, 17, 0.4); }

/* 3. the mic: white face, black icon — the mute state stays the dark slash,
   so live vs muted cannot be confused */
.voice .voice__mic { background: #fff; color: #111; border-color: #fff; }
/* 4. the side buttons: half-transparent white discs, icons full white */
.voice .voice__side { background: rgba(255, 255, 255, 0.5); color: #fff; border-color: transparent; }

/* 5. the typed ask — the blue-reference dialogue, translated to the orange */
/* IN THE STACK, symmetric with the buttons (Peter, 28 Aug — his red box: the
   input at the cluster's own width, directly above it, never behind the mic).
   Click into it and it GROWS and turns pure white. */
.voice__ask {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 300px;
  margin: 0 auto 12px;
  background: rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  padding: 6px 6px 6px 20px;
  transition: width .35s cubic-bezier(0.22, 1, 0.36, 1), background .25s ease;
}
.voice__ask:focus-within { width: min(560px, calc(100vw - 48px)); background: #fff; }
.voice__ask:focus-within .voice__ask-in { color: #111; }
.voice__ask:focus-within .voice__ask-in::placeholder { color: rgba(17, 17, 17, 0.4); }
.voice__ask:focus-within .voice__ask-go { background: #111; color: #fff; }
.voice__btnrow { display: flex; align-items: center; justify-content: center; gap: 24px; }

.voice__ask-in {
  flex: 1;
  border: none;
  background: none;
  font: inherit;
  font-size: 15px;
  color: #fff;
  outline: none;
  min-width: 0;
}
.voice__ask-in::placeholder { color: rgba(255, 255, 255, 0.65); }
.voice__ask-go {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.35);
  color: #fff;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.voice__ask-go:hover { background: rgba(255, 255, 255, 0.5); }


/* Peter, 28 Aug — polish round: NO shadows on the mic or side buttons, and
   the thread never shows a scrollbar over the orange. */
.voice .voice__mic, .voice .voice__side, .voice .voice__ask-go { box-shadow: none; }
.voice__thread { scrollbar-width: none; -ms-overflow-style: none; }
.voice__thread::-webkit-scrollbar { display: none; }
/* the bar stacks: input above, buttons under */
.voice__bar { flex-direction: column; }


/* THE CONTROLS RIDE OVER EVERYTHING (Peter, 28 Aug: "put the menu and the
   chat in front of everything" — the answer card was lying on top of the
   typed input). The whole bottom stack sits above the thread, and the thread
   keeps enough foot-room that its last card can always scroll clear. */
.voice__bar { z-index: 30; }
.voice__thread { padding-bottom: 250px; }   /* grew when the input joined the bar — the card's foot must clear it (Peter, 28 Aug screenshot) */


/* …and the control zone carries its own orange scrim, so a tall card can
   never read through the input, the mic or the hint — the thread slides in
   under a fade, the controls stand on solid ground. */
.voice .voice__bar {
  background: linear-gradient(to top, var(--voice-orange) 68%, rgba(232, 115, 44, 0));
  padding-top: 34px;
  pointer-events: none;            /* the fade band above the input stays scrollable */
}
.voice .voice__bar > * { pointer-events: auto; }
.voice:has(.voice__mic.is-muted) .voice__bar {
  background: linear-gradient(to top, color-mix(in srgb, var(--voice-orange) 72%, #000) 68%, rgba(0, 0, 0, 0));
}


/* THE B SCROLLS WITH THE PAGE (Peter, 28 Aug: "have the logo static — when
   you scroll down it just stays on the same part of the page and scrolls
   up"). The orb and the state line were absolute-pinned over the thread, so
   the conversation slid UNDER the glyph — they live inside the thread now
   and leave with it. */
.voice .voice__orb { position: static; margin: 6px auto 2px; transform: none; left: auto; top: auto; }
.voice .voice__state { position: static; transform: none; left: auto; top: auto; margin: 0 auto 6px; }


/* THE FROST IS DEAD (Peter, 28 Aug: "there is a fuzzy overlay on the main
   chat lane — I can't select the cards"). The orb carried a masked
   backdrop-blur halo from its PINNED days, to stay readable over text
   scrolling beneath it. The B scrolls WITH the thread now, nothing passes
   under it — and Safari renders that masked backdrop-filter as a huge blur
   patch sitting on the cards. No job + real harm = gone. */
.voice__orb::before { display: none; }
.voice__orb { -webkit-backdrop-filter: none; backdrop-filter: none; }

/* Tooltips on the voice screen: white card, black text (Peter, 28 Aug) —
   the global #ui-tip is dark-on-light for the app; on the orange it inverts. */
body.voice-open #ui-tip { background: #fff; color: #111; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25); }


/* THE SHAPE, all three (Peter, 28 Aug — "change the shape, all 3"):
   1. her measure widens on big screens — a two-sentence answer sits in 4-5
      lines instead of a 7-line wall; the SIZE stays exactly as it is
   2. YOUR lines step back — ~75% size, slightly dimmed, so the conversation
      reads question-whispers / answer-lands
   3. the card keeps its tighter width — voice loud and wide, figures tidy */
@media (min-width: 1440px) {
  .voice .voice__thread { width: min(840px, 100%); }
  /* the card keeps its tighter reading width inside the wider lane */
  .voice .voice__answer, .voice .voice__cards { max-width: 660px; margin-left: auto; margin-right: auto; }
}
/* 75%% of HER size, and lighter (Peter, 28 Aug — the first cut scaled off
   the 17px base and came out tiny) */
.voice .voice__line--you {
  font-size: clamp(18px, 4.8vw, 23px);
  font-weight: 500;
  opacity: 0.82;
}


/* THE BIG OFFER PILLS (Peter, 28 Aug): the questions she just spoke, as
   tap targets under her line — translucent white like the chat input, big
   enough for a thumb or a glance while driving. */
.voice__offer {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin: 14px auto 18px;
  max-width: 700px;
}
.voice__offerpill {
  border: none;
  background: rgba(255, 255, 255, 0.22);
  color: #fff;
  font: inherit;
  font-size: 17px;
  font-weight: 600;
  padding: 13px 22px;
  border-radius: 999px;
  cursor: pointer;
  transition: background .15s ease;
}
.voice__offerpill:hover { background: rgba(255, 255, 255, 0.35); }

/* one obvious place for follow-ups in voice — the card's small chips hide */
.voice .voice__answer .answer__followups { display: none; }

/* THE CARD'S ROWS ALIGN (Peter, 28 Aug, third ask): the doors and pills rows
   were centred, so their left edges wandered card to card — both rows now
   start from the same left margin. */
.voice .voice__answer .answer__doors,
.voice .voice__answer .answer__followups { justify-content: flex-start; }


/* TWO BIG CARDS on the fresh screen (Peter, 28 Aug — the reference ratio:
   chunky, thumb-first, a choice not a menu). */
.voice .voice__card {
  width: 232px;
  min-height: 216px;
  border-radius: 26px;
  padding: 22px 20px;
  gap: 12px;
}
.voice .voice__card-tick { width: 42px; height: 42px; font-size: 19px; }
.voice .voice__card-q { font-size: 18px; line-height: 1.32; }
.voice .voice__card-lead { font-size: 12px; }
/* PHONES (Peter, 2 Sep: "fix the cards in mobile view"): the two big cards
   were still 232px each on a 375px screen, so the pair overflowed the left
   edge and sat on top of each other. This rule outranks the 480px rule above
   (that one lost to .voice .voice__card on specificity, which is why the
   phone never got its smaller cards). Two cards share the width, the fan
   flattens to a gentle tilt, and the row keeps a little air for shadows. */
@media (max-width: 480px) {
  .voice .voice__cards { padding: 0 16px; gap: 10px; }
  .voice .voice__card { width: calc(50% - 5px); min-height: 172px; margin: 0; padding: 18px 16px; border-radius: 22px; }
  .voice .voice__cards.is-in .voice__card { transform: translateY(var(--dy, 0px)) rotate(calc(var(--r, 0deg) * 0.35)); }
  .voice .voice__card-tick { width: 36px; height: 36px; font-size: 16px; }
  .voice .voice__card-q { font-size: 16px; }
}


/* THE IN-SENTENCE PILLS (Peter, 28 Aug second pass): her own words, same
   font, a pale pill behind them — tappable. box-decoration-break keeps the
   pill whole when the phrase wraps a line. */
.voice__inpill {
  background: rgba(255, 255, 255, 0.18);
  border-radius: 14px;
  padding: 1px 12px 3px;
  cursor: pointer;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  transition: background .15s ease;
}
.voice__inpill:hover { background: rgba(255, 255, 255, 0.3); }
/* the separate offer row is retired — the sentence is the offer */
.voice__offer { display: none; }


/* 1440×900 FIT (Peter, 28 Aug: "pull it up — the bullet logo level with the
   back button and Mariana's icon"). The B lives in the top bar now, so the
   whole lane starts high and nothing needs scrolling on a laptop. */
.voice .voice__top .voice__orb { position: static; width: 40px; height: 40px; margin: 0; }
.voice .voice__state { margin-top: 2px; }
/* the flag, twice the size (Peter, 28 Aug) */
.voice__flag { font-size: 26px; padding: 0 8px; }


/* IN-PILL FIXES (Peter, 28 Aug): the pill boxes were taller than the line
   box, so pills on adjacent lines collided — a line carrying pills opens its
   leading. And the tap affordance: a stronger resting fill + a little ›
   inside the pill, so it reads as a button without breaking the sentence. */
.voice .voice__line--her:has(.voice__inpill) { line-height: 1.6; }
.voice__inpill { background: rgba(255, 255, 255, 0.24); padding: 0 12px 2px; }
.voice__inpill::after {
  content: '›';
  margin-left: 7px;
  opacity: 0.75;
  font-weight: 700;
}


/* the quiet flag acknowledgement in the thread */
.voice__flagack {
  text-align: center;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.75);
  margin: 4px auto 10px;
  max-width: 480px;
}


/* the DID-YOU-MEAN card keeps its option buttons — the in-pills rule hides
   follow-up chips on ANSWER cards, and was blanking this card to an empty
   "Did you mean:" shell (Peter's screenshot, 28 Aug) */
.voice .voice__answer .answer__lead ~ .answer__followups { display: flex; }
/* the help chat rides OVER the voice screen when a flag opens it */
body.voice-open #demo-chat { z-index: 99995 !important; }   /* the panel carries an inline z */

/* YELLOW IS THE AI (Peter, 8 Sep): the takeover wears Bullet's yellow, not orange, and its type goes to
   ink. One colour means "Bullet is talking", on the bar, the answer box, the takeover and the chat. */
.voice { --voice-orange: #ffe000; color: #111; }
.voice .voice__orb, .voice .voice__line--you, .voice .voice__line--her .vk.on, .voice .voice__state, .voice .voice__ask-in, .voice .voice__offerpill, .voice .voice__card-tick { color: #111; }
.voice .voice__line--her .vk { color: rgba(17, 17, 17, .38); }
.voice .voice__side, .voice .voice__back { background: rgba(17, 17, 17, .1); color: #111; border-color: transparent; }
.voice .voice__mic { background: #111; color: #fff; border-color: #111; }
.voice .voice__offerpill { background: rgba(255, 255, 255, .55); }
.voice .voice__bar { background: linear-gradient(to top, var(--voice-orange) 68%, rgba(255, 224, 0, 0)); }
.voice:has(.voice__mic.is-muted) .voice__bar { background: linear-gradient(to top, color-mix(in srgb, var(--voice-orange) 72%, #000) 68%, rgba(0, 0, 0, 0)); }
.voice:has(.voice__mic.is-muted) { color: #fff; }
.voice .voice__ask { background: rgba(255, 255, 255, .55); }
.voice .voice__ask-in::placeholder { color: rgba(17, 17, 17, .5); }
.voice .voice__line, .voice .voice__line--her, .voice .voice__line--hello, .voice .voice__line--you { color: #111; }
.voice .voice__dim { color: rgba(17, 17, 17, .55); }
.voice .voice__line--her .vk { color: rgba(17, 17, 17, .38); }
.voice .voice__line--her .vk.on { color: #111; }
.voice .voice__state, .voice .voice__pushlabel { color: rgba(17, 17, 17, .62) !important; }
