/* =====================================================================
   LUMI - floating study buddy
   =====================================================================
   Built entirely on the existing Aluma tokens (surfaces, accent, radii,
   spacing, type scale, motion easings) from styles.css, so Lumi inherits
   light/dark and any future palette change for free. Nothing here redefines a
   design primitive - it only composes them.
   ===================================================================== */

/* Lumi-only layout vars live on html so this sheet stays a composition
   layer after redesign.css rather than reopening the shared design-token
   block the cascade test guards against. */
html {
  --lumi-panel-w: clamp(300px, 26vw, 360px);
  --lumi-panel-gap: var(--s-3);
  /* Space reserved on the right of the app shell while Lumi is open so the
     panel docks instead of covering Home / Learn / etc. */
  --lumi-reserve: 0px;
}

/* Dock: slide the whole app left when the panel opens (desktop only).
   Reserve = panel width + its right inset + a matching left gutter so Home
   never sits flush under the panel edge. */
#app-shell {
  transition: margin-right var(--d-base) var(--ease-out);
  margin-right: var(--lumi-reserve);
  /* Keep the shell shrinkable; width:100% elsewhere would ignore the margin. */
  max-width: 100%;
  box-sizing: border-box;
}
body.lumi-open {
  --lumi-reserve: calc(var(--lumi-panel-w) + var(--lumi-panel-gap) * 2);
}

.lumi-root {
  position: fixed;
  inset: 0 0 0 auto;
  width: 0;
  height: 0;
  /* Above the page's own chrome (the mobile bottom nav is 80) but below every
     focused surface: modals (100), the assignment detail panel (320), the
     command palette and exam overlays (500), auth/paywall (1000). A floating
     helper must never cover a dialog the student has to answer. */
  z-index: 95;
  pointer-events: none;
}
.lumi-root[data-hidden="true"] { display: none; }
.lumi-root > * { pointer-events: auto; }

/* That z-index does not mean what the comment above it says, and has not since
   `#app-shell` was given `isolation: isolate`. The shell is a stacking context
   at `z-index: auto`, so every layer inside it - the modal at 100, this panel
   at 320, the palette at 500 - is sorted against its siblings and then the
   whole shell is placed as ONE box in the root context. `.lumi-root` is a
   sibling of the shell, not a child, so 95 is measured against the shell
   itself and beats everything in it. On a phone the assignment sheet fills the
   screen and the button landed on top of "Add to Test Prep".

   Moving the root inside the shell is the fix that makes 95 honest, and it is
   a change to where Lumi lives on every screen in the app. Until that is
   taken deliberately, the rule the comment above states is kept where it is
   cheap and certain: a helper that floats does not float over the sheet the
   student opened. */
body.task-detail-open .lumi-root { display: none; }

/* ── Floating button ─────────────────────────────────────────────────── */
/* Bottom-right, at every width. It used to rest 24px from the TOP-right,
   which is the corner every page header puts its main action in - so each
   header spent a 104px lane (soft.css) keeping "+ New session" out from under
   the badge, and the action never reached the corner it belongs in. A
   floating helper lives bottom-right on the phone already (below), and that
   is where students look for one. The student can still drag it up or down;
   lumi.js keeps a dragged position below the header. */
.lumi-fab {
  position: fixed;
  right: var(--s-6);
  top: auto;
  bottom: var(--s-6);
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  /* The button also carries `lumi-fab-orb`: redesign.css forces --r-md on every
     button except the ones opted out by [class*="orb"], and Lumi's button is a
     round mascot badge, not a control chip. Same exemption the app's other round
     marks use - no !important arms race. */
  border-radius: var(--r-full);
  background: var(--bg-elev-1);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-md);
  cursor: grab;
  transition: transform var(--d-base) var(--ease-out),
              box-shadow var(--d-base) var(--ease-out),
              border-color var(--d-base) var(--ease-out),
              opacity var(--d-fast) var(--ease-out),
              pointer-events var(--d-fast) var(--ease-out);
}
/* The first-visit storage notice is a bar along the bottom of the page, so
   the badge waits above it rather than on it. A phone hides the badge until
   the notice is dismissed instead (redesign.css) - no room for both there. */
@media (min-width: 901px) {
  html.has-storage-notice .lumi-fab {
    bottom: calc(var(--s-6) + var(--storage-notice-h, 64px) + var(--s-2));
  }
}
.lumi-fab:hover,
.lumi-fab:focus-visible {
  transform: translateY(-2px);
  border-color: rgb(var(--accent-rgb) / 0.55);
  box-shadow: var(--shadow-lg);
}
.lumi-fab:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 3px; }
.lumi-fab:active { transform: translateY(0) scale(0.96); }

.lumi-fab-halo {
  position: absolute;
  inset: -5px;
  border-radius: var(--r-full);
  background: var(--accent-glow);
  opacity: 0;
  transition: opacity var(--d-base) var(--ease-out);
}
.lumi-fab:hover .lumi-fab-halo { opacity: 1; }

.lumi-fab-img {
  position: relative;
  width: 52px;
  height: 48px;
  object-fit: contain;
  pointer-events: none;
  transform-origin: 60% 90%;
}

/* ── "You haven't met Lumi yet" dot ──────────────────────────────────────
   A real unread marker in the top-right of the button: it means one specific
   thing, it is cleared the first time the panel opens, and it never comes back.
   Not a permanent attention-grabber. */
.lumi-fab-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 15px;
  height: 15px;
  border-radius: var(--r-full);
  /* --accent-2 (the lime/green secondary), not the deep teal: on a white button
     the teal reads as a shadow. A notification dot has to be spotted without
     looking for it. */
  background: var(--accent-2);
  border: 2.5px solid var(--bg-elev-1);
  box-shadow: 0 0 0 1px rgb(var(--accent-2-rgb) / 0.35);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity var(--d-base) var(--ease-out), transform var(--d-base) var(--ease-spring);
  pointer-events: none;
}
.lumi-fab[data-badge="true"] .lumi-fab-badge { opacity: 1; transform: scale(1); }
/* One soft ring, not a strobe - it should read as a notification, not an alarm. */
.lumi-fab[data-badge="true"] .lumi-fab-badge::after {
  content: '';
  position: absolute;
  inset: -2.5px;
  border-radius: var(--r-full);
  border: 2px solid var(--accent-2);
  animation: lumi-badge-ring 2.4s var(--ease-out) infinite;
}
@keyframes lumi-badge-ring {
  0%        { transform: scale(1);   opacity: 0.65; }
  55%, 100% { transform: scale(2.1); opacity: 0; }
}
/* Unmet Lumi sits slightly proud of the page so the dot is noticed at all. */
.lumi-fab[data-badge="true"] { border-color: rgb(var(--accent-rgb) / 0.5); }

/* Tooltip - hover AND keyboard focus, so it isn't mouse-only. */
.lumi-tip {
  position: absolute;
  right: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%) translateX(4px);
  padding: 6px 10px;
  border-radius: var(--r-sm);
  background: var(--bg-elev-3);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
  box-shadow: var(--shadow-sm);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--d-fast) var(--ease-out), transform var(--d-fast) var(--ease-out);
}
.lumi-fab:hover .lumi-tip,
.lumi-fab:focus-visible .lumi-tip { opacity: 1; transform: translateY(-50%) translateX(0); }

/* ── The click animation: a quick happy react, then a slither to the edge.
      170ms + 250ms = 420ms end to end, under the 500ms budget. ─────────── */
@keyframes lumi-happy {
  0%   { transform: scale(1) rotate(0deg); }
  35%  { transform: scale(1.16) rotate(-8deg) translateY(-5px); }
  70%  { transform: scale(0.96) rotate(5deg) translateY(1px); }
  100% { transform: scale(1) rotate(0deg); }
}
@keyframes lumi-dash {
  0%   { transform: translateX(0) scaleX(1) rotate(0deg); opacity: 1; }
  40%  { transform: translateX(14px) scaleX(1.12) rotate(6deg); opacity: 1; }
  100% { transform: translateX(78px) scaleX(0.86) rotate(12deg); opacity: 0; }
}
.lumi-fab.is-happy .lumi-fab-img {
  animation: lumi-happy 170ms var(--ease-spring) both;
}
.lumi-fab.is-dashing .lumi-fab-img {
  animation: lumi-dash 250ms var(--ease-out) both;
}
.lumi-fab.is-dashing { box-shadow: var(--shadow-sm); }

/* Lumi has slithered into the panel - the button steps aside until it closes. */
.lumi-root[data-open="true"] .lumi-fab {
  opacity: 0;
  visibility: hidden;
  transform: translateX(20px);
  transition: opacity var(--d-fast) var(--ease-out), transform var(--d-fast) var(--ease-out),
              visibility 0s linear var(--d-fast);
}
.lumi-root[data-open="false"] .lumi-fab { transition-delay: 0s; }

/* Dragging state - remove transitions and add cursor feedback */
.lumi-fab[data-dragging="true"] {
  transition: none;
  cursor: grabbing;
  box-shadow: var(--shadow-lg);
}

/* The content-overlap fade is gone. `updateVisibility()` opened with
   `if (!btn.offsetParent) return;` and `.lumi-fab` is position:fixed with the
   viewport as its containing block, so offsetParent was always null and the
   feature never ran once. The attribute this answered is no longer written by
   anything. */

/* ── Side panel ──────────────────────────────────────────────────────── */
.lumi-panel {
  position: fixed;
  top: var(--lumi-panel-gap);
  right: var(--lumi-panel-gap);
  bottom: var(--lumi-panel-gap);
  width: var(--lumi-panel-w);
  display: flex;
  flex-direction: column;
  background: var(--bg-elev-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
  opacity: 0;
  transform: translateX(24px);
  transition: opacity var(--d-base) var(--ease-out), transform var(--d-base) var(--ease-out);
}
.lumi-panel.is-open { opacity: 1; transform: translateX(0); }
.lumi-panel[hidden] { display: none; }

.lumi-head {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: 8px 8px 8px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-elev-2);
}
.lumi-head-avatar { width: 28px; height: 28px; object-fit: contain; flex: none; }
.lumi-head-text { min-width: 0; flex: 1; }
.lumi-head-title {
  font-size: var(--fs-sm);
  font-weight: 650;
  line-height: var(--leading-tight);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lumi-head-context {
  font-size: 11px;
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lumi-icon-btn {
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  color: var(--text-muted);
  transition: background var(--d-fast) var(--ease-out), color var(--d-fast) var(--ease-out);
}
.lumi-icon-btn[hidden] { display: none; }
.lumi-icon-btn:hover { background: var(--bg-elev-3); color: var(--text); }
.lumi-icon-btn:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 1px; }

/* ── Messages ────────────────────────────────────────────────────────── */
.lumi-msgs {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.lumi-msgs:focus-visible { outline: none; }

.lumi-msg { display: flex; gap: var(--s-2); align-items: flex-start; }
.lumi-msg.lumi-user { justify-content: flex-end; }
.lumi-msg-avatar { width: 24px; height: 24px; object-fit: contain; flex: none; margin-top: 2px; }
.lumi-msg-content {
  font-size: var(--fs-sm);
  line-height: var(--leading-relaxed);
  color: var(--text);
  min-width: 0;
  overflow-wrap: anywhere;
}
.lumi-user .lumi-msg-content {
  max-width: 85%;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-md);
  background: var(--bg-elev-3);
  border: 1px solid var(--border);
}
.lumi-assistant .lumi-msg-content { flex: 1; }
.lumi-msg-content > :first-child { margin-top: 0; }
.lumi-msg-content > :last-child { margin-bottom: 0; }
.lumi-msg-content p { margin: 0 0 var(--s-2); }
.lumi-msg-content ul, .lumi-msg-content ol { margin: 0 0 var(--s-2); padding-left: var(--s-5); }
.lumi-msg-content pre {
  max-width: 100%;
  overflow-x: auto;
  padding: var(--s-2);
  border-radius: var(--r-sm);
  background: var(--bg-elev-3);
  font-size: var(--fs-xs);
}
.lumi-msg-content code { font-family: var(--font-mono); font-size: 0.92em; }
/* Tables have to survive a 380px column: scroll inside their own box rather
   than pushing the panel wide, and keep visible row rules so they still read
   as a table at this width. */
.lumi-msg-content table {
  display: block;
  overflow-x: auto;
  max-width: 100%;
  border-collapse: collapse;
  margin: 0 0 var(--s-2);
  font-size: var(--fs-xs);
}
.lumi-msg-content th,
.lumi-msg-content td {
  padding: 4px 8px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.lumi-msg-content th { color: var(--text-muted); font-weight: 650; }
.lumi-msg-content tr:last-child td { border-bottom: none; }

.lumi-streaming::after {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-left: 3px;
  border-radius: var(--r-full);
  background: var(--accent);
  animation: lumi-pulse 1s var(--ease-in-out) infinite;
  vertical-align: baseline;
}
@keyframes lumi-pulse { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }

/* ── Greeting + quick actions ────────────────────────────────────────── */
.lumi-greeting {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  background: var(--grad-soft);
  border: 1px solid var(--border);
}
.lumi-greeting-img { width: 36px; height: 34px; object-fit: contain; flex: none; }
.lumi-greeting-text {
  display: flex;
  flex-direction: column;
  gap: 0;
  font-size: var(--fs-xs);
  min-width: 0;
}
.lumi-greeting-text strong { color: var(--text); font-weight: 650; font-size: var(--fs-sm); }
.lumi-greeting-text span {
  color: var(--text-muted);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* First open only: compact chip strip of what Lumi can do (not a tall list). */
.lumi-greeting-intro { align-items: center; }
.lumi-intro-skills {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--bg-elev-2);
  animation: lumi-intro-in var(--d-slow) var(--ease-out) both;
}
@keyframes lumi-intro-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
.lumi-intro-head {
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.lumi-intro-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.lumi-intro-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 7px;
  border-radius: var(--r-sm);
  background: var(--bg-elev-1);
  border: 1px solid var(--border);
  font-size: 11px;
  font-weight: 550;
  color: var(--text);
  line-height: 1.2;
  max-width: 100%;
}
.lumi-intro-chip > [aria-hidden] { flex: none; font-size: 12px; line-height: 1; }
/* The chips are buttons now (they send their prompt), so they read as ones. */
button.lumi-intro-chip { font-family: inherit; text-align: left; cursor: pointer; }
button.lumi-intro-chip:hover { border-color: var(--border-strong, var(--border)); background: var(--bg-elev-3); }
button.lumi-intro-chip:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 1px; }
.lumi-intro-foot {
  font-size: 11px;
  color: var(--text-muted);
}

.lumi-quick-head {
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 6px;
}
.lumi-quick-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px;
}
.lumi-quick-btn {
  display: flex;
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 7px 9px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--bg-elev-2);
  transition: border-color var(--d-fast) var(--ease-out), background var(--d-fast) var(--ease-out);
  min-width: 0;
}
.lumi-quick-btn:hover { background: var(--bg-elev-3); border-color: rgb(var(--accent-rgb) / 0.45); }
.lumi-quick-btn:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 1px; }
.lumi-quick-btn[data-lumi-quick="new"],
.lumi-quick-btn[data-lumi-quick="install"],
.lumi-quick-btn.lumi-quick-resume { grid-column: 1 / -1; }
.lumi-quick-btn[data-lumi-quick="install"],
.lumi-quick-btn.lumi-quick-resume {
  background: rgb(var(--accent-rgb) / 0.08);
  border-color: rgb(var(--accent-rgb) / 0.35);
}
.lumi-quick-btn[data-lumi-quick="install"]:hover,
.lumi-quick-btn.lumi-quick-resume:hover {
  background: rgb(var(--accent-rgb) / 0.14);
  border-color: rgb(var(--accent-rgb) / 0.55);
}
.lqb-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lqb-hint { display: none; }

/* ── Tool status ─────────────────────────────────────────────────────── */
.lumi-tools {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  padding: 5px 12px;
  border-top: 1px solid var(--border);
  background: var(--bg-elev-2);
  font-size: 11px;
  color: var(--text-dim);
  min-height: 28px;
}
.lumi-tool-ico { width: 16px; height: 16px; object-fit: contain; }
.lumi-tool-label { font-weight: 600; }
.lumi-tool-chip {
  padding: 0 6px;
  border-radius: var(--r-full);
  background: var(--bg-elev-3);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 10px;
  line-height: 1.6;
}
/* Idle strip is empty chrome - hide it so the empty state fits without scroll. */
.lumi-tools[hidden] { display: none; }
.lumi-tools[data-state="idle"],
.lumi-tools[data-state=""],
.lumi-tools:not([data-state]) { display: none; }
.lumi-tools[data-state="generating"] .lumi-tool-label,
.lumi-tools[data-state="tool"] .lumi-tool-label { color: var(--accent); }
.lumi-tools[data-state="success"] .lumi-tool-label { color: var(--success); }
.lumi-tools[data-state="error"] .lumi-tool-label { color: var(--danger); }
.lumi-tools[data-state="generating"] .lumi-tool-label::after {
  content: '';
  display: inline-block;
  width: 5px; height: 5px;
  margin-left: 6px;
  border-radius: var(--r-full);
  background: currentColor;
  animation: lumi-pulse 1s var(--ease-in-out) infinite;
}

/* ── Lumi anywhere promo strip ───────────────────────────────────────── */
/* Compact dismissible banner beneath the header. Accent-tinted so it reads
   as a feature callout, not a warning or error. One time only - dismissed
   state lives in localStorage. */
.lumi-promo {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px 6px 12px;
  background: rgb(var(--accent-rgb) / 0.07);
  border-bottom: 1px solid rgb(var(--accent-rgb) / 0.22);
  font-size: 12px;
  line-height: 1.3;
  min-height: 30px;
}
.lumi-promo-ico {
  flex: none;
  color: var(--accent);
  opacity: 0.85;
}
.lumi-promo-text {
  flex: 1;
  min-width: 0;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lumi-promo-link {
  color: var(--accent);
  font-weight: 650;
  text-decoration: none;
  white-space: nowrap;
}
.lumi-promo-link:hover { text-decoration: underline; }
.lumi-promo-dismiss {
  flex: none;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  color: var(--text-dim);
  transition: background var(--d-fast) var(--ease-out), color var(--d-fast) var(--ease-out);
}
.lumi-promo-dismiss:hover { background: var(--bg-elev-3); color: var(--text); }
.lumi-promo-dismiss:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 1px; }

/* ── Composer ────────────────────────────────────────────────────────── */
.lumi-composer {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding: 8px 10px 10px;
  border-top: 1px solid var(--border);
}
.lumi-composer textarea {
  flex: 1;
  min-height: 36px;
  max-height: 120px;
  resize: none;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-strong);
  background: var(--bg-elev-2);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-sm);
  line-height: var(--leading-normal);
}
.lumi-composer textarea:focus {
  outline: none;
  border-color: var(--border-focus);
}
.lumi-composer textarea::placeholder { color: var(--text-dim); }
.lumi-send {
  flex: none;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  background: var(--accent-blue);
  color: #fff;
  transition: filter var(--d-fast) var(--ease-out);
}
.lumi-send:hover { filter: brightness(1.1); }
.lumi-send:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.lumi-send .lumi-stop-ico { display: none; }
.lumi-send.is-stopping { background: var(--danger); }
.lumi-send.is-stopping .lumi-send-ico { display: none; }
.lumi-send.is-stopping .lumi-stop-ico { display: block; }

/* ── Narrow screens: full-height sheet (no dock push - sheet owns the view) ─ */
@media (max-width: 900px) {
  body.lumi-open { --lumi-reserve: 0px; }
  .lumi-fab { right: var(--s-4); top: auto; bottom: 84px; width: 56px; height: 56px; }
  .lumi-fab-img { width: 44px; height: 41px; }
  /* The drawer hamburger floats at z-index 1002 - it would sit on top of the
     sheet's own header. The nav is one tap away again as soon as Lumi closes. */
  body.lumi-open .mobile-menu-btn { display: none; }
  body.nav-open .lumi-fab { visibility: hidden; pointer-events: none; }
  .lumi-panel {
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    width: auto;
    border-radius: 0;
    border: none;
    transform: translateY(16px);
  }
  .lumi-panel.is-open { transform: translateY(0); }
}

/* ── Reduced motion: no hop, no dash, no slide - just appear. ─────────── */
@media (prefers-reduced-motion: reduce) {
  #app-shell,
  .lumi-fab,
  .lumi-fab-img,
  .lumi-fab-halo,
  .lumi-fab-badge,
  .lumi-fab-badge::after,
  .lumi-tip,
  .lumi-panel,
  .lumi-intro-skills,
  .lumi-quick-btn,
  .lumi-icon-btn,
  .lumi-send { transition: none !important; animation: none !important; }
  /* The dot still shows - it carries information. Only the ring stops. */
  .lumi-fab[data-badge="true"] .lumi-fab-badge { opacity: 1; transform: none; }
  .lumi-fab[data-badge="true"] .lumi-fab-badge::after { display: none; }
  .lumi-fab:hover, .lumi-fab:focus-visible { transform: none; }
  .lumi-panel { transform: none; }
  .lumi-streaming::after,
  .lumi-tools[data-state="generating"] .lumi-tool-label::after { animation: none !important; }
}
