/* ==========================================================================
   Nota Voice — brand-integrated vocal experience.
   Two states: a silver seed (resting) and an immersive field (active).
   All colours flow from the Nota brand tokens — nothing is hardcoded.

   Two modes:
   - Fullscreen (default): immersive full-viewport experience
   - Inline: embedded within a component/pane, compact overlay
   ========================================================================== */

/* Voice uses the brand accent; the shared action ink remains readable
   in the traditional light/dark panel and on the floating launch control. */
.nv-seed, .nv-field {
  --voice-ink: var(--brand, #1a5490);
  --voice-tint: var(--brand-tint, rgba(26, 84, 144, 0.08));
  --voice-accent: var(--accent-purple, #6b4c9a);
}

/* --- Seed: the resting icon ---------------------------------------------- */
/* Rendered only where the page has NO help speed-dial (voice-panel.js
   renderSeed): where the dial exists its « Vocal » option is the door, and a
   second fixed bottom-right control painted over it. So the seed owns the
   16px..60px band of the corner — the slot the retired .guide-fab left, 10px
   below .sup-wrap (styles.css, bottom: 70px) — plus --nv-seed-clearance, the
   deterministic lift for any other fixed layer stacked in that corner, and the
   iOS safe-area insets so the home indicator never covers it. */
.nv-seed {
  --nv-seed-clearance: 0px;
  position: fixed;
  right: calc(clamp(16px, 3vw, 28px) + env(safe-area-inset-right, 0px));
  bottom: calc(16px + var(--nv-seed-clearance) + env(safe-area-inset-bottom, 0px));
  z-index: 1000;
  width: 44px;
  height: 44px;
  border-radius: var(--radius, 8px);
  border: 1px solid var(--border-strong, #a9c3ce);
  /* Opaque: the seed floats over arbitrary page content (a white card, a
     photo), and a transparent fill let whatever was behind it read through.
     Still the ghost register — surface fill, outlined border, brand only on
     the glyph. */
  background: var(--surface, #fbfdfd);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform var(--motion-enter) var(--ease-spring),
              border-color var(--motion-enter) var(--ease-ui),
              background var(--motion-enter) var(--ease-ui);
  font-family: var(--font-sans, 'Inter', system-ui, sans-serif);
}
.nv-seed:is(:hover, :focus-visible) {
  transform: scale(1.08);
  border-color: var(--voice-ink);
  background: var(--voice-tint);
}
.nv-seed:focus-visible {
  outline: 2px solid var(--voice-ink);
  outline-offset: 2px;
}
.nv-seed:active { transform: scale(0.96); }
.nv-seed svg {
  width: 20px;
  height: 20px;
  color: var(--ink-muted, #526b78);
  transition: color var(--motion-enter) var(--ease-ui);
}
.nv-seed:is(:hover, :focus-visible) svg { color: var(--voice-ink); }
.nv-seed svg {
  animation: nv-seed-breathe 3.5s ease-in-out infinite;
}
.nv-seed .nv-beta-dot {
  position: absolute;
  top: -2px;
  right: -2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--voice-ink);
  /* A ring in the control's own fill: the dot reads punched out of the seed
     rather than bleeding into whatever is behind it. */
  border: 2px solid var(--surface, #fbfdfd);
  opacity: 0;
  transition: opacity var(--motion-enter) var(--ease-ui);
}
.nv-seed:is(:hover, :focus-visible) .nv-beta-dot { border-color: var(--voice-tint); }
.nv-seed.has-beta .nv-beta-dot { opacity: 1; }

/* --- Corner stack --------------------------------------------------------- */
/* What else pins the bottom-right corner of a page with no speed-dial, and
   what the seed does about it (line numbers are styles.css's, which moves
   under concurrent edits):
   .sup-wrap / #chat-panel — bottom 70px desktop, clear of the seed's
     16px..60px band; its phone band drops it to bottom 10px full-width, so an
     open panel would sit under the seed's z-index 1000 → step out of it.
   .toast — bottom 24px, ~48px tall, up to 90vw so it crosses the corner → lift
     the seed 62px above its own inset, clear of the toast's top edge.
   .analytics-consent (z 10000) and dialog-based .account-tour already paint
   over the seed, so they cannot collide with it. */
body:has(#chat-panel:not([hidden])) .nv-seed {
  visibility: hidden;
}
body:has(.toast.show) .nv-seed {
  --nv-seed-clearance: 62px;
}

/* --- Field: the immersive experience ------------------------------------- */
.nv-field {
  position: fixed;
  inset: 0;
  z-index: 1001;
  font-family: var(--font-sans, 'Inter', system-ui, sans-serif);
  background: var(--surface, #fbfdfd);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transform: scale(0.92);
  transition: opacity var(--motion-enter) var(--ease-ui),
              transform var(--motion-enter) var(--ease-ui);
}
.nv-field.open {
  opacity: 1;
  pointer-events: auto;
  transform: scale(1);
}

/* Ambient subtle tint */
.nv-field::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--brand-tint, rgba(26, 84, 144, 0.04));
  pointer-events: none;
}

/* --- Close control ------------------------------------------------------- */
.nv-close {
  position: absolute;
  top: clamp(16px, 3vw, 28px);
  right: clamp(16px, 3vw, 28px);
  width: 44px;
  height: 44px;
  border-radius: var(--radius, 8px);
  border: 2px solid var(--brand, #1a5490);
  background: transparent;
  color: var(--brand, #1a5490);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--motion-ui) var(--ease-ui),
              color var(--motion-ui) var(--ease-ui),
              border-color var(--motion-ui) var(--ease-ui);
  font-size: 18px;
  line-height: 1;
}
.nv-close:hover {
  background: var(--brand-tint, rgba(26, 84, 144, 0.08));
  color: var(--brand, #1a5490);
  border-color: var(--brand, #1a5490);
}

/* --- Orb: the living centre ---------------------------------------------- */
.nv-orb-wrap {
  position: relative;
  width: 120px;
  height: 120px;
  margin-bottom: 40px;
  flex-shrink: 0;
}
.nv-orb {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: var(--brand-tint, rgba(26, 84, 144, 0.08));
  border: 2px solid var(--brand, #1a5490);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform var(--motion-enter) var(--ease-spring),
              border-color var(--motion-enter) var(--ease-ui);
}
.nv-orb svg {
  width: 36px;
  height: 36px;
  color: var(--brand, #1a5490);
  transition: color var(--motion-enter) var(--ease-ui),
              transform var(--motion-enter) var(--ease-ui);
}
.nv-orb-wrap:not(.listening) .nv-orb {
  animation: nv-idle-pulse 3s ease-in-out infinite;
}
.nv-orb-wrap.listening .nv-orb {
  transform: scale(1.08);
  border-color: var(--accent-purple, #6b4c9a);
  animation: nv-breathe 2.5s ease-in-out infinite;
}
.nv-orb-wrap.listening .nv-orb svg {
  color: var(--accent-purple, #6b4c9a);
  transform: scale(1.1);
}

/* Ripple rings */
.nv-ripple {
  /* Le décalage des trois anneaux est NOMMÉ, pas écrit trois fois : les ondes
     partent à 0, 600ms et 1200ms dans une boucle ambiante de 2,5s. C'est un
     décalage de scène, pas une cascade d'interface — il n'appartient donc à
     aucun barreau de --motion-*, mais il se lit à un seul endroit. */
  --nv-ripple-stagger: 600ms;
  position: absolute;
  inset: -20px;
  border-radius: 50%;
  border: 2px solid var(--brand, #1a5490);
  opacity: 0;
  transition: opacity var(--motion-enter) var(--ease-ui);
  pointer-events: none;
}
.nv-orb-wrap.listening .nv-ripple {
  opacity: 0.3;
  animation: nv-ripple-out 2.5s ease-out infinite;
}
.nv-ripple:nth-child(2) {
  inset: -40px;
  animation-delay: var(--nv-ripple-stagger) !important;
}
.nv-ripple:nth-child(3) {
  inset: -60px;
  animation-delay: calc(var(--nv-ripple-stagger) * 2) !important;
}

@keyframes nv-breathe {
  0%, 100% { transform: scale(1.08); }
  50% { transform: scale(1.12); }
}
@keyframes nv-idle-pulse {
  0%, 100% { transform: scale(1); border-color: var(--brand, #1a5490); }
  50% { transform: scale(1.04); border-color: var(--accent-purple, #6b4c9a); }
}
@keyframes nv-seed-breathe {
  0%, 100% { transform: scale(1); opacity: 0.7; }
  50% { transform: scale(1.08); opacity: 1; }
}
@keyframes nv-ripple-out {
  0% { transform: scale(0.85); opacity: 0.6; }
  100% { transform: scale(1.3); opacity: 0; }
}

/* --- Transcript: floating text ------------------------------------------- */
.nv-transcript {
  position: relative;
  max-width: 560px;
  width: 100%;
  padding: 0 clamp(20px, 5vw, 40px);
  text-align: center;
  color: var(--ink-muted, #526b78);
  font-size: 17px;
  line-height: 1.65;
  letter-spacing: -0.01em;
  min-height: 56px;
  transition: color var(--motion-enter) var(--ease-ui);
}
.nv-transcript.has-text { color: var(--ink, #173b52); }
.nv-transcript .nv-placeholder {
  color: var(--ink-muted, #526b78);
  opacity: 0.5;
  font-style: italic;
  font-size: 15px;
}
.nv-transcript .nv-response {
  display: block;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 2px solid var(--brand, #1a5490);
  color: var(--voice-accent, #6b4c9a);
  font-size: 15px;
}

/* --- Suggestions: ghost pills -------------------------------------------- */
.nv-suggestions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  max-width: 480px;
  padding: 0 clamp(20px, 5vw, 40px);
  margin-top: 24px;
}
.nv-suggestion-label {
  width: 100%;
  text-align: center;
  color: var(--ink-muted, #526b78);
  opacity: 0.6;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 4px;
}
.nv-suggestion {
  padding: 10px 16px;
  min-height: 44px;
  border-radius: var(--radius, 8px);
  border: 2px solid var(--border, #c5d8df);
  background: transparent;
  color: var(--ink-muted, #526b78);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  transition: background var(--motion-ui) var(--ease-ui),
              color var(--motion-ui) var(--ease-ui),
              border-color var(--motion-ui) var(--ease-ui);
}
.nv-suggestion:hover {
  background: var(--brand-tint, rgba(26, 84, 144, 0.08));
  color: var(--brand, #1a5490);
  border-color: var(--brand, #1a5490);
}

/* --- Mode selector: discrete pill ---------------------------------------- */
.nv-mode-pill {
  position: absolute;
  bottom: clamp(20px, 4vw, 36px);
  display: flex;
  align-items: center;
  gap: 0;
  border-radius: var(--radius, 8px);
  border: 2px solid var(--border, #c5d8df);
  background: transparent;
  overflow: hidden;
}
.nv-mode-btn {
  padding: 10px 18px;
  min-height: 44px;
  border: none;
  background: transparent;
  color: var(--ink-muted, #526b78);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--motion-ui) var(--ease-ui),
              background var(--motion-ui) var(--ease-ui);
  white-space: nowrap;
}
.nv-mode-btn:hover { color: var(--brand, #1a5490); }
.nv-mode-btn.active {
  color: var(--brand, #1a5490);
  background: transparent;
  border-bottom: 2px solid var(--brand, #1a5490);
}
.nv-mode-btn.nv-beta-toggle {
  position: relative;
}
.nv-mode-btn.nv-beta-toggle::after {
  content: '';
  position: absolute;
  top: 6px;
  right: 6px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--brand, #1a5490);
  opacity: 0;
  transition: opacity var(--motion-enter) var(--ease-ui);
}
.nv-mode-btn.nv-beta-toggle.is-beta::after { opacity: 1; }
.nv-mode-btn.nv-audio-toggle {
  padding: 10px 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.nv-mode-btn.nv-audio-toggle svg {
  width: 16px;
  height: 16px;
}
.nv-mode-btn.nv-audio-toggle.is-muted {
  color: var(--ink-muted, #526b78);
  opacity: 0.4;
}
.nv-mode-btn.nv-audio-toggle.is-muted:hover {
  color: var(--brand, #1a5490);
  opacity: 0.7;
}

/* --- Traditional mode: minimal card -------------------------------------- */
/* Traditional mode uses the same brand colors but with a lighter background
   and adjusted spacing for a more compact presentation. */
.nv-field.traditional {
  background: var(--surface, #fbfdfd);
  justify-content: flex-start;
  padding-top: clamp(60px, 12vh, 120px);
}
.nv-field.traditional::before {
  background: var(--brand-tint, rgba(26, 84, 144, 0.04));
}
.nv-field.traditional .nv-orb-wrap {
  width: 80px;
  height: 80px;
  margin-bottom: 28px;
}
.nv-field.traditional .nv-orb {
  background: var(--brand-tint, rgba(26, 84, 144, 0.08));
  border-color: var(--brand, #1a5490);
}
.nv-field.traditional .nv-orb svg {
  width: 28px;
  height: 28px;
  color: var(--brand, #1a5490);
}
.nv-field.traditional .nv-orb-wrap.listening .nv-orb {
  border-color: var(--accent-purple, #6b4c9a);
}
.nv-field.traditional .nv-orb-wrap.listening .nv-orb svg {
  color: var(--accent-purple, #6b4c9a);
}

/* --- Inline mode: embedded within components ----------------------------- */
/* Inline mode embeds the voice overlay within a pane/component.
   Used for component-level voice integration (notary workflows, etc.) */
.nv-field.inline {
  position: relative;
  inset: auto;
  z-index: 10;
  background: var(--surface, #fbfdfd);
  border: 2px solid var(--border, #c5d8df);
  border-radius: var(--radius-lg, 12px);
  padding: 24px;
  margin: 16px 0;
  min-height: 200px;
  opacity: 1;
  pointer-events: auto;
  transform: none;
}
.nv-field.inline::before {
  background: var(--brand-tint, rgba(26, 84, 144, 0.04));
  border-radius: var(--radius-lg, 12px);
}
.nv-field.inline .nv-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
}
.nv-field.inline .nv-orb-wrap {
  width: 64px;
  height: 64px;
  margin-bottom: 16px;
}
.nv-field.inline .nv-orb svg {
  width: 24px;
  height: 24px;
}
.nv-field.inline .nv-transcript {
  font-size: 15px;
  padding: 0;
}
.nv-field.inline .nv-suggestions {
  margin-top: 16px;
}
.nv-field.inline .nv-mode-pill {
  position: relative;
  bottom: auto;
  margin-top: 16px;
}

/* --- Error state --------------------------------------------------------- */
.nv-error {
  color: #e5484d !important;
  font-size: 14px !important;
}

/* --- Responsive ---------------------------------------------------------- */
@media (max-width: 600px) {
  .nv-orb-wrap { width: 96px; height: 96px; margin-bottom: 28px; }
  .nv-transcript { font-size: 15px; }
  .nv-mode-pill { bottom: 16px; }
  .nv-mode-btn { padding: 7px 14px; font-size: 11px; }
}

/* --- Reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .nv-seed, .nv-field, .nv-orb, .nv-orb svg, .nv-ripple {
    animation: none !important;
    transition-duration: 0.01ms !important;
  }
}

/* A closed voice dialog must leave the accessibility tree. */
.nv-field[hidden], .nv-confirmation[hidden] { display: none; }
.nv-orb-wrap { padding: 0; border: 0; background: transparent; cursor: pointer; }
.nv-orb-wrap:disabled { opacity: .45; cursor: default; }
.nv-orb-wrap:focus-visible { outline: 2px solid var(--ring); outline-offset: 6px; }
.nv-confirmation { max-width: 100%; text-align: center; }
.nv-proposal { overflow-wrap: anywhere; }
