/* readaloud.css — the reader's orb (js/reader-orb.js): one tiny liquid orb
   per page with a thin progress arc on its rim and a glass keyboard button
   under it, plus the word highlight and the selection pill the reader
   drives. The orb's own look (metallic liquid plasma in silver, gold,
   platinum and the other rare metals) is drawn by js/orb.js's "mini" preset and
   glided between metals by window.OrbMetal — no hue filter on the canvas.
   everything here takes the edition
   tokens (--glow-rgb follows the mood on html[data-mood], --claret-rgb,
   --pearl-rgb) from css/kits.css. */

/* ---------- the orb ---------- */

.ra-orb {
  --ra-orb-size: 208px;
  --ra-orb-pearl: #eef0f8;
  --ra-orb-champagne: #e8cc8e;
  --ra-orb-opacity: 0.30;
  position: fixed;
  left: 0;
  top: 0;
  z-index: calc(var(--z-bar, 200) - 1);   /* over the room, under bars, drawers, menus and sheets */
  width: var(--ra-orb-size);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  /* placed by reader-orb.js: a slow wander around the measured anchor —
     above the prompt box, clear of the edge tabs, the tab bar, the safe
     area and the Voice room's orb. No CSS transition on transform: the
     wander is already smooth frame by frame (sine-driven, ~60fps) and a
     jump between obstacle-driven anchors is rare enough to read as a
     re-settle, not a snap — a transition here would only add lag chasing
     a target that is already moving. */
  transform: translate3d(var(--ra-orb-x, -400px), var(--ra-orb-y, -400px), 0);
  transition: opacity 0.6s ease, visibility 0s;
  opacity: var(--ra-orb-opacity);
  pointer-events: none;                    /* only its two hands take a press: reading text under the rest of the wander stays reachable */
  -webkit-tap-highlight-color: transparent;
}
.ra-orb[hidden] { display: none; }
.ra-orb--float:not([data-placed]) { opacity: 0; transition: none; }
.ra-orb.is-pop { z-index: var(--z-menu, 1000); }
.ra-orb.is-tucked { opacity: 0; visibility: hidden; transition: opacity 0.2s ease, visibility 0s linear 0.2s; }
.ra-orb.is-tucked * { pointer-events: none !important; }
/* the agreement's wall is a layer of its own with its own orb */
body.nda-wall-open .ra-orb--float { visibility: hidden; }

/* opacity by state — dormant / engaged / alive, ~0.6 s ease (set above);
   reader-orb.js writes data-orb-opacity, never a class per state. */
.ra-orb[data-orb-opacity="dormant"] { --ra-orb-opacity: 0.30; }
.ra-orb[data-orb-opacity="engaged"] { --ra-orb-opacity: 0.60; }
.ra-orb[data-orb-opacity="alive"] { --ra-orb-opacity: 1.00; }

/* inline: an orb in a layer of its own (the agreement's wall), in flow — it
   never wanders (no position transition to carry), but still eases opacity
   between the three states */
.ra-orb--inline {
  position: relative;
  transform: none;
  z-index: auto;
  margin: 0 auto;
  transition: opacity 0.6s ease;
}

.ra-orb-hand {
  pointer-events: auto;
  position: relative;
  width: var(--ra-orb-size);
  height: var(--ra-orb-size);
  min-width: 44px;
  min-height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  display: grid;
  place-items: center;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
.ra-orb-canvas {
  display: block;
  width: var(--ra-orb-size);
  height: var(--ra-orb-size);
  border-radius: 50%;
  pointer-events: none;
  /* no CSS transition on filter: the colour cycle and the paused dimming
     is already eased by the engine's metal clock (OrbMetal) — a CSS
     transition here would double-ease it. */
}
.ra-orb-hand:focus-visible { outline: 1.5px solid var(--ra-orb-pearl); outline-offset: 3px; }
/* the metal cycle is drawn by the engine (window.OrbMetal); the canvas
   carries no hue filter, only reader-orb.js's paused dimming. */

/* the thin progress arc on the rim, and the hold-to-stop sweep under it */
.ra-orb-arc {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  transform: rotate(-90deg);
  pointer-events: none;
}
.ra-orb-arc circle { fill: none; stroke-width: 2.2; }
.ra-orb-arc-fill {
  stroke-linecap: round;
  opacity: 0;
  transition: stroke-dashoffset 0.12s linear, opacity 0.35s ease;
}
.ra-orb:not([data-state="idle"]) .ra-orb-arc-fill { opacity: 0.95; }
.ra-orb-arc-hold {
  stroke: rgba(var(--claret-rgb, 142, 27, 46), 0.95);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-dasharray: 298.45;
  stroke-dashoffset: 298.45;
  opacity: 0;
}
.ra-orb.is-holding .ra-orb-arc-hold {
  opacity: 1;
  animation: ra-orb-hold 0.48s linear 0.12s forwards;
}
@keyframes ra-orb-hold { to { stroke-dashoffset: 0; } }

/* the keyboard button: a 32 px glass face in a 44 px hand, centred under the orb */
.ra-orb-key {
  pointer-events: auto;
  width: 44px;
  height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ra-orb-pearl);
  display: grid;
  place-items: center;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.ra-orb.no-key .ra-orb-key { display: none; }
.ra-orb-key-face {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 120% at 30% 18%, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.04) 52%, rgba(6, 12, 36, 0.30));
  border: 1px solid rgba(238, 240, 248, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 4px 14px rgba(3, 8, 30, 0.35);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  backdrop-filter: blur(10px) saturate(1.2);
  opacity: 0.86;
  transition: box-shadow 0.25s ease, border-color 0.25s ease, opacity 0.25s ease, transform 0.2s ease;
}
.ra-orb-key-glyph { width: 18px; height: 18px; }
.ra-orb-key:hover .ra-orb-key-face,
.ra-orb-key:focus-visible .ra-orb-key-face {
  opacity: 1;
  border-color: rgba(var(--glow-rgb, 52, 84, 160), 0.75);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    0 0 0 1px rgba(var(--glow-rgb, 52, 84, 160), 0.35),
    0 0 18px rgba(var(--glow-rgb, 52, 84, 160), 0.55);
}
.ra-orb-key:focus-visible { outline: none; }
.ra-orb.key-pressed .ra-orb-key-face { transform: translateY(1px); }

/* a short word beside the orb when it cannot read (a refusal, no voice) */
.ra-orb-note {
  position: absolute;
  right: calc(100% + 10px);
  top: calc(var(--ra-orb-size) / 2);
  transform: translateY(-50%);
  max-width: min(240px, 62vw);
  padding: 6px 11px;
  border-radius: 999px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12px;
  line-height: 1.3;
  color: var(--text);
  background: linear-gradient(165deg, rgba(var(--claret-rgb, 142, 27, 46), 0.22), var(--bg-elevated) 70%);
  border: 1px solid rgba(var(--claret-rgb, 142, 27, 46), 0.55);
  box-shadow: var(--shadow-md);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.ra-orb.has-note .ra-orb-note { opacity: 1; }
.ra-orb--inline .ra-orb-note { right: auto; left: calc(100% + 10px); }
.ra-orb-live {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* the popover: speed and step, on a long press at rest or a right-click */
.ra-orb-pop {
  pointer-events: auto;
  position: absolute;
  right: 0;
  bottom: calc(100% + 10px);
  transform: translateX(var(--ra-orb-pop-shift, 0px));
  width: max-content;
  min-width: 216px;
  max-width: min(300px, calc(100vw - 32px));
  box-sizing: border-box;
  padding: 12px;
  display: grid;
  gap: 12px;
  border-radius: 16px;
  color: var(--text);
  font-size: 12px;
  background: linear-gradient(165deg, rgba(var(--glow-rgb, 52, 84, 160), 0.14), var(--bg-elevated) 68%);
  border: 1px solid var(--border-strong, rgba(238, 240, 248, 0.16));
  box-shadow: var(--shadow-lg);
  -webkit-backdrop-filter: blur(16px) saturate(1.15);
  backdrop-filter: blur(16px) saturate(1.15);
}
.ra-orb-pop[hidden] { display: none; }
.ra-orb-pop.is-left { right: calc(100% + 10px); bottom: auto; top: 0; }
.ra-orb--inline .ra-orb-pop { right: auto; left: 50%; bottom: auto; top: calc(100% + 8px); transform: translateX(-50%); }
.ra-orb-pop-row { display: grid; gap: 6px; }
.ra-orb-pop-label {
  font: 600 10.5px/1 var(--font-mono, ui-monospace, monospace);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.ra-orb-seg { display: flex; flex-wrap: wrap; gap: 4px; }
.ra-orb-chip {
  min-width: 44px;
  min-height: 34px;
  padding: 0 11px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}
.ra-orb-chip:hover { border-color: var(--border-strong); }
.ra-orb-chip[aria-pressed="true"] {
  border-color: rgba(var(--pearl-rgb, 214, 203, 176), 0.8);
  background: rgba(var(--glow-rgb, 52, 84, 160), 0.22);
}
.ra-orb-chip:disabled { opacity: 0.42; cursor: default; }
.ra-orb-chip:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 1px; }
.ra-orb-seg--steps { margin-top: 2px; }
.ra-orb-pop-extra:empty { display: none; }
@media (pointer: coarse), (max-width: 480px) {
  .ra-orb-chip { min-height: 44px; }
}

/* the spacer at the end of a room's scroll box: the last words scroll clear
   of the orb where it floats over the text column (height set by measure) */
.ra-orb-spacer { flex: none; grid-column: 1 / -1; width: 1px; pointer-events: none; }

/* env() for JavaScript: reader-orb.js reads the safe-area insets off this */
.ra-orb-safe-probe {
  position: fixed;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  visibility: hidden;
  pointer-events: none;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}

:root[data-theme="light"] .ra-orb-key { color: var(--text); }
:root[data-theme="light"] .ra-orb-key-face {
  background: radial-gradient(120% 120% at 30% 18%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.55) 60%, rgba(11, 27, 63, 0.06));
  border-color: rgba(11, 27, 63, 0.18);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 4px 12px rgba(11, 27, 63, 0.12);
}
:root[data-theme="light"] .ra-orb-hand:focus-visible { outline-color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .ra-orb { transition: opacity 0.2s ease; }
  .ra-orb-key-face { transition: none; }
  .ra-orb.is-holding .ra-orb-arc-hold { animation-duration: 0.01s; animation-delay: 0.58s; }
}

/* ---------- the words ---------- */

/* Word highlight: accent-coloured letters with a soft glow, no box — the
   live word is picked out by colour and glow alone. */
.ra-word--live {
  color: var(--accent-strong);
  text-shadow: 0 0 10px rgba(var(--glow-rgb), 0.55);
  border-radius: 3px;
}
@media (prefers-reduced-motion: reduce) {
  .ra-word--live { text-shadow: none; }
}

/* Sentence karaoke (§ the agreement wall): the whole live sentence lights,
   word by word text stays readable underneath — a soft wash, not a box. */
.ra-sentence--live {
  color: var(--accent-strong);
  text-shadow: 0 0 10px rgba(var(--glow-rgb), 0.4);
  background: rgba(var(--glow-rgb), 0.08);
  border-radius: 3px;
  cursor: pointer;
}
@media (prefers-reduced-motion: reduce) {
  .ra-sentence--live { text-shadow: none; }
}

/* The selection-read-aloud pill. */
.ra-pill {
  position: fixed;
  z-index: 200;
  min-height: 36px;
  padding: 0 16px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong);
  background: linear-gradient(165deg, rgba(var(--glow-rgb), 0.14), var(--bg-elevated) 60%);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  box-shadow: var(--shadow-lg);
  backdrop-filter: blur(10px) saturate(1.1);
  cursor: pointer;
}
.ra-pill:hover { background: var(--accent-soft); }
