  /* ================================================================
     Holographic UIX — iridescent accents over the existing crimson
     theme: checkboxes, dropdowns, nav "tabs", modal borders, buttons.
     Kept last so these rules win the cascade against the base rules
     above (identical selectors, later wins) without !important.

     Animation note: these elements are mostly thin (a 3px nav edge, a
     1px modal border) or small (a 17px checkbox). Panning/zooming a
     gradient's background-position across a thin shape only ever
     exposes one near-solid hue at a time — it reads as "still just
     red" rather than holographic. Animating `filter: hue-rotate()`
     instead keeps the gradient at its natural size (so every hue is
     visible across the shape simultaneously) and rotates all of them
     in place, which is what actually reads as an iridescent shimmer.
     ================================================================ */
  @keyframes holo-spin { to { filter: hue-rotate(360deg); } }

  /* Checkboxes — styled so any settings toggle/task option matches the
     rest of the holo theme. Radios (below) mirror this same treatment
     for whenever a single-choice control ships. */
  input[type="checkbox"] {
    -webkit-appearance: none; appearance: none;
    width: 18px; height: 18px; border-radius: 5px; flex-shrink: 0;
    background: rgba(255,255,255,0.03);
    border: 1px solid var(--border);
    position: relative;
    cursor: pointer;
    vertical-align: middle;
    transition: box-shadow 0.2s ease, border-color 0.2s ease;
  }
  input[type="checkbox"]:checked {
    border-color: transparent;
    background: var(--holo);
    animation: holo-spin 5s linear infinite;
    box-shadow: 0 0 12px -2px rgba(62,90,76,0.7);
  }
  /* A real check glyph via mask (matching icons.svg's i-check stroke path)
     instead of the old rotated-border-box trick, which drew a barely-visible,
     visibly off-center tick — inset:0 + margin:auto centers this exactly
     regardless of box size, no hand-tuned left/top offsets to get wrong. */
  input[type="checkbox"]:checked::after {
    content: "";
    position: absolute; inset: 0; margin: auto;
    width: 68%; height: 68%;
    background-color: #070605;
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12l5 5L20 6'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12l5 5L20 6'/%3E%3C/svg%3E");
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
    -webkit-mask-position: center; mask-position: center;
    -webkit-mask-size: contain; mask-size: contain;
  }
  input[type="checkbox"]:focus-visible { box-shadow: 0 0 0 3px rgba(62,90,76,0.25); }

  /* Radios — none ship in the UI yet; same shape language as the checkbox
     above (circular instead of rounded-square) so any future single-choice
     control matches on arrival. */
  input[type="radio"] {
    -webkit-appearance: none; appearance: none;
    width: 17px; height: 17px; border-radius: 50%; flex-shrink: 0;
    background: rgba(255,255,255,0.03);
    border: 1px solid var(--border);
    position: relative;
    cursor: pointer;
    vertical-align: middle;
    transition: box-shadow 0.2s ease, border-color 0.2s ease;
  }
  input[type="radio"]:checked {
    border-color: transparent;
    background: var(--holo);
    animation: holo-spin 5s linear infinite;
    box-shadow: 0 0 12px -2px rgba(62,90,76,0.7);
  }
  input[type="radio"]:checked::after {
    content: "";
    position: absolute; left: 50%; top: 50%;
    width: 6px; height: 6px; border-radius: 50%;
    background: #070605;
    transform: translate(-50%, -50%);
  }
  input[type="radio"]:focus-visible { box-shadow: 0 0 0 3px rgba(62,90,76,0.25); }

  /* Dropdowns — every <select> in the app: composer's agent picker,
     modal forms, sidebar/toolbar sort & filter pickers, the inline workspace
     status select. Previously each view rolled its own (mostly
     unstyled native chrome, cramped 3–8px padding, inconsistent
     size/radius/color) — this is the one shared look so a dropdown
     always reads as "the same kind of control" wherever it appears,
     sized for touch as well as mouse. The open popup list is native
     OS/browser chrome and can't be themed from CSS in every browser
     (esp. Firefox/Safari); dark color-scheme + option colors keep it
     dark everywhere regardless, and the holo treatment lives on the
     closed control. */
  select {
    appearance: none; -webkit-appearance: none;
    color-scheme: dark;
    font-family: inherit;
    color: var(--text);
    background-color: var(--panel-2);
    border: 1px solid rgba(85,124,104,0.3);
    border-radius: 8px;
    min-height: 40px;
    padding: 9px 34px 9px 12px;
    font-size: 13px;
    cursor: pointer;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M1 1l4 4 4-4' stroke='%23557c68' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat;
    background-position: right 12px center;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
  }
  select:hover { border-color: var(--accent-2); }
  select:focus {
    outline: none;
    border-color: var(--accent-2);
    box-shadow: 0 0 0 3px rgba(62,90,76,0.18), 0 0 16px -4px rgba(85,124,104,0.5);
  }
  select option {
    background: var(--panel-2);
    color: var(--text);
  }

  /* Compact variant — inline in dense toolbar/list rows (sort & filter
     pickers, the per-workspace-row status select) where the full 40px touch
     target would blow out row height. Still a clear step up from the
     old 3–8px-padding native controls: real padding, the same
     chevron/hover/focus treatment, just a shorter box. */
  select.select-compact {
    min-height: 32px;
    padding: 6px 28px 6px 10px;
    font-size: 12px;
    border-radius: 7px;
    background-position: right 9px center;
  }

  /* Agent badge — shown once a workspace is locked to whichever model sent
     the first message (no more switcher select at that point). Gets a
     gradient-text treatment instead of the flat gray label, same idea
     as the h1 title, so "Claude"/"Codex" reads as a small identity
     badge rather than disabled-looking metadata. */
  #agent-badge {
    border-color: rgba(85,124,104,0.35);
    font-weight: 700;
    background: linear-gradient(90deg, var(--accent), var(--accent-2) 55%, #E4DDCE);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }

  /* Log out — the same ghost-button holo tint as cancel/secondary
     buttons elsewhere, so the sidebar footer isn't the one unstyled
     corner of the app. */
  #sidebar-footer button {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
  }
  #sidebar-footer button:hover {
    border-color: var(--accent-2);
    box-shadow: 0 0 12px -4px rgba(62,90,76,0.4);
  }

  /* Sidebar top nav (Dashboard/Projects/System/Gallery/Memory/Settings) —
     the highlight is now one shared pill that glides between items (see
     .tab-indicator-vertical below and initTabIndicator in
     tab-indicator.js) instead of each item drawing its own background +
     edge line. Both of those are zeroed out here on `.active` — leaving
     either in place makes the "selected" look snap in instantly on its
     own, which visually swallows the pill's slide (it'd already look
     "arrived" well before the pill catches up). Project list rows keep
     their own per-item instant highlight below — a long, filterable,
     scrolling list isn't the same "few fixed tabs" shape as the nav
     above it. */
  #dashboard-nav, #projects-nav, #workbench-nav, #gallery-nav, #memory-nav, #knowledge-nav, #custodian-nav, #settings-nav, #system-nav, .project-item {
    position: relative;
  }
  #dashboard-nav.active, #projects-nav.active, #workbench-nav.active, #gallery-nav.active, #memory-nav.active, #knowledge-nav.active, #custodian-nav.active, #settings-nav.active {
    background: transparent;
    box-shadow: none;
  }
  /* Settings' own grouped nav (settings.js/settings.css) reuses this same
     "vertical" pill variant for its active tab — zero out its per-item
     background/box-shadow the same way, so the pill is the one thing that
     moves instead of the old highlight snapping in ahead of it. */
  .settings-nav-btn.active {
    background: transparent;
    box-shadow: none;
  }
  /* System keeps its own always-on danger tint (base #system-nav rule in
     sidebar.css) even while active — only the extra brightening step on
     top of that is dropped, so the pill stays the one moving "you're
     here" signal without erasing System's identity as a distinct zone. */
  #system-nav.active {
    background: rgba(62,90,76,0.08);
    box-shadow: none;
  }
  .project-item.active {
    box-shadow: none;
  }
  .project-item.active::before {
    content: "";
    position: absolute; left: 0; top: 4px; bottom: 4px; width: 3px;
    border-radius: 2px;
    background: linear-gradient(180deg, #3E5A4C, #6b8f7a, #9B958A, #E4DDCE, #3E5A4C);
    animation: holo-spin 5s linear infinite;
    box-shadow: 0 0 10px -1px rgba(62,90,76,0.8);
  }

  /* Sliding tab indicator — one shared element that glides to whichever
     button in a nav/tab group is currently active (initTabIndicator in
     tab-indicator.js), instead of each button's own background/underline
     just popping in and out with no motion between positions. Used by
     the sidebar's top nav, the Settings nav (also "vertical" — see
     settings.js), and the project header toolbar — not Gallery's tabs,
     which already have a dedicated tabbed layout of their own. The
     parent it's appended to must be `position: relative` and contain
     the tracked buttons as direct (or otherwise unpositioned-ancestor)
     children, since JS positions it with their offsetLeft/offsetTop.
     Three variants, chosen per group by the `variant` arg to
     initTabIndicator (not just cosmetic — it also picks which box
     dimensions JS drives, see tab-indicator.js): */
  .tab-indicator {
    position: absolute;
    left: 0; top: 0;
    pointer-events: none;
    opacity: 0;
    transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1),
                width 0.32s cubic-bezier(0.22, 1, 0.36, 1),
                height 0.32s cubic-bezier(0.22, 1, 0.36, 1),
                opacity 0.2s ease;
  }
  /* "vertical" (sidebar top nav): a full pill behind the row's own icon/
     label, sized to match the row exactly (JS drives x/y/width/height) —
     sits behind the row's content (z-index: -1; rows are
     `position: relative` with z-index: auto, which paints above
     negative-z-index siblings). */
  .tab-indicator-vertical {
    border-radius: 8px;
    background: var(--panel-2);
    box-shadow: inset 2px 0 0 var(--accent);
    z-index: -1;
  }
  /* "pill" (project header toolbar): a full glowing holographic capsule
     behind the tab label — the shifting conic-gradient ring used for
     modal borders (--holo), not just a flat tint, since this is the one
     users specifically read as "still looks like plain buttons" and
     needs to look unmistakably different from a bordered button. JS
     drives x/y/width/height to match the active tab exactly. */
  .tab-indicator-pill {
    border-radius: 20px;
    border: 1.5px solid transparent;
    background: linear-gradient(var(--panel-2), var(--panel-2)) padding-box, var(--holo) border-box;
    animation: holo-spin 5s linear infinite;
    box-shadow: 0 0 16px -3px rgba(62,90,76,0.7);
    z-index: -1;
  }
  /* "underline" (unused today, kept as a working variant — Settings used
     to be a horizontal tab strip using this before it became the grouped
     vertical nav above): a thin line pinned to the bottom edge — only
     x-position/width move (JS), height/vertical placement stay fixed
     here. */
  .tab-indicator-underline {
    bottom: -1px; height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, #3E5A4C, #6b8f7a, #9B958A, #E4DDCE, #3E5A4C);
    animation: holo-spin 5s linear infinite;
    box-shadow: 0 0 10px -1px rgba(62,90,76,0.8);
    z-index: 1;
  }
  @media (prefers-reduced-motion: reduce) {
    .tab-indicator { transition: none; }
  }

  /* Modals — animated holographic ring instead of a flat gray border.
     Warning dialogs get a crimson-only shimmer so they still read as
     "alert" rather than blending into the neutral rainbow accent. A
     conic gradient at its natural size already shows a different hue
     per edge of the card (top/right/bottom/left), so the ring reads
     as multicolor even on a single still frame. */
  .modal-card {
    border: 2px solid transparent;
    background: linear-gradient(var(--panel), var(--panel)) padding-box, var(--holo) border-box;
    animation: holo-spin 10s linear infinite;
  }
  .warn-card {
    border: 2px solid transparent;
    background: linear-gradient(var(--panel), var(--panel)) padding-box, var(--holo-warn) border-box;
    animation: holo-spin 7s linear infinite;
  }

  /* Primary/confirm buttons — full gradient fill visible at rest (not
     just revealed on hover), with a continuous shimmer. */
  .modal-card .actions .save-btn, .settings-form .save-btn,
  .warn-card .actions .confirm-btn, #composer button, #add-project-btn,
  .error-page button, #main-toolbar button.primary, .auth-card button[type="submit"],
  .gallery-panel-header button.primary, #reconnect-retry-btn,
  #work-item-toolbar button.primary, #goals-toolbar button.primary, #files-toolbar button.primary,
  #work-item-rel-add button, #status-add-form button, #create-token-form button,
  #notes-add-btn, #knowledge-add-btn, .note-form-actions button.primary, #create-guardrail-form button {
    background: linear-gradient(120deg, var(--accent), var(--accent-2) 55%, #E4DDCE);
    animation: holo-spin 6s linear infinite;
    transition: box-shadow 0.2s ease, transform 0.15s ease;
  }
  /* Note: hover can't use `filter` here — holo-spin already animates
     `filter: hue-rotate()`, and a running animation always wins over a
     plain declaration on the same property, so a hover filter would be
     silently ignored while the animation is active. */
  .modal-card .actions .save-btn:hover, .settings-form .save-btn:hover,
  .warn-card .actions .confirm-btn:hover, #composer button:not(:disabled):hover,
  #add-project-btn:hover, .error-page button:hover, #main-toolbar button.primary:hover,
  .auth-card button[type="submit"]:not(:disabled):hover,
  .gallery-panel-header button.primary:hover, #reconnect-retry-btn:hover,
  #work-item-toolbar button.primary:hover, #goals-toolbar button.primary:hover,
  #files-toolbar button.primary:not(:disabled):hover,
  #work-item-rel-add button:hover, #status-add-form button:hover, #create-token-form button:hover,
  #notes-add-btn:hover, #knowledge-add-btn:hover, .note-form-actions button.primary:hover, #create-guardrail-form button:hover {
    box-shadow: 0 6px 20px -4px rgba(62,90,76,0.65);
    transform: translateY(-1px);
  }

  /* Ghost/secondary buttons — subtle holo tint on hover */
  .modal-card .actions .cancel-btn:hover, .settings-form .secondary-btn:hover,
  .settings-form .cancel-btn:hover, .warn-card .actions .cancel-btn:hover {
    border-color: var(--accent-2);
    box-shadow: 0 0 12px -4px rgba(62,90,76,0.4);
  }

  /* Typography — the display font on the same footprint as the color
     treatment above: nav labels, modal/dialog titles, and buttons.
     Body copy, workspace messages, and logs stay on the system sans stack;
     Orbitron is dense/geometric and not meant for reading paragraphs. */
  #dashboard-nav, #gallery-nav, #settings-nav, #system-nav {
    font-family: var(--font-display);
    letter-spacing: 0.4px;
  }
  .modal-card h2, .warn-card h2, #settings-view h2 {
    font-family: var(--font-display);
    letter-spacing: 0.4px;
  }
  .modal-card .actions button, .settings-form .actions button,
  .warn-card .actions button, #composer button, #add-project-btn,
  .error-page button, #main-toolbar button.primary, .settings-nav-btn,
  .auth-card button[type="submit"], .gallery-panel-header button.primary,
  #reconnect-retry-btn, #work-item-toolbar button.primary, #goals-toolbar button.primary,
  #files-toolbar button.primary, #work-item-rel-add button, #status-add-form button,
  #create-token-form button, #notes-add-btn, #knowledge-add-btn, .note-form-actions button.primary,
  #create-guardrail-form button {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.8px;
  }

  /* Project toolbar (Workspaces/Tasks/Work Items/Status/Activity) — reads as an
     actual tab strip now, not a row of bordered buttons: each tab is flat
     (workspace.css strips its border/background), and a single glowing
     holographic pill (.tab-indicator-pill, initTabIndicator in
     tab-indicator.js) glides behind whichever one is open, growing/
     shrinking to fit its label as it moves. The active label itself gets
     the same shimmering gradient-text treatment as #agent-badge, so the
     "you are here" cue reads clearly even mid-glide. */
  .toolbar-nav-btn {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    position: relative;
    z-index: 1;
    transition: color 0.2s ease, transform 0.2s ease;
  }
  /* Scoped with the #main-toolbar parent ID — a bare `.toolbar-nav-btn.active`
     (0 IDs) loses to the existing `#main-toolbar button` rule (1 ID) for any
     shared property regardless of source order, since specificity is
     compared before position. */
  #main-toolbar .toolbar-nav-btn.active {
    background: linear-gradient(90deg, var(--accent), var(--accent-2) 55%, #E4DDCE);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    border-color: transparent;
    transform: translateY(-1px);
  }

  /* Gallery tabs — same tab language as the project toolbar/Settings
     tabs above, now that Gallery's sections switch instead of stacking. */
  .gallery-tab-btn {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    position: relative;
  }
  .gallery-tab-btn.active {
    color: var(--text);
    background: rgba(62,90,76,0.08);
  }
  .gallery-tab-btn.active::after {
    content: "";
    position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px;
    background: linear-gradient(90deg, #3E5A4C, #6b8f7a, #9B958A, #E4DDCE, #3E5A4C);
    animation: holo-spin 5s linear infinite;
    box-shadow: 0 0 10px -1px rgba(62,90,76,0.8);
  }

  /* Restart Bandua — a system-affecting action, not a normal nav
     button: amber "caution" tint distinct from the crimson brand accent
     used everywhere else, and from true-danger red — it briefly takes
     the app offline but isn't destructive. */
  /* Scoped with #main-toolbar for the same specificity reason as the
     toolbar-nav-btn.active rule above — see that comment. */
  #main-toolbar #restart-btn {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    border-color: rgba(245,184,79,0.4);
    color: var(--amber);
  }
  #main-toolbar #restart-btn:hover {
    background: rgba(245,184,79,0.12);
    border-color: var(--amber);
    color: var(--amber);
  }

  /* Unlock sudo — locked state gets the same caution tint as Restart.
     Unlocked gets a soft pulsing glow (reusing the existing green
     "unlocked" color) since "sudo is currently open" is a real
     security-relevant state worth drawing the eye to, not just a
     label change. */
  #sudo-toggle-btn {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.6px;
  }
  #sudo-toggle-btn.locked {
    border-color: rgba(245,184,79,0.35);
    color: var(--amber);
  }
  #sudo-toggle-btn.locked:hover {
    background: rgba(245,184,79,0.12);
    border-color: var(--amber);
  }
  #sudo-toggle-btn.unlocked {
    animation: sudo-glow 2.4s ease-in-out infinite;
  }
  @keyframes sudo-glow {
    0%, 100% { box-shadow: 0 0 0 rgba(62,207,142,0); }
    50% { box-shadow: 0 0 12px 1px rgba(62,207,142,0.55); }
  }
  /* At least one queued goal is sitting withheld on sudo being locked (see
     system.js's refreshSudoAttentionState) — a stronger, red pulse than the
     idle amber "locked" tint above, since this isn't just "sudo is off",
     it's "something is stuck waiting on you". Only ever applied together
     with .locked, so it wins over the amber styling above via source order. */
  #sudo-toggle-btn.locked.needs-attention {
    border-color: var(--red);
    color: var(--red);
    animation: sudo-needs-attention 1.6s ease-in-out infinite;
  }
  #sudo-toggle-btn.locked.needs-attention .icon-svg {
    color: var(--red);
  }
  @keyframes sudo-needs-attention {
    0%, 100% { box-shadow: 0 0 0 rgba(255,107,107,0); }
    50% { box-shadow: 0 0 14px 2px rgba(255,107,107,0.7); }
  }

  /* Workspace message bubbles — a static (not animated) gradient border on both
     bubble types instead of a flat var(--border) line. Static rather than
     the holo-spin shimmer used elsewhere: a workspace thread can hold hundreds of
     these, and animating a hue-rotate filter across every one of them at
     once reads as noisy rather than futuristic, and isn't free to keep
     running while scrolled off-screen. The user bubble leans crimson (this
     app's own brand accent, since it's "your" message); the assistant
     bubble spans the cooler half of the holo spectrum so the two read as
     distinct at a glance even before the alignment/color-fill difference
     registers. */
  .msg-user {
    border: 1px solid transparent;
    background:
      linear-gradient(var(--panel-2), var(--panel-2)) padding-box,
      linear-gradient(135deg, rgba(62,90,76,0.65), rgba(85,124,104,0.25)) border-box;
  }
  .msg-assistant {
    border: 1px solid transparent;
    background:
      linear-gradient(var(--panel), var(--panel)) padding-box,
      linear-gradient(135deg, rgba(228,221,206,0.45), rgba(155,149,138,0.4), rgba(62,90,76,0.4)) border-box;
    box-shadow: 0 3px 18px -10px rgba(0,0,0,0.6);
  }

  /* Links — brighter, glowing hover state so a link reads as unmistakably
     clickable instead of just slightly-differently-colored text. */
  .msg-user a, .msg-assistant a { transition: color 0.15s ease, text-shadow 0.15s ease; }
  .msg-user a:hover, .msg-assistant a:hover {
    color: #E4DDCE;
    text-shadow: 0 0 8px rgba(228,221,206,0.55);
  }

  /* Inline code + fenced code blocks — cyan-tinted "terminal" treatment
     instead of plain white-on-dark, matching the cooler half of the holo
     spectrum used on the assistant bubble border above. */
  .msg-user code, .msg-assistant code {
    background: rgba(228,221,206,0.12);
    color: #E4DDCE;
    border: 1px solid rgba(228,221,206,0.16);
  }
  .msg-user pre.msg-code, .msg-assistant pre.msg-code {
    border-color: rgba(228,221,206,0.28);
    box-shadow: inset 0 0 28px -20px rgba(228,221,206,0.7);
  }
  .msg-user pre.msg-code code, .msg-assistant pre.msg-code code {
    background: none;
    border: none;
    color: inherit;
  }
  .artifact-card {
    border-color: rgba(228,221,206,0.28);
    box-shadow: inset 0 0 28px -20px rgba(228,221,206,0.7);
  }
  .artifact-header { background: rgba(228,221,206,0.06); border-bottom-color: rgba(228,221,206,0.2); }
  .artifact-card pre.msg-code { box-shadow: none; }

  /* Blockquote — gradient left bar instead of a flat gray one. */
  .msg-user blockquote, .msg-assistant blockquote {
    border-left: 3px solid transparent;
    border-image: linear-gradient(180deg, var(--accent), #E4DDCE) 1;
    background: rgba(255,255,255,0.025);
  }

  /* Horizontal rule — gradient divider instead of a flat line. */
  .msg-user hr, .msg-assistant hr {
    height: 1px;
    border: none;
    background: linear-gradient(90deg, transparent, rgba(62,90,76,0.6), rgba(228,221,206,0.6), transparent);
  }

  /* h1/h2 inside a message reuse the same gradient-text treatment as
     #agent-badge and the thread title — h3-h6 stay plain so headings don't
     turn every subsection break into a glowing wall of text. */
  .msg-user h1, .msg-user h2, .msg-assistant h1, .msg-assistant h2 {
    background: linear-gradient(90deg, var(--accent), var(--accent-2) 55%, #E4DDCE);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }

  /* Inline images — soft glow lift on hover, echoing the link hover treatment. */
  .msg-img { transition: box-shadow 0.15s ease, transform 0.15s ease; }
  .msg-img-link:hover .msg-img {
    box-shadow: 0 0 0 1px rgba(228,221,206,0.4), 0 8px 24px -8px rgba(228,221,206,0.5);
    transform: translateY(-1px);
  }
