/* Listening.css
   The graphics with their own colours: the recording screens (the orb on Listen, the night stage on Listening, the
   orb on Thinking) and the breathing circle on Breathe. Hushly.css keeps to the system's tokens; these graphics may use
   their own colours and sizes (the one exception to that rule). A graphic never takes a design-system colour (see
   GraphicsUseHushlyColours): the recording screens use the light show's colours below, and the Breathe circle uses
   Hushly's palette (teal, cream, ink, butter), the colours Pip and the favicon are drawn in. Only the idle orb on
   Listen is a control (it says "Tap to listen"), so it stays on the system's brand gradient and theme.
   Motion follows Settings > Motion, set on <html data-motion>: Full moves everything, Gentle only fades (slower),
   Off holds everything still. The phone's reduce-motion setting counts as Off while nothing is chosen. The canvas
   on the Listening screen (App/ListenFx.js) reads the same setting. Listening is the one screen that is dark
   whatever the theme, so a parent's eyes stay adjusted at 3 am. Nothing here is a safety screen: Help now stays a
   plain, clearly lit button on every one of them. */

/* ---------- The light show's own colours ----------
   Hushly's own, not the design system's (see GraphicsUseHushlyColours). The cyan, electric blue, violet and pink are
   the aurora's; ListenFx.js draws the same family on the canvas. The three greens are the calm ring that shows when
   "That's enough" turns on. The night colours are the stage's own sky. Every graphic here reads these, once. */

:root {
  --ls-cyan: #29d9ff;
  --ls-blue: #4f7bff;
  --ls-violet: #b06cff;
  --ls-pink: #ff78cd;
  --ls-mint: #4af0c0;
  --ls-green: #35d98f;
  --ls-lime: #9bf0a4;
  --ls-ink: #e9eeff;
  --ls-night-one: #050816;
  --ls-night-two: #0a1033;
  --ls-night-three: #131052;
  --ls-night-four: #1b0f55;
}

/* ---------- Hushly's palette, and the Breathe circle drawn in it ----------
   The same four colours as Pip and the favicon (FlatPip). The Breathe circle is a graphic, so it takes these and
   never a system colour. Day: a teal arc on a soft teal track, a pale teal orb, ink words (about 8 to 1 on the orb).
   Night: a lighter teal arc so it stays clear on the dark page, a deep teal orb mixed toward the page, cream words
   (about 8 to 1 on the orb). The pace, the sizes and the pause rules stay in Hushly.css; Breathe is not a safety screen. */

:root {
  --hu-hushlyTeal: #0f766e;
  --hu-hushlyCream: #fffdf9;
  --hu-hushlyInk: #1f3a37;
  --hu-hushlyButter: #f4c95d;
  --hu-breatheArc: var(--hu-hushlyTeal);
  --hu-breatheTrack: color-mix(in srgb, var(--hu-hushlyTeal) 22%, var(--hu-hushlyCream));
  --hu-breatheOrbFill: color-mix(in srgb, var(--hu-hushlyTeal) 30%, var(--hu-hushlyCream));
  --hu-breatheWords: var(--hu-hushlyInk);
}
:root[data-theme="dark"] {
  --hu-breatheArc: color-mix(in srgb, var(--hu-hushlyTeal) 60%, var(--hu-hushlyCream));
  --hu-breatheTrack: color-mix(in srgb, var(--hu-hushlyTeal) 40%, var(--surface));
  --hu-breatheOrbFill: color-mix(in srgb, var(--hu-hushlyTeal) 72%, var(--surface));
  --hu-breatheWords: var(--hu-hushlyCream);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --hu-breatheArc: color-mix(in srgb, var(--hu-hushlyTeal) 60%, var(--hu-hushlyCream));
    --hu-breatheTrack: color-mix(in srgb, var(--hu-hushlyTeal) 40%, var(--surface));
    --hu-breatheOrbFill: color-mix(in srgb, var(--hu-hushlyTeal) 72%, var(--surface));
    --hu-breatheWords: var(--hu-hushlyCream);
  }
}
.hu-breathe .hu-ringTrack { stroke: var(--hu-breatheTrack); }
.hu-breathe .hu-ringFill { stroke: var(--hu-breatheArc); }
.hu-breathe .hu-breatheOrb { background: var(--hu-breatheOrbFill); color: var(--hu-breatheWords); }

/* ---------- Motion switches ----------
   An animation is switched by putting its name (or none) in a variable. --hu-move (1 in Full, 0 otherwise) comes
   from Hushly.css and takes the movement out of a keyframe so Gentle fades only. */

:root {
  --ls-slow: 1;
  --ls-fade: 0.5s;
  --ls-spin: ls-spin;
  --ls-ping: ls-ping;
  --ls-glow: ls-glow;
  --ls-twinkle: ls-twinkle;
  --ls-orbit: ls-orbit;
  --ls-ripple: ls-ripple;
  --ls-lit: ls-lit;
  --ls-wake: ls-wake;
  --ls-settle: ls-settle;
  --ls-ringIn: ls-ringIn;
  --ls-dotFade: none;
}
:root[data-motion="Gentle"] {
  --ls-slow: 2;
  --ls-spin: none;
  --ls-ping: none;
  --ls-glow: ls-glowSoft;
  --ls-orbit: none;
  --ls-ripple: none;
  --ls-lit: none;
  --ls-dotFade: ls-dotFade;
}
:root[data-motion="Off"] {
  --ls-slow: 1;
  --ls-fade: 0s;
  --ls-spin: none;
  --ls-ping: none;
  --ls-glow: none;
  --ls-twinkle: none;
  --ls-orbit: none;
  --ls-ripple: none;
  --ls-lit: none;
  --ls-wake: none;
  --ls-settle: none;
  --ls-ringIn: none;
  --ls-dotFade: none;
}
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion]) {
    --ls-slow: 1;
    --ls-fade: 0s;
    --ls-spin: none;
    --ls-ping: none;
    --ls-glow: none;
    --ls-twinkle: none;
    --ls-orbit: none;
    --ls-ripple: none;
    --ls-lit: none;
    --ls-wake: none;
    --ls-settle: none;
    --ls-ringIn: none;
    --ls-dotFade: none;
  }
}

@keyframes ls-spin { to { transform: rotate(360deg); } }
/* A ring opens out from the orb and fades: the "ready when you are" cue. */
@keyframes ls-ping {
  0% { transform: scale(1); opacity: 0; }
  12% { opacity: 0.5; }
  100% { transform: scale(1.72); opacity: 0; }
}
@keyframes ls-glow {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50% { opacity: 0.95; transform: scale(calc(1 + 0.07 * var(--hu-move))); }
}
@keyframes ls-glowSoft {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.9; }
}
@keyframes ls-twinkle {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 1; }
}
@keyframes ls-orbit { to { transform: rotate(calc(var(--a) + 360deg)) translateY(calc(-1 * var(--r))); } }
@keyframes ls-dotFade {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}
@keyframes ls-ripple {
  0% { transform: scale(1); opacity: 0; }
  15% { opacity: 0.45; }
  100% { transform: scale(2.1); opacity: 0; }
}
@keyframes ls-lit {
  0% { box-shadow: 0 12px 34px -8px rgba(60, 230, 180, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 0 0 0 rgba(60, 230, 180, 0.55); }
  100% { box-shadow: 0 12px 34px -8px rgba(60, 230, 180, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 0 0 18px rgba(60, 230, 180, 0); }
}
/* The orb wakes when its screen opens: it rises a little and fades in (Gentle: the fade only, as --hu-move is 0). */
@keyframes ls-wake {
  from { opacity: 0; transform: scale(calc(1 - 0.08 * var(--hu-move))); }
}
/* On Thinking the soft blob that listened settles into a circle. */
@keyframes ls-settle {
  from {
    border-radius: calc(50% - 12% * var(--hu-move)) calc(50% + 12% * var(--hu-move)) calc(50% + 5% * var(--hu-move)) calc(50% - 5% * var(--hu-move)) / calc(50% + 2% * var(--hu-move)) calc(50% - 12% * var(--hu-move)) calc(50% + 12% * var(--hu-move)) calc(50% - 2% * var(--hu-move));
    transform: scale(calc(1 + 0.45 * var(--hu-move)));
    opacity: 0.9;
  }
}
@keyframes ls-ringIn {
  from { opacity: 0; scale: calc(1 - 0.18 * var(--hu-move)); }
}

/* ---------- The orb ----------
   One element, three looks, chosen by data-state: Idle (Listen, a big button), Listening (the transparent centre of
   the night stage) and Thinking (a calm ring). The parts are shared: a halo behind, then the core. */

.hu-orbZone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  padding-block: var(--space-4);
}
.hu-body > .hu-orbZone { margin-block: auto; }
.hu-orbStage { position: relative; display: grid; place-items: center; }
.hu-orb {
  position: relative;
  display: grid;
  place-items: center;
  border-radius: 50%;
  isolation: isolate;
  color: var(--text-on-primary);
  text-decoration: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.hu-orb.IsStatic { cursor: default; }
.hu-orb:focus-visible { outline: 2px solid var(--outline-brand-primary); outline-offset: 0.5rem; }
.hu-orbHalo { position: absolute; z-index: -2; border-radius: 50%; pointer-events: none; }

/* Idle: the big button on Listen. A disc of the brand gradient with a rotating sheen, a layered glow, and rings that
   breathe outward every few seconds. */

/* The stage takes what is left under the header and above the raised Listen circle, so the arm's length line ends above the
   circle's top on first view. On a short phone (up to 640 high) the gaps and the zone's top padding tighten too. */
.hu-orbStage--idle { inline-size: clamp(10.5rem, calc(100dvh - 26rem - var(--hu-safe-top) - var(--hu-safe-bottom)), min(18rem, 70vw)); max-inline-size: 100%; aspect-ratio: 1; }
@media (max-height: 40rem) {
  #Listen .hu-body { gap: var(--space-4); }
  #Listen .hu-orbZone { gap: var(--space-4); padding-block-start: var(--space-2); }
}
.hu-orb[data-state="Idle"] { inline-size: calc(100% * 13 / 18); aspect-ratio: 1; cursor: pointer; }
.hu-orb[data-state="Idle"] .hu-orbHalo {
  inset: -30%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--primary-gradient-stop-one) 52%, transparent), color-mix(in srgb, var(--primary-gradient-stop-two) 16%, transparent) 62%, transparent);
  opacity: 0.75;
  animation: var(--ls-glow) calc(5.5s * var(--ls-slow)) ease-in-out infinite;
}
.hu-orbRing {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--primary-gradient-stop-one) 70%, white);
  opacity: 0;
  pointer-events: none;
}
.hu-orb[data-state="Idle"] .hu-orbRing { animation: var(--ls-ping) 6.3s cubic-bezier(0.2, 0.6, 0.3, 1) infinite; }
.hu-orb[data-state="Idle"] .hu-orbRing:nth-child(3) { animation-delay: 2.1s; }
.hu-orb[data-state="Idle"] .hu-orbRing:nth-child(4) { animation-delay: 4.2s; }
.hu-orb[data-state="Idle"] .hu-orbCore {
  position: relative;
  display: grid;
  place-items: center;
  place-content: center;
  gap: var(--space-1);
  inline-size: 100%;
  block-size: 100%;
  overflow: hidden;
  border-radius: 50%;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 30, 110, 0.5), 0 1px 10px rgba(0, 50, 140, 0.5);
  /* The first layer is a deep-blue scrim behind the mic and "Tap to listen", so white reads clearly on the cyan end of
     the gradient (about 4.5 to 1 or better) while the corners keep the bright look. */
  background:
    radial-gradient(ellipse 52% 32% at 50% 52%, rgba(0, 40, 140, 0.62), rgba(0, 40, 140, 0.46) 55%, transparent),
    radial-gradient(circle at 50% 118%, rgba(0, 40, 140, 0.5), transparent 62%),
    linear-gradient(150deg, var(--primary-gradient-stop-one), var(--primary-gradient-stop-two));
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.6),
    inset 0 -22px 40px rgba(0, 40, 140, 0.28),
    0 22px 44px -12px color-mix(in srgb, var(--primary-gradient-stop-two) 70%, transparent),
    0 0 0 1px rgba(255, 255, 255, 0.18);
  transition: transform 160ms var(--hu-ease);
  animation: var(--ls-wake) 0.7s var(--hu-ease) backwards;
}
.hu-orb[data-state="Idle"] .hu-orbCore::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 30% 18%, rgba(255, 255, 255, 0.4), transparent 52%);
  pointer-events: none;
}
.hu-orb[data-state="Idle"] .hu-orbCore > :not(.hu-orbSheen) { position: relative; }
.hu-orbSheen {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  background: conic-gradient(from 0deg, transparent 0deg, transparent 210deg, rgba(255, 255, 255, 0.36) 275deg, transparent 335deg);
  -webkit-mask-image: radial-gradient(closest-side, transparent 35%, #000 92%);
  mask-image: radial-gradient(closest-side, transparent 35%, #000 92%);
  animation: var(--ls-spin) calc(14s * var(--ls-slow)) linear infinite;
}
.hu-orb[data-state="Idle"]:active .hu-orbCore { transform: scale(calc(1 - 0.04 * var(--hu-move))); }

/* Listening: the orb is the empty, transparent centre of the stage. The canvas draws the aurora over it. When the
   canvas is not drawing (motion Off, or it could not start) a still circle stands in whose brightness follows the
   level (--Level, set by Listen.js) so the parent still sees that Pip hears something. */

.hu-orb[data-state="Listening"] { z-index: 2; inline-size: 44%; aspect-ratio: 1; }
.hu-orb[data-state="Listening"] .hu-orbHalo { display: none; }
.hu-orb[data-state="Listening"] .hu-orbCore {
  inline-size: 100%;
  block-size: 100%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.9), rgba(120, 170, 255, 0.6) 45%, rgba(110, 80, 235, 0.5) 90%, rgba(195, 175, 255, 0.9) 97%, rgba(195, 175, 255, 0));
  box-shadow: 0 0 2.5rem rgba(110, 130, 255, 0.5);
  opacity: calc(0.25 + 0.75 * var(--Level, 0));
}
.hu-stage.is-fx .hu-orb[data-state="Listening"] .hu-orbCore { opacity: 0; }

/* Thinking: a smaller, calmer orb. The blob settles into a soft ring that turns slowly, three dots go round it, and Pip
   thinks in the middle. It sits on the themed page but is a graphic, so it wears the light show's colours. */

.hu-thinkStage { position: relative; display: grid; place-items: center; inline-size: 11rem; block-size: 11rem; }
.hu-orb[data-state="Thinking"] { inline-size: 100%; block-size: 100%; }
.hu-orb[data-state="Thinking"] .hu-orbHalo {
  inset: 6%;
  z-index: -1;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--ls-cyan) 38%, transparent), color-mix(in srgb, var(--ls-blue) 10%, transparent) 70%, transparent);
  animation: var(--ls-settle) 1s var(--hu-ease) backwards;
}
.hu-orb[data-state="Thinking"] .hu-orbCore {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0deg, var(--ls-cyan) 120deg, var(--ls-blue) 250deg, transparent 330deg);
  -webkit-mask-image: radial-gradient(closest-side, transparent calc(100% - 7px), #000 calc(100% - 6px));
  mask-image: radial-gradient(closest-side, transparent calc(100% - 7px), #000 calc(100% - 6px));
  animation: var(--ls-ringIn) 0.9s var(--hu-ease) backwards, var(--ls-spin) calc(12s * var(--ls-slow)) linear infinite;
}
.hu-orbDots { position: absolute; inset: 0; pointer-events: none; }
.hu-orbDot {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  inline-size: 0.55rem;
  block-size: 0.55rem;
  margin: -0.275rem;
  border-radius: 50%;
  background: var(--ls-blue);
  transform: rotate(var(--a)) translateY(calc(-1 * var(--r)));
  animation: var(--ls-orbit) var(--p) linear infinite, var(--ls-dotFade) calc(3.2s * var(--ls-slow)) ease-in-out infinite;
}
.hu-orbDot:nth-child(1) { --a: 0deg; --r: 5.3rem; --p: 7s; }
.hu-orbDot:nth-child(2) { --a: 120deg; --r: 4.3rem; --p: 5s; animation-direction: reverse, normal; animation-delay: 0s, 0.8s; inline-size: 0.45rem; block-size: 0.45rem; margin: -0.225rem; }
.hu-orbDot:nth-child(3) { --a: 240deg; --r: 3.4rem; --p: 3.8s; animation-delay: 0s, 1.6s; inline-size: 0.35rem; block-size: 0.35rem; margin: -0.175rem; }
.hu-orbPip { z-index: 1; }

/* ---------- Listening: the night stage ----------
   Deep navy to indigo whatever the theme, with a sparse field of stars that twinkle in Full and Gentle. The bar is the
   transparent immersive bar from Hushly.css and takes its ink from here. */

:root[data-screen="Listening"] { color-scheme: dark; }
#Listening {
  --hu-immersive-ink: var(--ls-ink);
  overflow: clip;
  color: var(--ls-ink);
  background:
    radial-gradient(70% 42% at 50% 40%, rgba(70, 100, 255, 0.24), transparent 72%),
    linear-gradient(180deg, var(--ls-night-one) 0%, var(--ls-night-two) 40%, var(--ls-night-three) 74%, var(--ls-night-four) 100%);
}
#Listening::before,
#Listening::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-repeat: no-repeat;
  animation: var(--ls-twinkle) calc(5s * var(--ls-slow)) ease-in-out infinite alternate;
}
#Listening::before {
  background-image:
    radial-gradient(circle 1.3px at 8% 12%, rgba(255, 255, 255, 0.9), transparent),
    radial-gradient(circle 1px at 21% 31%, rgba(255, 255, 255, 0.8), transparent),
    radial-gradient(circle 1.5px at 37% 8%, rgba(200, 220, 255, 0.9), transparent),
    radial-gradient(circle 1px at 52% 19%, rgba(255, 255, 255, 0.7), transparent),
    radial-gradient(circle 1.3px at 68% 6%, rgba(255, 255, 255, 0.85), transparent),
    radial-gradient(circle 1px at 83% 22%, rgba(210, 225, 255, 0.8), transparent),
    radial-gradient(circle 1.5px at 93% 11%, rgba(255, 255, 255, 0.9), transparent),
    radial-gradient(circle 1px at 12% 58%, rgba(255, 255, 255, 0.7), transparent),
    radial-gradient(circle 1.3px at 90% 46%, rgba(255, 255, 255, 0.8), transparent),
    radial-gradient(circle 1px at 6% 83%, rgba(220, 230, 255, 0.8), transparent),
    radial-gradient(circle 1.3px at 47% 91%, rgba(255, 255, 255, 0.75), transparent),
    radial-gradient(circle 1px at 76% 79%, rgba(255, 255, 255, 0.7), transparent);
}
#Listening::after {
  background-image:
    radial-gradient(circle 1px at 15% 20%, rgba(255, 255, 255, 0.8), transparent),
    radial-gradient(circle 1.5px at 29% 14%, rgba(255, 255, 255, 0.9), transparent),
    radial-gradient(circle 1px at 44% 28%, rgba(210, 225, 255, 0.75), transparent),
    radial-gradient(circle 1.3px at 61% 15%, rgba(255, 255, 255, 0.85), transparent),
    radial-gradient(circle 1px at 76% 33%, rgba(255, 255, 255, 0.7), transparent),
    radial-gradient(circle 1.5px at 88% 4%, rgba(200, 220, 255, 0.9), transparent),
    radial-gradient(circle 1px at 4% 41%, rgba(255, 255, 255, 0.75), transparent),
    radial-gradient(circle 1.3px at 96% 66%, rgba(255, 255, 255, 0.85), transparent),
    radial-gradient(circle 1px at 24% 74%, rgba(255, 255, 255, 0.7), transparent),
    radial-gradient(circle 1.5px at 59% 86%, rgba(210, 225, 255, 0.85), transparent),
    radial-gradient(circle 1px at 84% 93%, rgba(255, 255, 255, 0.7), transparent);
  animation-duration: calc(7.3s * var(--ls-slow));
  animation-delay: -2.4s;
  animation-direction: alternate-reverse;
}
#Listening .hu-bar { z-index: 6; }
#Listening .hu-bar .app-bar__title { text-align: center; font: var(--type-body-02-bolder); letter-spacing: 0.04em; opacity: 0.7; }
#Listening .hu-bar .app-bar__action { background: rgba(255, 255, 255, 0.08); }
#Listening .hu-bar .app-bar__action:active { background: rgba(255, 255, 255, 0.16); }
/* Help now stays a plain, clearly lit button on the dark stage: light red text on a dark pane with a red outline. */
#Listening .hu-helpBtn.btn {
  background-color: rgba(8, 12, 40, 0.55);
  box-shadow: inset 0 0 0 1px rgba(255, 150, 135, 0.7);
  color: #ffb9ad;
}
#Listening .hu-helpBtn.btn:active { background-color: rgba(60, 20, 40, 0.7); box-shadow: inset 0 0 0 1px #ffb9ad; color: #ffd6cf; }

#Listening .hu-body {
  position: relative;
  z-index: 1;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding-block: calc(var(--hu-safe-top) + var(--space-16)) var(--space-4);
  text-align: center;
}
.hu-listenTitle { margin: 0; color: rgba(233, 238, 255, 0.72); letter-spacing: 0.02em; }
.hu-stage {
  position: relative;
  display: grid;
  place-items: center;
  /* As wide as the column allows (25rem at most), and no taller than what is left once the bar, the title, the timer, the hint
     and the foot have their room, so a short phone still shows the hint above the button. */
  inline-size: clamp(11rem, calc(100dvh - 24rem - var(--hu-safe-top) - var(--hu-safe-bottom)), min(100%, 25rem));
  aspect-ratio: 1;
}
.hu-fx { position: absolute; inset: 0; z-index: 0; inline-size: 100%; block-size: 100%; pointer-events: none; }

/* The progress ring: a faint track, a gradient stroke, round caps and a glowing head where the arc ends. The head turns
   with --Progress (set by Listen.js), so it keeps pace in every motion setting. When "That's enough" turns on, the green
   stroke fades in over the blue one. Strokes are in the ring's own units (the box is 100 across). */

#Listening .hu-ring { position: absolute; inset: 0; z-index: 1; inline-size: 100%; block-size: 100%; transform: rotate(-90deg); overflow: visible; pointer-events: none; }
#Listening .hu-ringTrack { fill: none; stroke: rgba(255, 255, 255, 0.11); stroke-width: 0.55; }
#Listening .hu-ringFill {
  fill: none;
  stroke: url(#ListenRingCool);
  stroke-width: 0.85;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--Progress, 0));
}
#Listening .hu-ringFillCalm { stroke: url(#ListenRingCalm); opacity: 0; transition: opacity calc(var(--ls-fade) * 1.6) ease; }
#Listening[data-ready] .hu-ringFillCalm { opacity: 1; }
#ListenRingCool stop:nth-child(1) { stop-color: var(--ls-cyan); }
#ListenRingCool stop:nth-child(2) { stop-color: var(--ls-blue); }
#ListenRingCool stop:nth-child(3) { stop-color: var(--ls-violet); }
#ListenRingCalm stop:nth-child(1) { stop-color: var(--ls-mint); }
#ListenRingCalm stop:nth-child(2) { stop-color: var(--ls-green); }
#ListenRingCalm stop:nth-child(3) { stop-color: var(--ls-lime); }
#Listening .hu-ringHead { transform-box: view-box; transform-origin: 50% 50%; transform: rotate(calc(var(--Progress, 0) * 360deg)); }
#Listening .hu-ringHeadGlow { fill: rgba(160, 205, 255, 0.22); }
#Listening .hu-ringHeadDot { fill: #fff; }
#Listening[data-ready] .hu-ringHeadGlow { fill: rgba(150, 255, 210, 0.24); }

/* Without the canvas (motion Off, or it could not start) a few CSS ripples stand in, in Full motion only. */
.hu-ripple {
  position: absolute;
  inset: 29.5%;
  z-index: 0;
  border-radius: 50%;
  border: 2px solid rgba(130, 175, 255, 0.6);
  opacity: 0;
  pointer-events: none;
}
.hu-stage:not(.is-fx) .hu-ripple { animation: var(--ls-ripple) 2.4s linear infinite; animation-delay: 0.5s; }
.hu-stage:not(.is-fx) .hu-ripple:nth-of-type(2) { animation-delay: 1.1s; }
.hu-stage:not(.is-fx) .hu-ripple:nth-of-type(3) { animation-delay: 1.7s; }

/* The timer under the orb: big, even-width digits that glow. The hint under it fades out and in when it changes. */
.hu-listenTimer {
  margin: 0;
  font: 500 3.5rem/1 var(--font-family-base);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: #f4f7ff;
  text-shadow: 0 0 28px rgba(110, 150, 255, 0.55);
  transition: text-shadow var(--ls-fade) ease;
}
#Listening[data-ready] .hu-listenTimer { text-shadow: 0 0 28px rgba(80, 235, 180, 0.55); }
.hu-listenHint {
  margin: 0;
  min-block-size: 3em;
  max-inline-size: 22rem;
  color: rgba(233, 238, 255, 0.76);
  transition: opacity 0.18s ease;
}
.hu-listenHint.is-swapping { opacity: 0; }
:root[data-motion="Off"] .hu-listenHint { transition: none; }
@media (prefers-reduced-motion: reduce) { :root:not([data-motion]) .hu-listenHint { transition: none; } }

/* The foot: That's enough is a large pill, glass while it is not ready and lit with a gradient once it is.
   Cancel and I'm overwhelmed are light links. */
#Listening .hu-foot {
  z-index: 2;
  background: transparent;
  box-shadow: none;
}
#Listening .hu-enough.btn {
  position: relative;
  isolation: isolate;
  min-block-size: 3.5rem;
  border-radius: 999px;
  background-color: rgba(255, 255, 255, 0.08);
  background-image: none;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  color: rgba(233, 238, 255, 0.55);
  transition: color var(--ls-fade) ease, box-shadow var(--ls-fade) ease;
}
#Listening .hu-enough.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(100deg, #3be8b0, #19c3d6 55%, #4aa8ff);
  opacity: 0;
  transition: opacity var(--ls-fade) ease;
}
#Listening .hu-enough.btn:not(.is-disabled) {
  background-color: rgba(255, 255, 255, 0.08);
  box-shadow: 0 12px 34px -8px rgba(60, 230, 180, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  color: #03231d;
  animation: var(--ls-lit) 1.4s ease-out 1;
}
#Listening .hu-enough.btn:not(.is-disabled)::before { opacity: 1; }
#Listening .hu-enough.btn:active { background-color: rgba(255, 255, 255, 0.08); }
#Listening .link-btn { color: rgba(233, 238, 255, 0.82); }
#Listening .link-btn:active { color: #fff; }

/* ---------- Screen change and the orb that grows into the stage ----------
   With full motion, where the browser has view transitions, tapping the orb on Listen grows it into the Listening
   stage, and when listening ends the stage shrinks into the ring on Thinking (Listen.js starts both transitions;
   the one name, hu-orb, is only ever on one showing screen). The new screen then skips the usual slide and only fades.
   Listen.js sets html[data-handoff] while the change to Thinking runs, so a back or a tab change into Thinking
   at any other time keeps its normal motion. */

:root[data-nav] #Listening.hu-screen { animation-name: var(--hu-aFade); }
:root[data-handoff] #Thinking.hu-screen { animation-name: var(--hu-aFade); }
@supports (view-transition-name: none) {
  #Listen .hu-orb[data-state="Idle"] { view-transition-name: hu-orb; }
  #Listening .hu-stage { view-transition-name: hu-orb; }
  #Thinking .hu-thinkStage { view-transition-name: hu-orb; }
}
::view-transition-group(hu-orb) { animation-duration: 0.52s; animation-timing-function: var(--hu-ease); }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.42s; }
