  :root {
    /* Aurora Spectral Palette */
    --aurora-emerald: #00ff87;
    --aurora-mint: #10e891;
    --aurora-cyan: #00f0ff;
    --aurora-teal: #06b6d4;
    --aurora-blue: #3b82f6;
    --aurora-violet: #8b5cf6;
    --aurora-purple: #a855f7;
    --aurora-magenta: #ec4899;
    --aurora-rose: #f43f5e;

    /* Master Brand Color - Arctic Cyan */
    --dc-blue: #00f0ff;
    --dc-blue-dark: color-mix(in srgb, var(--dc-blue) 70%, black);
    --dc-blue-deeper: color-mix(in srgb, var(--dc-blue) 45%, black);
    --dc-blue-light: color-mix(in srgb, var(--dc-blue) 12%, transparent);
    --dc-blue-mid: color-mix(in srgb, var(--dc-blue) 85%, white);
    --dc-blue-tint: color-mix(in srgb, var(--dc-blue) 65%, white);
    --dc-blue-tint-light: color-mix(in srgb, var(--dc-blue) 45%, white);

    /* Accents - Neon Polar Emerald & High-Altitude Violet */
    --dc-accent: #00ff87;
    --dc-accent-light: color-mix(in srgb, var(--dc-accent) 14%, transparent);
    --dc-violet: #8b5cf6;
    --dc-gold: #00ff87;
    --dc-orange: #00f0ff;
    --dc-green: #10e891;

    /* Light Mode — Glacial Dawn Aurora */
    --bg-primary: #f2faf8;
    --bg-panel: rgba(255, 255, 255, 0.88);
    --bg-secondary: #e2f5f1;
    --bg-sidebar: linear-gradient(168deg, rgba(8, 24, 38, 0.94) 0%, rgba(5, 16, 28, 0.96) 52%, rgba(10, 20, 36, 0.98) 100%);
    --text-primary: #05242b;
    --text-secondary: #0d4b52;
    --text-muted: #158288;
    --border: rgba(0, 240, 255, 0.28);
    --border-light: rgba(0, 255, 135, 0.22);
    --user-bubble: #009aa6;
    --ai-bubble: rgba(255, 255, 255, 0.92);

    --danger: #F0595B;
    --danger-tint: color-mix(in srgb, var(--danger) 12%, transparent);
    --danger-edge: color-mix(in srgb, var(--danger) 26%, transparent);
    --font-main: 'Plus Jakarta Sans', sans-serif;
    --font-mono: 'JetBrains Mono', monospace;
    --radius-sm: 9px;
    --radius-md: 15px;
    --radius-lg: 22px;
    --sidebar-w: 260px;
    --header-h: 92px;

    /* Aurora Shadows & Glows */
    --shadow-card: 0 4px 20px rgba(0, 240, 255, 0.08), 0 1px 3px rgba(0, 0, 0, 0.05);
    --shadow-input: 0 4px 24px rgba(0, 255, 135, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);

    /* Sidebar glass ink */
    --sb-text: rgba(230, 248, 255, 0.85);
    --sb-text-strong: #ffffff;
    --sb-text-dim: rgba(200, 235, 245, 0.6);
    --sb-text-faint: rgba(180, 220, 235, 0.4);
    --sb-border: rgba(0, 240, 255, 0.14);
    --sb-hover-bg: rgba(0, 240, 255, 0.09);
    --sb-accent: #00f0ff;

    --scene-dust: #00f0ff;
    --scene-gold: #00ff87;
  }

  /* Polar Midnight Aurora — deep velvet cosmic night void lit by ethereal ribbons of emerald, cyan, violet, and rose */
  [data-theme="dark"] {
    --bg-primary: #020712;
    --bg-panel: rgba(6, 16, 32, 0.76);
    --bg-secondary: rgba(10, 24, 46, 0.72);
    --bg-sidebar: linear-gradient(172deg, rgba(5, 14, 28, 0.88) 0%, rgba(3, 9, 20, 0.94) 55%, rgba(2, 6, 14, 0.98) 100%);
    --scene-dust: #00f0ff;
    --scene-gold: #00ff87;
    --text-primary: #f0fdff;
    --text-secondary: #a2e8ec;
    --text-muted: #62b5ba;
    --border: rgba(0, 240, 255, 0.18);
    --border-light: rgba(139, 92, 246, 0.16);
    --user-bubble: #00f0ff;
    --ai-bubble: rgba(8, 20, 38, 0.72);
    --dc-blue-light: rgba(0, 240, 255, 0.12);
    --dc-accent: #00ff87;
    --dc-accent-light: rgba(0, 255, 135, 0.14);
    --danger: #F0595B;
    --danger-tint: color-mix(in srgb, var(--danger) 15%, transparent);
    --danger-edge: color-mix(in srgb, var(--danger) 30%, transparent);
  }

  * { box-sizing: border-box; margin: 0; padding: 0; }

  /* Volumetric Aurora Borealis atmospheric sky glows */
  [data-theme="dark"] body {
    background:
      radial-gradient(1200px 800px at 20% -10%, rgba(0, 255, 135, 0.16), transparent 65%),
      radial-gradient(1100px 750px at 80% 0%, rgba(0, 240, 255, 0.18), transparent 60%),
      radial-gradient(950px 800px at 50% 12%, rgba(139, 92, 246, 0.16), transparent 60%),
      radial-gradient(900px 650px at 95% 60%, rgba(236, 72, 153, 0.11), transparent 55%),
      radial-gradient(850px 700px at 10% 85%, rgba(0, 240, 255, 0.1), transparent 60%),
      var(--bg-primary);
  }

  /* Glacial Dawn Aurora — daylight atmospheric glow over frosted ice */
  body {
    font-family: var(--font-main);
    background:
      radial-gradient(1200px 800px at 20% -10%, rgba(0, 255, 135, 0.14), transparent 65%),
      radial-gradient(1100px 750px at 80% 0%, rgba(0, 240, 255, 0.15), transparent 60%),
      radial-gradient(950px 800px at 50% 12%, rgba(139, 92, 246, 0.12), transparent 60%),
      radial-gradient(900px 650px at 95% 60%, rgba(236, 72, 153, 0.08), transparent 55%),
      linear-gradient(160deg, #f0fdf9 0%, #e3f8f4 40%, #eef2ff 100%),
      var(--bg-primary);
    color: var(--text-primary);
    height: 100dvh;
    display: flex;
    overflow: hidden;
    transition: background 0.3s, color 0.3s;
  }

  /* Ambient Aurora Scene Layer — waving curtain ribbons, vertical rays, and starfield */
  .bg-scene {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
    pointer-events: none;
    overflow: hidden;
  }

  /* Light mode (Glacial Dawn Aurora): soft translucent curtains */
  .bg-scene .aurora-curtain {
    mix-blend-mode: multiply;
    opacity: 0.28;
    transform-origin: 50% 20%;
  }
  .bg-scene .aurora-curtain-1 {
    animation: aurora-wave-1 20s ease-in-out infinite alternate;
  }
  .bg-scene .aurora-curtain-2 {
    animation: aurora-wave-2 15s ease-in-out infinite alternate;
  }
  .bg-scene .aurora-curtain-3 {
    animation: aurora-wave-3 12s ease-in-out infinite alternate;
  }
  .bg-scene .aurora-rays {
    mix-blend-mode: multiply;
    opacity: 0.18;
    animation: aurora-rays-shimmer 8s ease-in-out infinite alternate;
  }

  /* Dark mode (Polar Midnight Aurora): rich luminous ribbons tuned for text legibility */
  [data-theme="dark"] .bg-scene .aurora-curtain {
    mix-blend-mode: screen;
    opacity: 0.65;
  }
  [data-theme="dark"] .bg-scene .aurora-curtain-1 {
    opacity: 0.55;
  }
  [data-theme="dark"] .bg-scene .aurora-curtain-2 {
    opacity: 0.68;
  }
  [data-theme="dark"] .bg-scene .aurora-curtain-3 {
    opacity: 0.70;
  }
  [data-theme="dark"] .bg-scene .aurora-rays {
    mix-blend-mode: screen;
    opacity: 0.40;
  }

  .bg-scene .bg-stars circle {
    animation: bg-twinkle 6s ease-in-out infinite alternate;
  }
  .bg-scene .bg-stars circle:nth-child(2n) { animation-delay: -2s; animation-duration: 7.5s; }
  .bg-scene .bg-stars circle:nth-child(3n) { animation-delay: -4s; animation-duration: 9s; }
  .bg-scene .bg-stars circle:nth-child(5n) { animation-delay: -1.2s; animation-duration: 5s; }

  .bg-scene .bg-sparkle {
    animation: bg-sparkle-pulse 5s ease-in-out infinite alternate;
  }
  .bg-scene .bg-sparkle:nth-of-type(2n) { animation-delay: -2.5s; animation-duration: 6.5s; }
  .bg-scene .bg-sparkle:nth-of-type(3n) { animation-delay: -3.8s; animation-duration: 7s; }

  @keyframes aurora-wave-1 {
    0% { transform: translate(0, 0) scaleY(1) rotate(0deg); }
    50% { transform: translate(-35px, 20px) scaleY(1.12) rotate(1.2deg); }
    100% { transform: translate(30px, -15px) scaleY(0.92) rotate(-0.8deg); }
  }
  @keyframes aurora-wave-2 {
    0% { transform: translate(0, 0) scaleX(1) scaleY(1); }
    50% { transform: translate(45px, -25px) scaleX(1.06) scaleY(1.18); }
    100% { transform: translate(-30px, 15px) scaleX(0.96) scaleY(0.95); }
  }
  @keyframes aurora-wave-3 {
    0% { transform: translate(0, 0) scale(1); }
    45% { transform: translate(-25px, 30px) scale(1.08); }
    85% { transform: translate(20px, -20px) scale(0.95); }
    100% { transform: translate(0, 0) scale(1); }
  }
  @keyframes aurora-rays-shimmer {
    0%, 100% { opacity: 0.45; transform: translateY(0) scaleY(1); }
    50% { opacity: 0.85; transform: translateY(-15px) scaleY(1.1); }
  }
  @keyframes bg-sparkle-pulse {
    0%, 100% { opacity: 0.5; transform: scale(0.85); }
    50% { opacity: 1; transform: scale(1.2); }
  }
  @keyframes bg-twinkle {
    0%, 100% { opacity: 0.45; transform: translate(0, 0); }
    50% { opacity: 0.95; transform: translate(2px, -3px); }
  }

  @media (prefers-reduced-motion: reduce) {
    .bg-scene .aurora-curtain,
    .bg-scene .aurora-rays,
    .bg-scene .bg-stars circle,
    .bg-scene .bg-sparkle {
      animation: none !important;
    }
  }

  /* SIDEBAR — floats as a rounded card next to the icon rail on desktop
     (mobile keeps the old full-bleed square-cornered drawer, see below) */
  .sidebar {
    width: var(--sidebar-w);
    background: var(--bg-sidebar);
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    border: 1px solid var(--sb-border);
    border-left: none;
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
    margin: 10px 10px 10px 0;
    overflow: hidden;
    transition: transform 0.3s cubic-bezier(0.4,0,0.2,1), width 0.25s ease, margin 0.25s ease;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35), 0 0 20px rgba(0, 240, 255, 0.04);
    z-index: 100;
  }
  /* Desktop collapse: the icon-rail is the persistent nav, so the sidebar
     panel collapses away entirely instead of becoming a second icon rail */
  .sidebar.collapsed {
    width: 0;
    min-width: 0;
    margin: 10px 0;
    border: none;
    overflow: hidden;
  }
  .sidebar.collapsed .brand-text,
  .sidebar.collapsed .sidebar-collapse-btn,
  .sidebar.collapsed .sidebar-section,
  .sidebar.collapsed .history-list,
  .sidebar.collapsed .nc-label,
  .sidebar.collapsed .sidebar-wifi-status,
  .sidebar.collapsed .sidebar-wifi-ssid { display: none; }
  .sidebar.collapsed .sidebar-brand { justify-content: center; padding-left: 0; padding-right: 0; }
  .sidebar.collapsed .new-chat-btn {
    justify-content: center;
    gap: 0;
    padding-left: 0;
    padding-right: 0;
  }
  .sidebar.collapsed .sidebar-footer { padding: 10px 0; }
  .sidebar.collapsed .sidebar-wifi { margin: 0 auto; padding: 7px; width: 40px; }
  .sidebar.collapsed .sidebar-wifi-top { justify-content: center; margin-bottom: 0; gap: 0; }

  .sidebar-brand {
    padding: 18px 16px 14px;
    display: flex;
    align-items: center;
    gap: 10px;
    border-bottom: 1px solid var(--sb-border);
  }

  /* Aurora Brand Gradient — vibrant polar emerald to arctic cyan, ionosphere violet, and solar rose */
  .avatar.ai, .modal-logo, .dc-brand-gradient {
    background: linear-gradient(135deg, #00ff87 0%, #00f0ff 40%, #8b5cf6 80%, #ec4899 100%);
    box-shadow: 0 0 16px rgba(0, 255, 135, 0.35), 0 0 24px rgba(0, 240, 255, 0.2);
  }
  [data-theme="dark"] .avatar.ai,
  [data-theme="dark"] .modal-logo,
  [data-theme="dark"] .dc-brand-gradient {
    background: linear-gradient(135deg, #00ff87 0%, #00f0ff 40%, #8b5cf6 80%, #ec4899 100%);
    box-shadow: 0 0 18px rgba(0, 255, 135, 0.4), 0 0 28px rgba(0, 240, 255, 0.25);
  }

  .brand-text { flex: 1; overflow: hidden; display: flex; align-items: center; }
  .brand-wordmark { height: 22px; width: auto; max-width: 100%; object-fit: contain; }

  .new-chat-btn {
    margin: 12px 12px 8px;
    padding: 10px 14px;
    background: linear-gradient(135deg, rgba(0, 255, 135, 0.12) 0%, rgba(0, 240, 255, 0.15) 100%);
    border: 1px solid rgba(0, 240, 255, 0.35);
    border-radius: var(--radius-sm);
    color: #80f7ff;
    font-size: 12.5px;
    font-weight: 600;
    font-family: var(--font-main);
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
    transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
    letter-spacing: 0.2px;
    box-shadow: 0 2px 10px rgba(0, 240, 255, 0.08);
  }
  .new-chat-btn:hover {
    background: linear-gradient(135deg, rgba(0, 255, 135, 0.24) 0%, rgba(0, 240, 255, 0.3) 100%);
    color: #ffffff;
    border-color: #00ff87;
    box-shadow: 0 0 18px rgba(0, 255, 135, 0.35), 0 0 28px rgba(0, 240, 255, 0.25);
    transform: translateY(-1px);
  }
  .new-chat-btn svg { flex-shrink: 0; }

  .sidebar-section {
    padding: 8px 12px 4px;
    font-size: 9.5px;
    font-weight: 700;
    color: var(--sb-text-faint);
    letter-spacing: 1.2px;
    text-transform: uppercase;
  }

  .history-list {
    flex: 1;
    overflow-y: auto;
    padding: 4px 8px 8px;
  }
  .history-list::-webkit-scrollbar { width: 3px; }
  .history-list::-webkit-scrollbar-thumb { background: rgba(0, 240, 255, 0.25); border-radius: 2px; }

  .history-item {
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--sb-text);
    font-size: 12.5px;
    font-weight: 400;
    transition: all 0.2s;
    margin-bottom: 2px;
    overflow: hidden;
    user-select: none;
    border-left: 3px solid transparent;
  }
  .history-item:hover {
    background: var(--sb-hover-bg);
    color: var(--sb-text-strong);
    border-left-color: rgba(0, 240, 255, 0.3);
  }
  .history-item.active {
    background: linear-gradient(90deg, rgba(0, 240, 255, 0.18) 0%, rgba(0, 255, 135, 0.08) 100%);
    color: #ffffff;
    border-left-color: #00f0ff;
    box-shadow: inset 0 0 16px rgba(0, 240, 255, 0.12);
  }
  .history-item svg { flex-shrink: 0; opacity: 0.75; }
  .history-item-title {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 12.5px;
    line-height: 1.3;
  }
  .history-item-badge {
    flex-shrink: 0;
    font-size: 9.5px;
    font-weight: 700;
    background: rgba(255,255,255,0.14);
    color: var(--sb-text-dim);
    border-radius: 10px;
    padding: 1px 6px;
    min-width: 18px;
    text-align: center;
  }
  .history-item.active .history-item-badge {
    background: color-mix(in srgb, var(--dc-blue) 35%, transparent);
    color: color-mix(in srgb, var(--dc-blue-tint) 80%, transparent);
  }
  .history-item-delete {
    flex-shrink: 0;
    display: none;
    background: none;
    border: none;
    padding: 2px 4px;
    cursor: pointer;
    color: var(--sb-text-dim);
    border-radius: 4px;
    line-height: 1;
    transition: color 0.15s, background 0.15s;
  }
  .history-item:hover .history-item-delete { display: flex; align-items: center; }
  .history-item-delete:hover { color: #ff6b6b; background: rgba(255,107,107,0.12); }

  .sidebar-footer {
    padding: 10px 12px;
    border-top: 1px solid var(--sb-border);
  }

  .model-badge {
    background: color-mix(in srgb, var(--sb-accent) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--sb-accent) 25%, transparent);
    border-radius: 20px;
    padding: 5px 10px 5px 8px;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: var(--sb-accent);
    font-weight: 500;
  }
  .model-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--sb-accent);
    animation: pulse 2s infinite;
  }
  @keyframes pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.5; transform: scale(0.8); }
  }

  /* MAIN */
  .main {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-width: 0;
    position: relative;
  }

  /* HEADER — only shown once a conversation is active; the welcome/main
     screen stays clean with no header bar (and thus no Back button either,
     since it lives inside it). */
  /* Separated by a rule, not by a fill. Any opaque or tinted bar is a flat
     colour laid over the body's radial-gradient glow, so it reads as a block
     cut into the background with a hard edge against the sidebar. A hairline
     marks the boundary just as clearly and lets the glow run straight
     through. Nothing scrolls behind the header either — .chat-area is its
     flex sibling, not underneath it — so it needs no fill to stay legible. */
  .header {
    /* min-height, not height: while the title is being renamed the h1 wraps
       onto extra lines and the bar grows downward with it. */
    min-height: var(--header-h);
    background: rgba(245, 252, 250, 0.88);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    border-bottom: 1px solid rgba(0, 200, 210, 0.22);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
    display: flex;
    align-items: center;
    padding: 0 28px;
    gap: 18px;
    flex-shrink: 0;
  }
  [data-theme="dark"] .header {
    background: rgba(4, 12, 24, 0.75);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35), 0 1px 0 rgba(0, 240, 255, 0.08);
  }
  .main.welcome-mode .header { display: none; }

  .back-btn {
    display: flex;
    align-items: center;
    gap: 3px;
    border: none;
    background: none;
    cursor: pointer;
    padding: 7px 11px 7px 7px;
    border-radius: 8px;
    color: var(--text-secondary);
    font-family: var(--font-main);
    font-size: 13px;
    font-weight: 600;
    transition: background 0.15s, color 0.15s;
    flex-shrink: 0;
  }
  .back-btn:hover { background: var(--border-light); color: var(--text-primary); }

  .header-title {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 12px;
  }
  .header-title h1 {
    flex: 1 1 auto;
    min-width: 0;              /* lets the flex item shrink so text can wrap */
    font-size: 21px;
    font-weight: 800;
    letter-spacing: -0.3px;
    color: var(--text-primary);
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  [data-theme="dark"] .header-title h1 {
    color: #f0fdff;
    text-shadow: 0 0 16px rgba(0, 240, 255, 0.35);
  }
  /* Click-to-rename: subtle hover hint, clear focus ring while editing */
  .header-title h1[contenteditable="true"] {
    cursor: text;
    border-radius: 6px;
    padding: 2px 7px;
    margin: -2px -7px;
    outline: none;
    transition: background 0.15s;
  }
  .header-title h1[contenteditable="true"]:hover { background: var(--border-light); }
  /* While editing, a long name wraps downward inside the box instead of
     running off the header as one line. overflow-wrap: anywhere is what
     breaks an unbroken run of characters (a pasted URL, a name typed with
     no spaces); white-space: normal alone would leave it as one long word.
     Past ~3 lines the box scrolls rather than swallowing the screen. */
  .header-title h1[contenteditable="true"]:focus {
    background: var(--bg-primary);
    box-shadow: 0 0 0 2px var(--dc-blue);
    white-space: normal;
    overflow-wrap: anywhere;
    text-overflow: clip;
    overflow-y: auto;
    max-height: calc(3.6em + 8px);
  }

  .header-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
  }

  .lang-toggle-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--text-muted);
    user-select: none;
    flex-shrink: 0;
    transition: border-color 0.15s;
  }
  .lang-toggle-btn:hover { border-color: var(--dc-blue); }
  @media (max-width: 640px) { .lang-toggle-btn { display: none; } }

  .icon-btn {
    width: 34px; height: 34px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-secondary);
    transition: all 0.15s;
  }
  .icon-btn:hover { background: var(--border-light); color: var(--text-primary); }

  .status-chip {
    display: flex;
    align-items: center;
    gap: 6px;
    background: rgba(0, 255, 135, 0.12);
    border: 1px solid rgba(0, 255, 135, 0.35);
    border-radius: 20px;
    padding: 4px 11px 4px 8px;
    font-size: 11px;
    font-weight: 600;
    color: #0d4b52;
    transition: all 0.4s;
    box-shadow: 0 0 10px rgba(0, 255, 135, 0.12);
  }
  .status-chip.disconnected {
    background: rgba(240, 89, 91, 0.12);
    border-color: rgba(240, 89, 91, 0.35);
    color: #991B1B;
    box-shadow: none;
  }
  [data-theme="dark"] .status-chip {
    background: rgba(0, 255, 135, 0.14);
    border-color: rgba(0, 255, 135, 0.4);
    color: #00ff87;
    box-shadow: 0 0 14px rgba(0, 255, 135, 0.2);
  }
  [data-theme="dark"] .status-chip.disconnected {
    background: rgba(240, 89, 91, 0.16);
    border-color: rgba(240, 89, 91, 0.4);
    color: #FCA5A5;
    box-shadow: none;
  }
  .status-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: #00ff87;
    box-shadow: 0 0 8px #00ff87;
    transition: background 0.4s;
    animation: pulse 2s infinite;
  }
  .status-chip.disconnected .status-dot {
    background: #F0595B;
    box-shadow: 0 0 8px #F0595B;
    animation: none;
  }

  /* "Checking" is a genuine third state, not a flavour of offline: right after
     you pick a model nothing is known about it yet. Amber + a spinner says
     "still probing", where the red dot said "this model is dead" — which was
     a lie for the second or two a cloud endpoint takes to answer. */
  .status-chip.checking {
    background: #FFF7ED;
    border-color: #FED7AA;
    color: #9A5B0B;
  }
  [data-theme="dark"] .status-chip.checking {
    background: rgba(217,119,6,0.15);
    border-color: rgba(217,119,6,0.35);
    color: #FBBF24;
  }
  .status-chip.checking .status-dot {
    width: 9px; height: 9px;
    background: none;
    border: 1.5px solid currentColor;
    border-top-color: transparent;
    animation: spin 0.7s linear infinite;
  }

  /* WIFI BANNER */
  .wifi-banner {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 16px;
    font-size: 12px;
    font-weight: 500;
    background: #EDFAF3;
    border-bottom: 1px solid #B2E6C8;
    color: #1A7A45;
    transition: all 0.4s;
    flex-shrink: 0;
  }
  .wifi-banner.disconnected {
    background: #FFF7ED;
    border-color: #FED7AA;
    color: #92400E;
  }
  [data-theme="dark"] .wifi-banner {
    background: rgba(26,122,69,0.1);
    border-color: rgba(26,122,69,0.25);
    color: #4AE08A;
  }
  [data-theme="dark"] .wifi-banner.disconnected {
    background: rgba(146,64,14,0.12);
    border-color: rgba(146,64,14,0.3);
    color: #FBB97C;
  }
  .wifi-ssid {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.5px;
    background: rgba(0,0,0,0.07);
    padding: 1px 7px;
    border-radius: 5px;
  }
  [data-theme="dark"] .wifi-ssid { background: rgba(255,255,255,0.08); }
  .wifi-banner-right {
    margin-left: auto;
    font-size: 10.5px;
    opacity: 0.7;
    white-space: nowrap;
  }
  .wifi-bars {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 14px;
    flex-shrink: 0;
  }
  .wifi-bars span {
    display: block;
    width: 3px;
    border-radius: 1px;
    background: currentColor;
    transition: opacity 0.4s;
  }
  .wifi-bars span:nth-child(1) { height: 4px; }
  .wifi-bars span:nth-child(2) { height: 7px; }
  .wifi-bars span:nth-child(3) { height: 10px; }
  .wifi-bars span:nth-child(4) { height: 14px; }
  .wifi-banner.disconnected .wifi-bars span { opacity: 0.25; }
  .wifi-banner.disconnected .wifi-bars span:nth-child(1) { opacity: 0.6; }

  /* SIDEBAR WIFI CARD */
  .sidebar-wifi {
    margin: 8px 10px 4px;
    background: rgba(255,255,255,0.06);
    border: 1px solid var(--sb-border);
    border-radius: 12px;
    padding: 10px 12px;
    transition: all 0.4s;
  }
  .sidebar-wifi.connected {
    border-color: rgba(0, 255, 135, 0.4);
    background: rgba(0, 255, 135, 0.08);
    box-shadow: 0 0 16px rgba(0, 255, 135, 0.15);
  }
  .sidebar-wifi.disconnected {
    border-color: rgba(240, 89, 91, 0.4);
    background: rgba(240, 89, 91, 0.08);
  }
  .sidebar-wifi-top {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 7px;
  }
  .sidebar-wifi-icon {
    display: flex; align-items: center; justify-content: center;
    width: 26px; height: 26px;
    border-radius: 7px;
    background: rgba(255,255,255,0.12);
    flex-shrink: 0;
  }
  /* Now that this line names whatever endpoint is live, it can be handed a
     bare host — "generativelanguage.googleapis.com · Gemini" — so it has to be
     able to cut. min-width:0 is what lets it: without it the flex item refuses
     to shrink below its text and pushes the card wider than the sidebar. */
  .sidebar-wifi-ssid {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    font-weight: 700;
    font-family: var(--font-mono);
    color: rgba(255,255,255,0.85);
    letter-spacing: 0.3px;
  }
  .sidebar-wifi-status {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    font-weight: 600;
    margin-top: 2px;
  }
  .sidebar-wifi-status.ok { color: #00ff87; }
  .sidebar-wifi-status.err { color: #FC8181; }
  .swifi-dot {
    width: 5px; height: 5px; border-radius: 50%;
    flex-shrink: 0;
  }
  .sidebar-wifi-status.ok .swifi-dot {
    background: #00ff87;
    box-shadow: 0 0 8px #00ff87;
    animation: pulse 2s infinite;
  }
  .sidebar-wifi-status.err .swifi-dot { background: #EF4444; }
  .sidebar-wifi.checking { border-color: rgba(217,119,6,0.3); background: rgba(217,119,6,0.07); }
  .sidebar-wifi-status.checking { color: #FBBF24; }
  .sidebar-wifi-status.checking .swifi-dot {
    width: 8px; height: 8px;
    background: none;
    border: 1.5px solid currentColor;
    border-top-color: transparent;
    animation: spin 0.7s linear infinite;
  }

  /* CHAT AREA */
  .chat-area {
    flex: 1;
    overflow-y: auto;
    padding: 20px 16px;
    display: flex;
    flex-direction: column;
    gap: 16px;
  }
  .chat-area::-webkit-scrollbar { width: 4px; }
  .chat-area::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

  /* WELCOME */
  .welcome-screen {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 20px 20px 180px;
    gap: 20px;
  }

  .welcome-icon {
    width: 90px; height: 90px;
    object-fit: contain;
    flex-shrink: 0;
    filter: drop-shadow(0 0 20px rgba(0, 240, 255, 0.35)) drop-shadow(0 0 35px rgba(0, 255, 135, 0.2));
    animation: aurora-icon-pulse 6s ease-in-out infinite alternate;
  }
  @keyframes aurora-icon-pulse {
    0% { filter: drop-shadow(0 0 18px rgba(0, 240, 255, 0.35)) drop-shadow(0 0 35px rgba(139, 92, 246, 0.2)); transform: translateY(0); }
    100% { filter: drop-shadow(0 0 28px rgba(0, 255, 135, 0.5)) drop-shadow(0 0 45px rgba(0, 240, 255, 0.3)); transform: translateY(-3px); }
  }

  .welcome-hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 10px 24px;
    border-radius: 20px;
    position: relative;
  }
  [data-theme="dark"] .welcome-hero {
    background: radial-gradient(ellipse at center, rgba(2, 7, 18, 0.72) 0%, rgba(2, 7, 18, 0) 75%);
  }

  .welcome-brief {
    font-size: 12.5px;
    color: #0d555c;
    font-weight: 500;
    max-width: 480px;
    line-height: 1.5;
    letter-spacing: 0.05px;
  }
  [data-theme="dark"] .welcome-brief {
    color: #a5f3fc;
    opacity: 0.95;
    text-shadow: 0 1px 8px rgba(0, 0, 0, 0.85);
  }

  .welcome-greeting {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    font-size: 13.5px;
    color: #0d4b52;
    font-weight: 600;
    letter-spacing: 0.15px;
  }
  .welcome-greeting svg { flex-shrink: 0; color: #0284c7; }

  [data-theme="dark"] .welcome-greeting {
    color: #e2fbf7;
    text-shadow: 0 1px 8px rgba(0, 0, 0, 0.85);
  }
  [data-theme="dark"] .welcome-greeting svg {
    color: #00ff87;
    filter: drop-shadow(0 0 6px rgba(0, 255, 135, 0.6));
  }

  .welcome-title {
    font-size: 36px;
    font-weight: 800;
    letter-spacing: -0.6px;
    line-height: 1.2;
    color: #04272d;
    display: inline-block;
    text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
    transition: color 0.3s;
  }
  [data-theme="dark"] .welcome-title {
    color: #ffffff;
    text-shadow:
      0 2px 10px rgba(0, 0, 0, 0.95),
      0 0 20px rgba(0, 240, 255, 0.65),
      0 0 45px rgba(0, 255, 135, 0.35);
  }
  .welcome-sub {
    font-size: 13px;
    color: var(--text-secondary);
    max-width: 340px;
    line-height: 1.65;
  }

  /* SUGGESTION CHIPS (replaces big cards on welcome screen) */
  .suggestion-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    max-width: 640px;
  }
  .suggestion-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px;
    border: 1px solid rgba(0, 160, 180, 0.28);
    border-radius: 24px;
    background: rgba(255, 255, 255, 0.88);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    color: #042f2e;
    font-family: var(--font-main);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
    white-space: nowrap;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 180, 200, 0.1);
  }
  .suggestion-chip-icon {
    font-size: 14px;
    line-height: 1;
    display: flex;
    align-items: center;
    color: #0284c7;
  }
  .suggestion-chip:hover {
    border-color: #0284c7;
    color: #022c22;
    background: linear-gradient(135deg, rgba(0, 255, 135, 0.18) 0%, rgba(0, 240, 255, 0.25) 100%);
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(0, 180, 210, 0.25), 0 0 12px rgba(0, 255, 135, 0.15);
  }
  [data-theme="dark"] .suggestion-chip {
    background: rgba(6, 16, 34, 0.75);
    border-color: rgba(0, 240, 255, 0.28);
    color: #f0fdff;
    font-weight: 600;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.45), 0 0 12px rgba(0, 240, 255, 0.08);
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
  }
  [data-theme="dark"] .suggestion-chip .suggestion-chip-icon {
    color: #00f0ff;
  }
  [data-theme="dark"] .suggestion-chip:hover {
    border-color: #00ff87;
    color: #ffffff;
    background: linear-gradient(135deg, rgba(0, 255, 135, 0.22) 0%, rgba(0, 240, 255, 0.28) 100%);
    box-shadow: 0 6px 24px rgba(0, 255, 135, 0.35), 0 0 20px rgba(0, 240, 255, 0.3);
  }
  [data-theme="dark"] .suggestion-chip:hover .suggestion-chip-icon {
    color: #00ff87;
  }

  /* Keep old suggestion-grid for any legacy references */
  .suggestion-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 8px;
    width: 100%;
    max-width: 480px;
  }

  .suggestion-card {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 12px 13px;
    text-align: left;
    cursor: pointer;
    transition: all 0.2s;
    box-shadow: var(--shadow-card);
  }
  .suggestion-card:hover {
    border-color: var(--dc-blue);
    background: var(--dc-blue-light);
    transform: translateY(-1px);
  }
  .suggestion-card-icon {
    font-size: 18px;
    margin-bottom: 6px;
    display: block;
  }
  .suggestion-card-label {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.3;
  }
  .suggestion-card-desc {
    font-size: 10.5px;
    color: var(--text-muted);
    margin-top: 2px;
    line-height: 1.3;
  }

  /* MESSAGES */
  .message-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
  }

  /* Avatars sit at the TOP of a row, level with the first line of the message
     and with the name label above them. Bottom-aligned, a long reply parked
     the AI's face down beside the *next* prompt, which read as if the person
     below had written the answer. Both bubbles already point their sharp
     corner at that top edge. */
  .message-row {
    display: flex;
    gap: 10px;
    align-items: flex-start;
  }
  .message-row.user { flex-direction: row-reverse; }

  .avatar {
    width: 28px; height: 28px;
    border-radius: 50%;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: -0.3px;
  }
  .avatar.ai {
    color: white;
  }
  /* The participant's own face: a person glyph, not the word "You". Their own
     messages are already the ones on the right in their own colour — a text
     label there was spending the only 28px it has on something the layout
     says twice over.
     Same brand palette as the AI's fallback face, deliberately: these are the
     two speakers in one conversation, and a grey chip opposite a brand-gradient
     one read as a placeholder waiting to be filled in. What separates them is
     geometry, not hue — a rounded square instead of a circle, and a radial
     highlight off the top-right corner instead of the AI's 135° diagonal
     sweep. Distinguishable at 28px and in a thumbnail; still one family. */
  .avatar.user {
    border-radius: 9px;
    background: radial-gradient(circle at 78% 14%,
      var(--dc-gold) 0%, var(--dc-violet) 32%, var(--dc-blue) 78%);
    color: #fff;
  }
  .avatar.user svg { display: block; }
  /* An uploaded picture sits inside the avatar, so the brand gradient stays
     behind anything transparent instead of being replaced by it. */
  .avatar.ai .avatar-img {
    width: 100%; height: 100%;
    object-fit: cover;
    border-radius: 50%;
    display: block;
  }

  /* The AI's name, above its avatar. Taken out of flow on purpose: the avatar
     column has to stay exactly 28px because .bubble's
     `max-width: calc(100% - 44px)` is measured against it, so a long name must
     not be able to widen it — that would shrink every bubble in the
     conversation. Absolute positioning also keeps it out of the row's flex
     layout entirely, so no wrapper element is needed around the avatar.
     padding-top opens the band the label lives in, above both the avatar and
     the bubble. */
  .message-row.has-ident {
    position: relative;
    padding-top: 18px;   /* label is ~14px tall; the rest is its gap to the bubble */
  }
  .ai-ident-name {
    position: absolute;
    top: 0;
    left: 0;
    /* Fits the 40-char name cap on desktop, and still inside the row on a
       320px screen. Past that CSS cuts it — see the .slice note in
       aiIdentMarkup() for why this isn't done in JS. */
    max-width: 240px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 10.5px;
    font-weight: 650;
    line-height: 1.3;
    color: var(--text-muted);
  }

  .bubble {
    max-width: calc(100% - 44px);
    padding: 10px 13px;
    border-radius: 16px;
    font-size: 13.5px;
    line-height: 1.65;
    word-break: break-word;
  }

  .bubble.ai {
    background: var(--ai-bubble);
    border: 1px solid var(--border-light);
    border-radius: 4px 16px 16px 16px;
    color: var(--text-primary);
    box-shadow: var(--shadow-card);
  }

  .bubble.user {
    background: var(--user-bubble);
    color: white;
    border-radius: 16px 4px 16px 16px;
    font-weight: 500;
  }

  .bubble pre {
    background: rgba(0,0,0,0.06);
    border-radius: 6px;
    padding: 8px 10px;
    margin: 8px 0;
    overflow-x: auto;
    font-family: var(--font-mono);
    font-size: 11.5px;
    line-height: 1.5;
  }
  [data-theme="dark"] .bubble.ai pre { background: rgba(255,255,255,0.05); }
  .bubble.user pre { background: rgba(255,255,255,0.15); }

  .bubble code {
    font-family: var(--font-mono);
    font-size: 11.5px;
    background: color-mix(in srgb, var(--dc-blue) 8%, transparent);
    padding: 1px 5px;
    border-radius: 4px;
    color: var(--dc-blue);
  }
  .bubble.user code { background: rgba(255,255,255,0.2); color: white; }

  .bubble strong { font-weight: 600; }
  .bubble em { font-style: italic; }
  .bubble s { text-decoration: line-through; opacity: 0.7; }
  .bubble p { margin: 2px 0; line-height: 1.65; }
  .bubble ul, .bubble ol { padding-left: 18px; margin: 5px 0; }
  .bubble li { margin: 2px 0; line-height: 1.6; }
  .bubble h2 { font-size: 14.5px; font-weight: 700; margin: 12px 0 4px; color: var(--dc-blue); border-bottom: 1px solid var(--border-light); padding-bottom: 3px; }
  .bubble h3 { font-size: 13.5px; font-weight: 700; margin: 10px 0 3px; color: var(--dc-blue); }
  .bubble h4 { font-size: 13px; font-weight: 700; margin: 8px 0 3px; color: var(--text-secondary); }
  [data-theme="dark"] .bubble h2, [data-theme="dark"] .bubble h3 { color: var(--dc-accent); }
  .bubble hr { border: none; border-top: 1px solid var(--border-light); margin: 10px 0; }
  .bubble blockquote {
    border-left: 3px solid var(--dc-blue);
    margin: 6px 0;
    padding: 4px 12px;
    color: var(--text-secondary);
    background: var(--dc-blue-light);
    border-radius: 0 6px 6px 0;
    font-size: 13px;
  }
  [data-theme="dark"] .bubble blockquote { background: color-mix(in srgb, var(--dc-blue) 10%, transparent); }

  /* CODE BLOCK */
  .code-block {
    margin: 8px 0;
    border-radius: 10px;
    overflow: hidden;
    border: 1px solid var(--border-light);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  }
  [data-theme="dark"] .code-block {
    background: rgba(3, 9, 20, 0.88);
    border: 1px solid rgba(0, 240, 255, 0.2);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 15px rgba(0, 240, 255, 0.05);
  }
  .code-block-header {
    display: flex; align-items: center; justify-content: space-between;
    background: var(--border-light);
    border-bottom: 1px solid var(--border-light);
    padding: 3px 8px 3px 12px;
  }
  [data-theme="dark"] .code-block-header {
    background: rgba(6, 18, 36, 0.9);
    border-bottom: 1px solid rgba(0, 240, 255, 0.15);
  }
  .code-lang-label {
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 10px; font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
  }
  .code-copy-btn {
    display: inline-flex; align-items: center; gap: 4px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-muted);
    font-family: var(--font-sans, inherit);
    font-size: 11px; font-weight: 600;
    padding: 3px 7px;
    border-radius: 5px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
  }
  .code-copy-btn:hover { background: color-mix(in srgb, var(--dc-blue) 8%, transparent); color: var(--dc-blue); border-color: color-mix(in srgb, var(--dc-blue) 20%, transparent); }
  [data-theme="dark"] .code-copy-btn:hover { background: rgba(0, 240, 255, 0.12); color: var(--dc-blue); border-color: rgba(0, 240, 255, 0.25); }
  .code-copy-btn.copied { color: #00ff87; background: rgba(0, 255, 135, 0.15); border-color: rgba(0, 255, 135, 0.35); box-shadow: 0 0 10px rgba(0, 255, 135, 0.2); }
  .code-copy-btn svg { flex-shrink: 0; }
  .code-block pre { margin: 0; border-radius: 0; border: none; white-space: pre; }

  /* TABLE */
  .table-wrap { overflow-x: auto; margin: 8px 0; border-radius: 8px; border: 1px solid var(--border-light); }
  .bubble table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
  .bubble th {
    background: var(--dc-blue-light);
    color: var(--dc-blue);
    font-weight: 700;
    text-align: left;
    padding: 7px 11px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
    font-size: 12px;
  }
  .bubble td {
    padding: 6px 11px;
    border-bottom: 1px solid var(--border-light);
    vertical-align: top;
    line-height: 1.5;
  }
  .bubble tr:last-child td { border-bottom: none; }
  .bubble tbody tr:nth-child(even) td { background: rgba(0,0,0,0.02); }
  [data-theme="dark"] .bubble th { background: color-mix(in srgb, var(--dc-blue) 18%, transparent); color: var(--dc-accent); }
  [data-theme="dark"] .bubble tbody tr:nth-child(even) td { background: rgba(255,255,255,0.03); }

  /* Flex rather than a plain text line: the timestamp shares this row with the
     message's Copy / Edit / Ask again buttons, which keeps them on the 720px
     column and the 42px indent without a wrapper of their own. min-height holds
     the row at its hovered size so revealing the buttons can't shift the
     conversation above them. */
  .message-time {
    font-size: 10px;
    color: var(--text-muted);
    padding: 0 42px;
    margin-top: 2px;
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 20px;
  }
  .message-time.user { justify-content: flex-end; }

  /* MESSAGE ACTIONS — quiet until the message is hovered. The buttons are
     always in the layout, only faded, so nothing moves when they appear. */
  .msg-actions {
    display: inline-flex;
    align-items: center;
    gap: 1px;
  }
  @media (hover: hover) {
    /* The fade is on the buttons, not on the row that holds them. Opacity on a
       parent clips its children — a child cannot be more opaque than its
       parent — so fading the container would take the version switcher with it,
       and the switcher has to stay visible (see .msg-versions below). The `>`
       matters: it reaches Copy / Edit / Ask again but not the switcher's own
       arrows, which are nested one level deeper. */
    .msg-actions > .msg-action {
      opacity: 0;
      transition: opacity 0.14s ease;
    }
    /* The bubble and this row are siblings under #chat-area, so hovering the
       message reaches its actions through the adjacent-sibling combinator. */
    .message-row:hover + .message-time .msg-actions > .msg-action,
    .message-time:hover .msg-actions > .msg-action,
    .msg-actions:focus-within > .msg-action { opacity: 1; }
  }
  .msg-action {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    transition: color 0.12s, background 0.12s;
  }
  .msg-action:hover {
    color: var(--text-primary);
    background: var(--bg-secondary);
  }
  [data-theme="dark"] .msg-action:hover { background: rgba(255,255,255,0.07); }
  .msg-action.copied { color: var(--dc-green); }
  .msg-action svg { display: block; }
  /* Editing or rewinding the thread while a reply is streaming would land that
     reply on a conversation that no longer matches what it was asked. */
  body.is-generating .msg-action {
    pointer-events: none;
    opacity: 0.3;
  }

  /* PROMPT EDITOR — takes the place of the user's bubble in the same row, so
     the edited text sits exactly where the message it replaces was. */
  .prompt-edit {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 12px;
    background: var(--bg-panel);
    border: 1.5px solid var(--dc-accent);
    border-radius: 20px 4px 20px 20px;
  }
  .prompt-edit-input {
    width: 100%;
    border: none;
    outline: none;
    resize: none;
    background: transparent;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 14px;
    line-height: 1.55;
    overflow-y: auto;
  }
  .prompt-edit-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
  }
  .prompt-edit-hint {
    margin-right: auto;
    font-size: 10px;
    color: var(--text-muted);
  }
  .prompt-edit-btn {
    font-family: inherit;
    font-size: 12px;
    padding: 5px 12px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: color 0.12s, border-color 0.12s, background 0.12s;
  }
  .prompt-edit-btn:hover { color: var(--text-primary); border-color: var(--text-muted); }
  .prompt-edit-btn.primary {
    background: var(--dc-accent);
    border-color: var(--dc-accent);
    color: #fff;
  }
  .prompt-edit-btn.primary:hover { filter: brightness(1.08); color: #fff; }

  /* VERSION SWITCHER — `‹ 2/3 ›`, on the prompt for wordings and on the answer
     for re-rolls. Unlike its neighbours this is never hidden: a count is state,
     not an offered action, and a version nobody can see they have is a version
     they lose. It carries the muted colour of the timestamp it sits beside. */
  .msg-versions {
    display: inline-flex;
    align-items: center;
    gap: 1px;
  }
  .msg-version-count {
    font-variant-numeric: tabular-nums;   /* 1/2 → 2/2 must not shift width */
    font-size: 10px;
    color: var(--text-muted);
    padding: 0 1px;
  }
  .msg-action.msg-version-step { width: 16px; height: 20px; border-radius: 4px; }
  .msg-action:disabled {
    opacity: 0.3;
    pointer-events: none;
  }

  /* THINKING INDICATOR — expandable agent trace.
     The header is a quiet button; everything below it hangs off a single
     hairline rail, so the trace reads as one thread of work rather than a
     stack of boxes. Collapse uses the 1fr→0fr grid trick so the height
     animates without measuring anything in JS. */
  @keyframes spin { to { transform: rotate(360deg); } }
  @keyframes shimmer-text { to { background-position: -200% 0; } }
  @keyframes fade-up {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
  }

  .thinking-bubble {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    padding: 9px 13px 11px;
    min-width: 268px;
  }
  .thinking-top-row {
    display: flex;
    align-items: center;
    gap: 8px;
    width: calc(100% + 12px);
    margin: -3px -6px 0;
    padding: 4px 6px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    user-select: none;
    transition: background 0.1s ease;
  }
  .thinking-top-row:hover { background: var(--border-light); }
  .thinking-sparkle {
    flex-shrink: 0;
    color: var(--text-secondary);
    display: flex;
  }
  .thinking-top-chevron {
    display: flex;
    flex-shrink: 0;
    color: var(--text-muted);
    transform: rotate(180deg);   /* the trace starts expanded */
    transition: transform 0.3s ease;
  }
  .thinking-top-row.collapsed .thinking-top-chevron { transform: rotate(0deg); }
  /* Shimmer sweeps across the label instead of the old trailing "...", so the
     header stays one stable width while the model works. */
  .thinking-label {
    font-size: 13px;
    font-weight: 500;
    font-style: normal;
    white-space: nowrap;
    background-image: linear-gradient(90deg,
      #00ff87 25%, #00f0ff 50%, #a78bfa 75%);
    background-size: 200% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    animation: shimmer-text 1.4s linear infinite;
  }
  /* Work is over — the sweep stops and the label states the total. */
  .thinking-label.settled {
    background-image: none;
    -webkit-background-clip: border-box;
    background-clip: border-box;
    color: var(--text-secondary);
    animation: fade-in 350ms ease-out both;
  }
  .thinking-model-tag {
    font-size: 10.5px;
    font-family: var(--font-mono);
    color: var(--text-muted);
    margin-left: auto;
    padding-left: 10px;
    font-style: normal;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 45%;
  }

  .thinking-collapsible {
    display: grid;
    grid-template-rows: 1fr;
    opacity: 1;
    width: 100%;
    transition: grid-template-rows 0.4s cubic-bezier(0.23, 1, 0.32, 1),
                opacity 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  }
  .thinking-collapsible.hidden { grid-template-rows: 0fr; opacity: 0; }
  .thinking-clip { overflow: hidden; }
  /* The rail is positioned rather than measured — top/bottom insets let it
     grow with the trace for free as steps stream in. */
  .thinking-trace {
    position: relative;
    margin: 4px 0 0 5px;
    padding-left: 16px;
  }
  .thinking-trace::before {
    content: '';
    position: absolute;
    left: 0;
    top: -4px;
    bottom: 8px;
    width: 1px;
    background: var(--border);
  }

  .thinking-steps-section { margin-top: 8px; }
  .thinking-steps-section.hidden { display: none; }
  .thinking-steps-label {
    font-size: 10px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    padding-left: 6px;
    margin-bottom: 3px;
  }
  .thinking-steps-list {
    display: flex;
    flex-direction: column;
    gap: 1px;
  }
  /* A row is icon → what happened → what it cost. The primary text truncates
     so the measurement on the right is never the thing that gets cut off. */
  .thinking-step {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 26px;
    padding: 2px 6px;
    border-radius: 6px;
    font-size: 12.5px;
    line-height: 1.35;
    color: var(--text-primary);
    font-weight: 500;
    text-decoration: none;
    animation: fade-up 320ms cubic-bezier(0.23, 1, 0.32, 1) both;
  }
  .thinking-step.step-done { color: var(--text-secondary); }
  .thinking-step.step-error { color: var(--danger); }

  /* Retrieved chunks of a single file: indented under the row naming that file,
     with a quiet tick instead of a source dot. They are parts of one thing, and
     giving each the same marker a whole source gets is what made three chunks of
     one PDF read as three documents. */
  .thinking-step.kind-chunk {
    min-height: 22px;
    padding-left: 22px;
    font-size: 12px;
    font-weight: 400;
    color: var(--text-muted);
  }
  .chunk-tick {
    display: block;
    width: 7px;
    height: 2px;
    border-radius: 1px;
    background: var(--border);
  }
  .thinking-step.kind-chunk .step-meta { color: var(--text-muted); }
  .step-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .step-meta {
    flex-shrink: 0;
    font-size: 11.5px;
    font-weight: 400;
    color: var(--text-muted);
    white-space: nowrap;
  }
  .step-icon {
    width: 14px;
    height: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--text-muted);
  }
  .thinking-step.step-error .step-icon { color: var(--danger); }
  .step-mini-spinner {
    width: 12px; height: 12px;
    border-radius: 50%;
    border: 1.5px solid var(--border);
    border-top-color: var(--text-secondary);
    animation: spin 700ms linear infinite;
    display: inline-block;
  }

  /* SEARCH ROWS — the query that was sent, then the pages it came back with.
     Sources are real links: the trace is only worth showing if the student can
     go read what the model was fed. */
  .thinking-step.kind-query { color: var(--text-secondary); font-weight: 400; }
  .thinking-step.kind-source {
    color: var(--text-primary);
    transition: background 0.15s ease;
  }
  .thinking-step.kind-source:hover { background: var(--border-light); }
  .thinking-step.kind-source:hover .step-text { text-decoration: underline; }
  /* Three near-identical rows of blue link text are unscannable — a coloured
     dot per source gives the eye something to sort on. */
  .src-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    flex-shrink: 0;
  }
  .thinking-step.kind-more {
    display: block;
    padding-left: 28px;
    font-size: 12px;
    font-weight: 400;
    color: var(--text-muted);
    min-height: 0;
  }

  /* EDUCATIONAL CARD inside thinking bubble — kept, but demoted to an inset
     panel on the rail so it supports the trace instead of competing with it. */
  .thinking-edu-card {
    background: color-mix(in srgb, var(--dc-blue) 5%, transparent);
    border: 1px solid var(--border-light);
    border-radius: 10px;
    width: 100%;
    box-sizing: border-box;
    overflow: hidden;
    transition: opacity 0.25s ease;
  }
  [data-theme="dark"] .thinking-edu-card { background: rgba(255,255,255,0.035); }
  .thinking-edu-body {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    padding: 9px 11px 8px;
  }
  .thinking-edu-icon {
    display: flex;
    flex-shrink: 0;
    margin-top: 1px;
    color: var(--text-muted);
  }
  .thinking-edu-text {
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.6;
    font-style: normal;
  }
  .thinking-edu-footer {
    border-top: 1px solid var(--border-light);
    padding: 6px 7px 7px;
  }
  .thinking-edu-footer-label {
    display: block;
    font-size: 10px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    margin: 0 0 3px 4px;
  }
  .thinking-edu-links {
    display: flex;
    flex-wrap: wrap;
    gap: 1px;
  }
  .thinking-edu-links a {
    font-size: 11.5px;
    color: var(--text-secondary);
    text-decoration: none;
    border-radius: 6px;
    padding: 3px 6px;
    font-weight: 500;
    transition: background 0.12s ease, color 0.12s ease;
  }
  .thinking-edu-links a:hover { background: var(--border-light); color: var(--text-primary); }

  /* SETTLED TRACE — the same trace, once the answer exists. It moves inside the
     bubble and folds shut, so the record of the work sits with the work rather
     than vanishing the moment it becomes checkable. */
  .process-trace {
    width: 100%;
    margin-bottom: 8px;
  }
  .process-trace .thinking-top-row {
    width: calc(100% + 12px);
    margin: -2px -6px 0;
  }
  .process-trace .thinking-trace { margin-top: 2px; }
  .process-trace:not(.live) .thinking-steps-section.hidden { display: block; }

  /* THINK BLOCK — the model's own reasoning. Same language as the trace above
     it: sparkle, shimmer while it runs, settled label, prose on the rail. */
  .think-block { margin-bottom: 10px; }
  .think-block-header {
    display: flex;
    align-items: center;
    gap: 8px;
    width: calc(100% + 12px);
    margin: 0 -6px;
    padding: 4px 6px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    user-select: none;
    transition: background 0.1s ease;
  }
  .think-block-header:hover { background: var(--border-light); }
  .think-header-label {
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
    background-image: linear-gradient(90deg,
      var(--text-muted) 35%, var(--text-primary) 50%, var(--text-muted) 65%);
    background-size: 200% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    animation: shimmer-text 1.4s linear infinite;
  }
  .think-header-label.settled {
    background-image: none;
    -webkit-background-clip: border-box;
    background-clip: border-box;
    color: var(--text-secondary);
    animation: fade-in 350ms ease-out both;
  }
  .think-block-chevron {
    display: flex;
    flex-shrink: 0;
    margin-left: auto;
    color: var(--text-muted);
    transition: transform 0.3s ease;
  }
  .think-block-header.open .think-block-chevron { transform: rotate(180deg); }
  /* The rail is a border, not a pseudo-element: this box scrolls, and an
     absolutely-positioned rail would scroll away with the text. */
  .think-block-body {
    margin: 4px 0 0 5px;
    padding: 2px 0 2px 16px;
    border-left: 1px solid var(--border);
    font-size: 11.5px;
    color: var(--text-secondary);
    white-space: pre-wrap;
    max-height: 240px;
    overflow-y: auto;
    line-height: 1.7;
  }
  .think-block-body.hidden { display: none; }

  /* MESSAGE METADATA */
  .msg-meta {
    font-size: 10px;
    color: var(--text-muted);
    padding: 3px 42px 0;
    letter-spacing: 0.1px;
    display: flex;
    gap: 0;
    align-items: center;
  }
  .msg-meta-dot {
    margin: 0 5px;
    opacity: 0.45;
  }

  /* CLICKABLE MESSAGE STATS */
  .msg-meta-wrap {
    position: relative;
    margin-left: 42px;
  }
  .msg-meta-clickable {
    cursor: pointer;
    padding: 3px 8px;
    border-radius: 6px;
    transition: background 0.15s, color 0.15s;
    width: fit-content;
  }
  .msg-meta-clickable:hover { color: var(--text-secondary); background: var(--border-light); }
  .msg-meta-chevron {
    margin-left: 5px;
    opacity: 0.5;
    transition: transform 0.2s;
    vertical-align: -1px;
  }
  .msg-meta-clickable.open .msg-meta-chevron { transform: rotate(180deg); }

  .msg-stats-popover {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 50;
    min-width: 230px;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 13px 15px 11px;
    box-shadow: 0 8px 32px color-mix(in srgb, var(--dc-blue) 18%, transparent), 0 2px 8px rgba(0,0,0,0.06);
    animation: statsPop 0.16s cubic-bezier(0.4,0,0.2,1);
  }
  [data-theme="dark"] .msg-stats-popover {
    box-shadow: 0 8px 32px rgba(0,0,0,0.45);
  }
  .msg-stats-popover.hidden { display: none; }
  /* Flip above the trigger when there isn't room below (e.g. last message) */
  .msg-stats-popover.up {
    top: auto;
    bottom: calc(100% + 6px);
    animation-name: statsPopUp;
  }
  @keyframes statsPop {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  @keyframes statsPopUp {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  .msg-stats-title {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-primary);
    letter-spacing: 0.2px;
    margin-bottom: 10px;
  }
  .msg-stats-rows { display: flex; flex-direction: column; gap: 6px; }
  .msg-stats-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    font-size: 11.5px;
  }
  .msg-stats-k {
    color: var(--text-muted);
    font-weight: 500;
    flex-shrink: 0;
  }
  .msg-stats-v {
    color: var(--text-secondary);
    text-align: right;
  }
  .msg-stats-v b { color: var(--text-primary); font-weight: 600; }
  .msg-stats-v.mono { font-family: var(--font-mono); font-size: 11px; }
  .msg-stats-divider {
    height: 1px;
    background: var(--border-light);
    margin: 10px 0;
  }
  .msg-stats-note {
    font-size: 10px;
    color: var(--text-muted);
    margin-top: 9px;
    opacity: 0.8;
  }

  /* SOURCE CHIPS */
  .source-row {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--border-light);
  }
  .source-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: var(--dc-blue-light);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 3px 9px;
    font-size: 10.5px;
    color: var(--dc-blue);
    font-weight: 500;
    cursor: default;
  }
  [data-theme="dark"] .source-chip { color: var(--dc-accent); }

  /* INPUT — floats as a centered card in both welcome AND active-chat
     state (previously only welcome mode floated; the docked chat-mode bar
     now gets the same lift/rounding/shadow instead of sitting flush). */
  .input-area {
    padding: 10px 14px 14px;
    background: var(--bg-panel);
    border: 1.5px solid var(--border);
    flex-shrink: 0;
    position: absolute;
    left: 50%;
    width: calc(100% - 40px);
    max-width: 760px;
    transform: translateX(-50%);
    margin: 0 0 20px;
    bottom: 0;
    z-index: 10;
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 40px color-mix(in srgb, var(--dc-blue) 15%, transparent), 0 2px 8px color-mix(in srgb, var(--dc-blue) 8%, transparent);
    transition: border-color 0.3s ease, box-shadow 0.4s ease;
  }
  [data-theme="dark"] .input-area {
    box-shadow: 0 8px 40px color-mix(in srgb, var(--dc-accent) 10%, transparent), 0 2px 8px rgba(0,0,0,0.2);
  }
  /* Hide footer details when floating — keep it compact like Gemini */
  .main.welcome-mode .legal-disclaimer {
    display: none;
  }

  /* Chat mode: leave room for the floating input bar (+ its bottom margin),
     and dissolve messages as they scroll in behind it.

     The fade is a mask on the scroll box, not a coloured scrim laid on top of
     it. A scrim has to commit to one flat colour, and any flat colour reads as
     a cut-out rectangle over the body's radial-gradient glow — the previous
     one painted a 150px band of --bg-primary across the bottom of .main, which
     showed up as a hard seam running down the sidebar's edge and a visibly
     mismatched block under the input card. Masking fades the content itself
     and leaves whatever is behind it completely untouched. */
  .main:not(.welcome-mode) .chat-area {
    padding-bottom: 200px;
    /* -start/-end are measured up from the bottom of the scroll box: content
       is fully opaque above -start and fully gone below -end. -top is the
       short matching fade at the header end, so messages dissolve as they
       reach the header's rule rather than sliding under it at full strength. */
    --chat-fade-top: 22px;
    --chat-fade-start: 150px;
    --chat-fade-end: 45px;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--chat-fade-top), #000 calc(100% - var(--chat-fade-start)), transparent calc(100% - var(--chat-fade-end)));
    mask-image: linear-gradient(to bottom, transparent 0, #000 var(--chat-fade-top), #000 calc(100% - var(--chat-fade-start)), transparent calc(100% - var(--chat-fade-end)));
  }

  .input-box {
    background: var(--bg-panel);
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 8px 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    transition: border-color 0.25s, box-shadow 0.25s;
    box-shadow: var(--shadow-input);
  }
  .input-box:focus-within {
    border-color: #00f0ff;
    box-shadow: 0 0 0 3px rgba(0, 240, 255, 0.15), 0 0 25px rgba(0, 255, 135, 0.15), var(--shadow-input);
  }
  [data-theme="dark"] .input-box {
    background: rgba(4, 13, 26, 0.78);
    border-color: rgba(0, 240, 255, 0.24);
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.5), 0 0 20px rgba(0, 240, 255, 0.08);
  }
  [data-theme="dark"] .input-box:focus-within {
    border-color: #00f0ff;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6), 0 0 30px rgba(0, 240, 255, 0.25), 0 0 15px rgba(0, 255, 135, 0.2);
  }

  /* Off-screen twin of the textarea, used only to measure the draft's
     natural width (see syncComposer in app/chat.js). Absolute + invisible
     so it never affects layout or gets read out. */
  .composer-measure {
    position: absolute;
    visibility: hidden;
    pointer-events: none;
    white-space: pre;
    font-family: var(--font-main);
    font-size: 13.5px;
    line-height: 1.5;
  }

  /* Two layouts, one flex row.
     Collapsed — everything shares the line:  [ + ][ text …… ][ model ][ ↑ ]
     Expanded  — the draft takes the line:    [ text ……………………………………………… ]
                                              [ + ]        [ model ][ ↑ ]
     Sending the textarea to 100% is what wraps the controls onto their own
     line; nothing is placed by hand, so visitor mode (which drops the "+"
     and the model picker from the DOM) reflows on its own.

     Collapsed stays nowrap on purpose. A wrapping flex container breaks its
     lines from each item's *unshrunk* basis, so a bare <textarea> (which is
     ~20 characters wide by default) plus a long model name would push the
     controls onto a second line by itself — the composer must only ever
     restack when syncComposer() decides it should. */
  .composer-controls {
    display: flex;
    flex-wrap: nowrap;
    align-items: flex-end;
    gap: 6px;
  }
  /* basis 0, not auto: the textarea takes the room that's left over rather
     than asking for its intrinsic width first. */
  .composer-controls > #message-input { flex: 1 1 0; min-width: 0; }
  .composer-controls > .model-select-btn { min-width: 0; }

  .composer-controls.expanded { flex-wrap: wrap; }
  .composer-controls.expanded > #message-input {
    order: -1;
    flex: 1 0 100%;
  }
  /* Collapsed, the stretched textarea already pushes these right; once it
     moves up a line, they need the push themselves. */
  .composer-controls.expanded > .model-select-btn {
    margin-left: auto;
    flex-shrink: 1;   /* last resort on a very narrow controls row */
  }

  #message-input {
    /* No width here on purpose: flex-basis:auto would inherit it and pin the
       textarea to a full line, so it could never share one with the controls.
       .composer-controls.expanded sets the 100% basis when it wants that. */
    min-width: 0;
    border: none;
    background: none;
    font-family: var(--font-main);
    font-size: 13.5px;
    color: var(--text-primary);
    resize: none;
    outline: none;
    min-height: 36px;
    max-height: 140px;
    overflow-y: hidden;
    overflow-x: hidden;
    overflow-wrap: anywhere;
    line-height: 1.5;
    padding: 8px 4px;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
  }
  #message-input::-webkit-scrollbar { width: 4px; }
  #message-input::-webkit-scrollbar-track { background: transparent; }
  #message-input::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
  #message-input::-webkit-scrollbar-button { display: none; }
  /* Placeholder hints stay single-line (like Gemini's "Ask Gemini") — real typed
     text still wraps/scrolls normally when it grows past one row. */
  #message-input::placeholder {
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .send-btn {
    width: 38px; height: 38px;
    background: linear-gradient(135deg, #00ff87 0%, #00f0ff 50%, #8b5cf6 100%);
    border: none;
    border-radius: 12px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #030712;
    box-shadow: 0 0 16px rgba(0, 255, 135, 0.4), 0 0 25px rgba(0, 240, 255, 0.2);
    transition: background 0.2s, color 0.2s, transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s, opacity 0.2s;
    flex-shrink: 0;
  }
  @media (hover: hover) {
    .send-btn:hover {
      background: linear-gradient(135deg, #10e891 0%, #33f3ff 50%, #a78bfa 100%);
      transform: scale(1.06);
      box-shadow: 0 0 22px rgba(0, 255, 135, 0.6), 0 0 35px rgba(0, 240, 255, 0.35);
    }
    [data-theme="dark"] .send-btn:hover {
      background: linear-gradient(135deg, #10e891 0%, #33f3ff 50%, #a78bfa 100%);
      box-shadow: 0 0 25px rgba(0, 255, 135, 0.7), 0 0 40px rgba(0, 240, 255, 0.45);
    }
  }
  .send-btn:active { transform: scale(0.93); }
  [data-theme="dark"] .send-btn {
    background: linear-gradient(135deg, #00ff87 0%, #00f0ff 50%, #8b5cf6 100%);
    color: #020712;
    box-shadow: 0 0 18px rgba(0, 255, 135, 0.45), 0 0 30px rgba(0, 240, 255, 0.25);
  }
  .send-btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; }
  /* Nothing to send yet — the button stays clickable (sendMessage() is the
     one guard on an empty draft) but drops out of the brand gradient so the
     composer reads as "waiting for you" rather than "ready to fire". */
  .send-btn.idle {
    background: rgba(0, 240, 255, 0.1);
    color: var(--text-muted);
    box-shadow: none;
  }
  @media (hover: hover) {
    .send-btn.idle:hover,
    [data-theme="dark"] .send-btn.idle:hover {
      background: rgba(0, 240, 255, 0.18);
      color: var(--text-primary);
      transform: none;
      box-shadow: 0 0 12px rgba(0, 240, 255, 0.15);
    }
  }
  /* Stop / cancel state while the model is generating — outranks .idle.
     A solid red block here shouts louder than anything else on screen for
     something the user does routinely; the tinted chip still reads as stop
     (same slot, same square glyph) without competing with the reply. */
  .send-btn.stop,
  .send-btn.stop.idle {
    background: var(--danger-tint);
    color: var(--danger);
    box-shadow: inset 0 0 0 1px var(--danger-edge);
  }
  @media (hover: hover) {
    .send-btn.stop:hover,
    [data-theme="dark"] .send-btn.stop:hover {
      background: color-mix(in srgb, var(--danger) 20%, transparent);
      transform: none;
    }
  }
  .cancelled-note {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px dashed var(--border);
    font-size: 12px;
    font-style: italic;
    color: var(--text-muted);
  }
  .cancelled-note svg { flex-shrink: 0; opacity: 0.8; }

  .input-tip {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 5px;
    text-align: center;
    font-size: 10.5px;
    color: var(--text-secondary);
    margin-top: 6px;
    letter-spacing: 0.1px;
  }
  [data-theme="dark"] .input-tip {
    color: #a2e8ec;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
  }
  .input-tip-dot { opacity: 0.5; }
  .input-tip-badges {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 5px;
  }
  .tip-badge {
    display: inline-flex;
    align-items: center;
    border-radius: 3px;
    padding: 1px 6px;
    font-size: 9px;
    font-weight: 800;
    color: white;
    letter-spacing: 0.3px;
    white-space: nowrap;
    line-height: 1.6;
  }

  /* MODEL SELECT BUTTON (inside the composer) — a borderless label+chevron
     that sits flush with the other composer controls instead of reading as
     a separate outlined pill. */
  .model-select-btn {
    display: flex;
    align-items: center;
    gap: 4px;
    height: 36px;
    max-width: 190px;
    padding: 0 8px;
    background: transparent;
    border: none;
    border-radius: 10px;
    cursor: pointer;
    font-family: var(--font-main);
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
    transition: background 0.15s, color 0.15s, transform 0.15s, gap 0.18s ease, padding 0.18s ease;
    white-space: nowrap;
    flex-shrink: 0;
    letter-spacing: 0.1px;
  }
  #model-select-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  @media (hover: hover) {
    .model-select-btn:hover {
      background: var(--dc-blue-light);
      color: var(--dc-blue);
    }
    [data-theme="dark"] .model-select-btn:hover {
      background: var(--dc-accent-light);
      color: var(--dc-accent);
    }
  }
  .model-select-btn:active { transform: scale(0.96); }
  .model-select-btn.open {
    background: var(--dc-blue-light);
    color: var(--dc-blue);
  }
  [data-theme="dark"] .model-select-btn.open {
    background: var(--dc-accent-light);
    color: var(--dc-accent);
  }
  .model-select-btn svg { flex-shrink: 0; }
  .model-select-btn .model-select-caret { opacity: 0.6; transition: transform 0.2s, opacity 0.2s; }
  .model-select-btn:hover .model-select-caret { opacity: 1; }
  .model-select-btn.open .model-select-caret { transform: rotate(180deg); opacity: 1; }
  #model-select-icon { display: inline-flex; align-items: center; flex-shrink: 0; }
  #model-select-icon img.model-dd-icon { opacity: 1; }

  /* Collapsed pill (in-conversation only) — once there are messages on screen
     the picker is sharing its row with the draft, so it drops back to a bare
     model name and hands the width to the textarea. Hovering it, or opening
     the dropdown, restores the full logo + name + chevron.

     Welcome mode keeps the full pill: nothing is competing for the row yet,
     and that's the one moment the picker should be unmissable. Scoped to
     (hover: hover) + desktop widths so touch never gets a control that only
     un-collapses on an event it can't produce — mobile keeps its own layout,
     where the controls already have a row to themselves. */
  @media (hover: hover) and (min-width: 641px) {
    /* max-width, not display — a collapsing width is what can animate, and
       the flex items need overflow clipped because the SVGs inside them are
       fixed-size and won't shrink with their box. */
    #model-select-icon,
    .model-select-btn .model-select-caret {
      max-width: 20px;
      overflow: hidden;
      transition: max-width 0.18s ease, opacity 0.18s ease, transform 0.2s;
    }
    .main:not(.welcome-mode) .model-select-btn:not(:hover):not(:focus-visible):not(.open) {
      gap: 0;
      padding: 0 4px;
    }
    .main:not(.welcome-mode) .model-select-btn:not(:hover):not(:focus-visible):not(.open) > #model-select-icon,
    .main:not(.welcome-mode) .model-select-btn:not(:hover):not(:focus-visible):not(.open) > .model-select-caret {
      max-width: 0;
      opacity: 0;
    }
  }

  /* TOOLS MENU (Gemini "+" style) — collapses sources/thinking/web-search into one button */
  .tools-wrap { position: relative; flex-shrink: 0; }

  .tools-btn {
    width: 36px; height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    border-radius: 10px;
    cursor: pointer;
    color: var(--text-muted);
    transition: background 0.15s, color 0.15s, transform 0.15s;
    position: relative;
  }
  .tools-btn:active { transform: scale(0.94); }
  /* Hover-only on devices with a real pointer — on touchscreens (no true
     hover), :hover applies on tap and then sticks until something else is
     tapped, leaving the "+" looking permanently lit. The .open highlight
     below still applies everywhere, since that's driven by a class, not
     a pseudo-state. */
  @media (hover: hover) {
    .tools-btn:hover { background: var(--dc-blue-light); color: var(--dc-blue); }
    [data-theme="dark"] .tools-btn:hover { background: var(--dc-accent-light); color: var(--dc-accent); }
  }
  .tools-btn.open {
    background: var(--dc-blue-light);
    color: var(--dc-blue);
  }
  [data-theme="dark"] .tools-btn.open {
    background: var(--dc-accent-light);
    color: var(--dc-accent);
  }
  .tools-dropdown {
    position: absolute;
    bottom: calc(100% + 8px);
    left: 0;
    background: var(--bg-panel);
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45), 0 0 20px rgba(0, 240, 255, 0.1);
    padding: 6px;
    width: 200px;
    display: none;
    flex-direction: column;
    gap: 2px;
    z-index: 20;
    animation: dropdownIn 0.15s ease;
  }
  .tools-dropdown.open { display: flex; }

  .tools-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 9px;
    border: none;
    background: none;
    border-radius: 8px;
    cursor: pointer;
    font-family: var(--font-main);
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-primary);
    text-align: left;
    width: 100%;
    transition: background 0.12s;
  }
  .tools-item:hover { background: var(--bg-primary); }
  .tools-item-ico { flex-shrink: 0; display: flex; opacity: 0.75; }
  .tools-item-label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tools-item-check { flex-shrink: 0; font-size: 12px; font-weight: 700; color: var(--dc-blue); opacity: 0; }
  .tools-item.active { background: var(--dc-blue-light); color: var(--dc-blue); }
  .tools-item.active .tools-item-ico { opacity: 1; }
  .tools-item.active .tools-item-check { opacity: 1; }
  [data-theme="dark"] .tools-item.active { background: var(--dc-accent-light); color: var(--dc-accent); }
  [data-theme="dark"] .tools-item.active .tools-item-check { color: var(--dc-accent); }

  /* Model picker — this was the mobile stand-in for the model-select pill
     back when that pill was hidden on narrow screens. The stacked composer
     gives the real pill a row of its own at every width now, so the entry
     stays hidden rather than listing the model in two places at once. */
  .tools-item-model { display: none; }
  .tools-section-label {
    font-size: 9.5px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.9px;
    padding: 2px 9px;
  }
  .tools-section-divider {
    height: 1px;
    margin: 4px 2px 6px;
    background: var(--border);
  }
  /* ── STREAMED TEXT ─────────────────────────────────────────────────
     Words carry no entry animation: text just appears as it arrives, with a
     caret marking where it is up to. Anything that fades a word in has to be
     paced, and the pacing is what read as slow and flickery.

     Layout-neutral wrappers: the split into committed vs. still-arriving text
     is a rendering concern, so it must not add a box that stops paragraph
     margins collapsing across the seam. */
  .stream-stable, .stream-tail { display: contents; }
  @keyframes pop-in {
    from { opacity: 0; transform: scale(0.9); }
    to   { opacity: 1; transform: scale(1); }
  }
  /* Deliberately not blinking: the caret is re-created on every repaint, so a
     blink would restart each tick and freeze at one phase. Its movement across
     the text is the liveness signal. */
  .stream-caret {
    display: inline-block;
    width: 2px;
    height: 0.85em;
    margin-left: 2px;
    vertical-align: -1px;
    border-radius: 2px;
    background: var(--text-primary);
    opacity: 0.75;
  }

  /* ── INLINE CITATION CHIP ──────────────────────────────────────────
     Replaces the model's bare "[1]" markers with the source it points at,
     so a claim carries its provenance in place. */
  .cite-chip {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    height: 17px;
    margin: 0 2px 0 1px;
    padding: 0 4px 0 3px;
    border-radius: 5px;
    background: var(--border-light);
    box-shadow: inset 0 0 0 1px var(--border);
    vertical-align: middle;
    transform: translateY(-1px);
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--text-secondary);
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease;
    animation: pop-in 250ms cubic-bezier(0.23, 1, 0.32, 1) both;
  }
  .cite-chip:hover { background: var(--dc-blue-light); color: var(--dc-blue); }
  .cite-chip img { width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0; }

  /* ── SOURCES ROW + EXPANDABLE LIST ─────────────────────────────────
     Collapsed to one line of stacked avatars; the full list opens in place. */
  .web-sources { margin-top: 10px; }
  .src-toggle {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-left: -4px;
    padding: 3px 6px;
    border: none;
    background: none;
    border-radius: 6px;
    cursor: pointer;
    font-family: var(--font-main);
    transition: background 0.15s ease;
  }
  .src-toggle:hover { background: var(--border-light); }
  .src-stack { display: flex; flex-shrink: 0; }
  .src-stack img {
    width: 15px; height: 15px;
    border-radius: 50%;
    background: var(--bg-panel);
    box-shadow: 0 0 0 1.5px var(--ai-bubble);
  }
  .src-stack img + img { margin-left: -4px; }
  .src-toggle-label { font-size: 12px; color: var(--text-secondary); }
  .src-toggle-chevron {
    display: flex;
    color: var(--text-muted);
    transition: transform 0.25s ease;
  }
  .src-toggle.open .src-toggle-chevron { transform: rotate(180deg); }

  .src-list {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition: grid-template-rows 0.3s cubic-bezier(0.23, 1, 0.32, 1),
                opacity 0.3s cubic-bezier(0.23, 1, 0.32, 1);
  }
  .src-list.open { grid-template-rows: 1fr; opacity: 1; }
  .src-list-clip { overflow: hidden; }
  .src-list-inner {
    margin-top: 6px;
    padding: 4px;
    border-radius: 10px;
    background: var(--border-light);
    box-shadow: inset 0 0 0 1px var(--border);
    display: flex;
    flex-direction: column;
  }
  [data-theme="dark"] .src-list-inner { background: rgba(255,255,255,0.04); }
  .web-source-link {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 6px;
    border-radius: 6px;
    text-decoration: none;
    color: var(--text-secondary);
    font-size: 12px;
    transition: background 0.12s, color 0.12s;
  }
  .web-source-link:hover { background: var(--bg-panel); color: var(--text-primary); }
  [data-theme="dark"] .web-source-link:hover { background: rgba(255,255,255,0.06); }
  .web-source-num {
    flex-shrink: 0;
    width: 16px; height: 16px;
    border-radius: 4px;
    overflow: hidden;
  }
  .web-source-num img { width: 100%; height: 100%; display: block; }
  .web-source-title {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .web-source-host {
    flex-shrink: 0;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 10.5px;
  }

  /* ── KNOWLEDGE SOURCES (local retrieval) ───────────────────────────
     Same collapse mechanics as the web strip, but each row carries the
     retrieval score and the chunk text — a web citation can only say where
     an answer came from, while this can also say how strongly it matched. */
  .kb-source-item {
    padding: 6px;
    border-radius: 6px;
  }
  .kb-source-item + .kb-source-item { border-top: 1px solid var(--border); }
  .kb-source-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: var(--text-secondary);
  }
  .kb-source-marker {
    flex-shrink: 0;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    color: var(--dc-accent);
    background: color-mix(in srgb, var(--dc-accent) 14%, transparent);
    border-radius: 4px;
    padding: 1px 4px;
  }
  .kb-score {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 5px;
  }
  .kb-score-bar {
    width: 34px;
    height: 4px;
    border-radius: 2px;
    background: var(--border);
    overflow: hidden;
  }
  .kb-score-bar > span {
    display: block;
    height: 100%;
    border-radius: 2px;
    background: var(--dc-accent);
  }
  .kb-score-num {
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--text-muted);
    min-width: 24px;
  }
  .kb-source-text {
    margin-top: 5px;
    margin-left: 24px;
    max-height: 74px;
    overflow-y: auto;
    font-size: 11.5px;
    line-height: 1.55;
    color: var(--text-muted);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
  /* The web chip shows a hostname; this one shows a filename, which runs longer
     and would otherwise push the paragraph it sits in around. */
  .cite-chip.kb-chip { max-width: 150px; }
  .cite-chip.kb-chip span:not(.kb-chip-n) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .kb-chip-n {
    flex-shrink: 0;
    font-weight: 600;
    color: var(--dc-accent);
  }

  /* ── PROMPT INSPECTOR ──────────────────────────────────────────────
     The literal bytes sent to the model. Monospace and unstyled on purpose —
     this panel's whole value is that it isn't a rendering of the prompt. */
  .prompt-inspector { margin-top: 8px; }
  .prompt-toggle-icon {
    display: flex;
    flex-shrink: 0;
    color: var(--text-muted);
  }
  .prompt-toggle-meta {
    flex-shrink: 0;
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--text-muted);
  }
  .prompt-inner {
    margin-top: 6px;
    border-radius: 10px;
    background: var(--border-light);
    box-shadow: inset 0 0 0 1px var(--border);
    overflow: hidden;
  }
  [data-theme="dark"] .prompt-inner { background: rgba(255,255,255,0.04); }
  /* ── Composition view ──────────────────────────────────────────────
     The part of the panel a beginner reads: a sentence, a bar, and one row
     per contributor naming the setting that produced it. */
  .prompt-breakdown { padding: 11px 12px 12px; }
  .prompt-lede {
    margin: 0 0 10px;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--text-secondary);
  }
  .prompt-lede b { color: var(--text-primary); font-weight: 700; }
  .prompt-bar {
    display: flex;
    height: 9px;
    border-radius: 5px;
    overflow: hidden;
    background: var(--border);
  }
  .prompt-bar > span { display: block; height: 100%; }
  .prompt-bar > span + span { box-shadow: inset 1px 0 0 var(--bg-panel); }
  .prompt-parts { margin-top: 10px; }
  /* Two lines per part: name and size on the first, provenance on the second.
     The wrap has to be explicit — .prompt-part-src claims a full basis to force
     itself onto its own row, which without flex-wrap would instead squeeze the
     label into a two-word column. */
  .prompt-part {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 8px;
    padding: 5px 0;
    font-size: 12px;
    line-height: 1.45;
  }
  .prompt-part + .prompt-part { border-top: 1px solid var(--border); }
  .prompt-part-dot {
    flex-shrink: 0;
    width: 8px; height: 8px;
    border-radius: 2px;
    transform: translateY(-1px);
  }
  .prompt-part-label {
    flex: 1;
    min-width: 0;
    color: var(--text-primary);
    font-weight: 600;
  }
  .prompt-part-size {
    flex-shrink: 0;
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--text-secondary);
    white-space: nowrap;
  }
  .prompt-part-pct { margin-left: 6px; color: var(--text-muted); }
  /* The provenance line wraps under the label on its own row. */
  .prompt-part-src {
    flex-basis: 100%;
    margin-left: 16px;
    font-size: 11px;
    color: var(--text-muted);
  }
  .prompt-note {
    margin: 11px 0 0;
    padding-top: 9px;
    border-top: 1px solid var(--border);
    font-size: 11px;
    line-height: 1.6;
    color: var(--text-muted);
  }

  /* ── Raw text, behind its own disclosure ───────────────────────────*/
  .prompt-raw-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 8px 12px;
    font-family: inherit;
    font-size: 11.5px;
    color: var(--text-secondary);
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
  }
  .prompt-raw-toggle:hover { color: var(--text-primary); }
  .prompt-raw-toggle .src-toggle-chevron {
    display: flex;
    transform: rotate(-90deg);
    transition: transform 0.2s;
  }
  .prompt-raw-toggle.open .src-toggle-chevron { transform: rotate(0deg); }
  .prompt-raw-body.hidden { display: none; }
  .prompt-raw-body { border-top: 1px solid var(--border); }

  .prompt-head {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 8px 12px;
    border-top: 1px solid var(--border);
  }
  .prompt-head-cfg { flex: 1; display: flex; gap: 4px; flex-wrap: wrap; }
  .prompt-head-cfg code {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--text-muted);
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 1px 5px;
  }
  .prompt-copy-btn {
    flex-shrink: 0;
    font-family: inherit;
    font-size: 11px;
    color: var(--text-secondary);
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 3px 9px;
    cursor: pointer;
    transition: color 0.12s, border-color 0.12s;
  }
  .prompt-copy-btn:hover { color: var(--text-primary); }
  .prompt-copy-btn.copied { color: var(--dc-green); border-color: var(--dc-green); }
  .prompt-msg + .prompt-msg { border-top: 1px solid var(--border); }
  .prompt-msg-role {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 10px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
  }
  .prompt-msg.role-system .prompt-msg-role { color: var(--dc-accent); }
  .prompt-msg-len {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-muted);
  }
  .prompt-msg-body {
    margin: 0;
    padding: 0 10px 10px;
    max-height: 260px;
    overflow: auto;
    font-family: var(--font-mono);
    font-size: 11px;
    line-height: 1.6;
    color: var(--text-secondary);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }

  /* ── FOLLOW-UPS ────────────────────────────────────────────────────
     Generated after the answer lands; each row sends itself on click. */
  .followups {
    margin-top: 12px;
    animation: fade-in 300ms ease-out both;
  }
  .followups-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: 1px;
  }
  .followup-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: calc(100% + 12px);
    margin: 0 -6px;
    padding: 7px 6px;
    border: none;
    border-bottom: 1px solid var(--border-light);
    background: none;
    border-radius: 7px;
    cursor: pointer;
    text-align: left;
    font-family: var(--font-main);
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--text-primary);
    transition: background 0.1s ease;
    animation: fade-up 350ms cubic-bezier(0.23, 1, 0.32, 1) both;
  }
  .followup-item:hover { background: var(--border-light); }
  .followup-item svg { flex-shrink: 0; color: var(--text-muted); }

  /* MODEL DROPDOWN PANEL (search-style picker) */
  .model-dropdown {
    position: absolute;
    bottom: calc(100% + 8px);
    right: 14px;
    background: var(--bg-panel);
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45), 0 0 25px rgba(0, 240, 255, 0.12);
    padding: 8px;
    width: 280px;
    display: none;
    flex-direction: column;
    gap: 6px;
    z-index: 20;
    animation: dropdownIn 0.15s ease;
  }
  .model-dropdown.open { display: flex; }
  @keyframes dropdownIn {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  .model-dd-search-row { display: flex; align-items: center; gap: 6px; }
  .model-dd-search {
    flex: 1;
    min-width: 0;
    padding: 7px 10px;
    border: 1.5px solid var(--border);
    border-radius: 8px;
    background: var(--bg-primary);
    color: var(--text-primary);
    font-family: var(--font-main);
    font-size: 12.5px;
    outline: none;
    transition: border-color 0.15s;
  }
  .model-dd-search:focus { border-color: var(--dc-accent); }
  .model-dd-search::placeholder { color: var(--text-muted); }
  .model-dd-add {
    flex-shrink: 0;
    width: 30px; height: 30px;
    display: flex; align-items: center; justify-content: center;
    border: 1.5px solid var(--dc-accent);
    border-radius: 8px;
    background: transparent;
    color: var(--dc-accent);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: all 0.15s;
  }
  .model-dd-add:hover { background: var(--dc-accent); color: #fff; }
  .model-dd-recent-label {
    font-size: 9.5px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.9px;
    padding: 2px 4px 0;
  }
  .model-dd-list { display: flex; flex-direction: column; gap: 2px; max-height: 220px; overflow-y: auto; }
  .model-dd-empty { padding: 10px 6px; font-size: 12px; color: var(--text-muted); text-align: center; }
  .model-dd-demo-note { padding: 4px 8px 6px; font-size: 10.5px; color: var(--text-muted); text-align: left; }
  .model-dropdown-opt.demo { border: 1px dashed var(--border); opacity: 0.85; }
  .model-dropdown-opt.demo:hover { background: var(--bg-primary); opacity: 1; }
  .model-dropdown-opt.demo .model-dd-endpoint { font-style: italic; }
  .model-dropdown-opt {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 10px;
    border: none;
    background: none;
    border-radius: 8px;
    cursor: pointer;
    font-family: var(--font-main);
    font-size: 12.5px;
    color: var(--text-primary);
    font-weight: 500;
    transition: background 0.12s;
    text-align: left;
    width: 100%;
  }
  .model-dropdown-opt:hover { background: var(--bg-primary); }
  .model-dropdown-opt.active { background: var(--dc-blue-light); }
  [data-theme="dark"] .model-dropdown-opt.active { background: var(--dc-accent-light); }
  .model-dd-icon { flex-shrink: 0; opacity: 0.8; }
  img.model-dd-icon { object-fit: contain; border-radius: 4px; opacity: 1; }
  .model-dd-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
  .model-dd-name { font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .model-dropdown-opt.active .model-dd-name { color: var(--dc-accent); }
  .model-dd-endpoint { font-size: 10.5px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .model-dd-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    margin-left: auto;
    background: #F59E0B;   /* default: checking / idle */
    transition: background 0.2s;
  }
  .model-dd-dot.online  { background: #22C55E; }
  .model-dd-dot.idle    { background: #F59E0B; }
  .model-dd-dot.offline { background: #EF4444; }
  .model-dd-badge {
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: 0.3px;
    padding: 2px 7px;
    border-radius: 20px;
    white-space: nowrap;
    flex-shrink: 0;
  }
  .model-dd-badge.rec   { background: rgba(34,197,94,0.14);  color: #16A34A; }
  .model-dd-badge.fast  { background: rgba(245,158,11,0.16); color: #B45309; }
  .model-dd-badge.smart { background: rgba(139,92,246,0.14); color: #7C3AED; }
  [data-theme="dark"] .model-dd-badge.rec   { color: #4ADE80; }
  [data-theme="dark"] .model-dd-badge.fast  { color: #FBBF24; }
  [data-theme="dark"] .model-dd-badge.smart { color: #A78BFA; }
  .model-dd-dot.checking {
    background: #F59E0B;
    animation: dot-pulse 1s ease-in-out infinite;
  }
  @keyframes dot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

  /* ADD MODELS — ENDPOINT CARDS */
  .endpoint-card {
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: var(--bg-primary);
  }
  .endpoint-source {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 11px;
    border: 1.5px solid var(--border);
    border-radius: 8px;
    background: var(--bg-panel);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.6px;
    color: var(--text-secondary);
  }
  .endpoint-source svg { opacity: 0.7; }
  .endpoint-row { display: flex; align-items: center; gap: 8px; }
  .endpoint-row .settings-input { flex: 1; min-width: 0; }
  .endpoint-type, .endpoint-provider {
    flex-shrink: 0;
    background: var(--bg-panel);
    border: 1.5px solid var(--border);
    border-radius: 8px;
    padding: 8px 9px;
    font-family: var(--font-main);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-primary);
    cursor: pointer;
    outline: none;
  }
  .endpoint-type { width: 76px; }
  .endpoint-provider { display: flex; align-items: center; }
  .endpoint-type:focus, .endpoint-provider:focus { border-color: var(--dc-blue); }
  .endpoint-actions { display: flex; justify-content: flex-end; gap: 8px; }
  .endpoint-btn {
    padding: 8px 18px;
    border-radius: 8px;
    font-family: var(--font-main);
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.15s;
    white-space: nowrap;
  }
  .endpoint-btn.ghost {
    background: transparent;
    border: 1.5px solid var(--border);
    color: var(--text-secondary);
  }
  .endpoint-btn.ghost:hover:not(:disabled) { border-color: var(--dc-blue); color: var(--dc-blue); }
  .endpoint-btn.solid {
    background: var(--dc-blue);
    border: 1.5px solid var(--dc-blue);
    color: #fff;
  }
  .endpoint-btn.solid:hover:not(:disabled) { filter: brightness(1.08); }
  .endpoint-btn:disabled { opacity: 0.6; cursor: default; }
  .endpoint-quickstart {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 9px 11px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-panel);
    font-family: var(--font-main);
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background 0.15s;
  }
  .endpoint-quickstart:hover { background: var(--bg-primary); }
  .endpoint-quickstart svg { transition: transform 0.2s; opacity: 0.6; }
  .endpoint-quickstart.open svg { transform: rotate(90deg); }
  .quickstart-body {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 4px 4px 2px;
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.5;
  }
  /* The rule above sets display:flex, which beats the UA stylesheet's
     display:none for [hidden] — without this the panel could never
     collapse and the Quickstart toggle looked dead. */
  .quickstart-body[hidden] { display: none; }
  .quickstart-body code {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 11.5px;
    color: var(--dc-blue);
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
  }
  .quickstart-body strong { color: var(--text-primary); }
  .quickstart-body a { color: var(--dc-blue); font-weight: 600; text-decoration: none; }
  .quickstart-body a:hover { text-decoration: underline; }
  .qs-step { display: flex; gap: 9px; align-items: flex-start; }
  .qs-num {
    flex-shrink: 0;
    width: 19px;
    height: 19px;
    margin-top: 1px;
    border-radius: 50%;
    background: var(--dc-blue);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .qs-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
  .qs-text strong { font-size: 12.5px; }
  .qs-text code { align-self: flex-start; max-width: 100%; overflow-x: auto; }
  .qs-tip {
    margin-top: 2px;
    padding: 8px 10px;
    border-radius: 7px;
    background: var(--bg-panel);
    font-size: 11.5px;
    line-height: 1.55;
  }
  .qs-tip code {
    background: none;
    border: none;
    padding: 0;
    font-size: 11px;
  }

  /* ADDED MODELS / ENDPOINT MANAGER */
  .added-endpoints-section { margin-top: 4px; }
  .added-endpoints-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 700;
    color: var(--text-primary);
  }
  .added-endpoints-head svg { opacity: 0.65; }
  .added-endpoints-sub { font-weight: 500; color: var(--text-muted); }
  .added-endpoints-desc {
    margin: 4px 0 12px;
    font-size: 11.5px;
    color: var(--text-muted);
  }
  .ep-group { margin-bottom: 14px; }
  .ep-group-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.6px;
    color: var(--text-muted);
    margin-bottom: 6px;
  }
  .ep-group-label svg { opacity: 0.6; }
  .ep-card {
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 12px 13px;
    background: var(--bg-primary);
  }
  .ep-card-main { display: flex; align-items: center; flex-wrap: wrap; gap: 9px; }
  .ep-card-name {
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text-primary);
    white-space: nowrap;
  }
  .ep-badge {
    font-size: 10.5px;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 20px;
    background: rgba(5,150,105,0.12);
    color: #059669;
    white-space: nowrap;
  }
  .ep-badge.off { background: var(--bg-panel); color: var(--text-muted); }
  .ep-manage-hint {
    flex: 1;
    min-width: 0;
    font-size: 11px;
    color: var(--text-muted);
    cursor: pointer;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .ep-card-actions { display: flex; align-items: center; gap: 7px; flex-shrink: 0; margin-left: auto; }
  .ep-mini-btn {
    padding: 5px 12px;
    border-radius: 7px;
    font-family: var(--font-main);
    font-size: 11.5px;
    font-weight: 600;
    cursor: pointer;
    background: transparent;
    border: 1.5px solid var(--border);
    color: var(--text-secondary);
    transition: all 0.15s;
    white-space: nowrap;
  }
  .ep-mini-btn:hover { border-color: var(--dc-blue); color: var(--dc-blue); }
  .ep-mini-btn.danger:hover { border-color: #DC2626; color: #DC2626; }
  .ep-chevron {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: none;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 6px;
  }
  .ep-chevron:hover { background: var(--bg-panel); }
  .ep-chevron svg { transition: transform 0.2s; }
  .ep-chevron.open svg { transform: rotate(180deg); }
  .ep-url-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    font-size: 11px;
    color: var(--text-muted);
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
  }
  .ep-url-copy {
    border: none;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px;
    display: inline-flex;
    border-radius: 4px;
  }
  .ep-url-copy:hover { color: var(--dc-blue); }
  .ep-models {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .ep-model-row {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 4px;
    font-size: 12.5px;
    color: var(--text-primary);
  }
  .ep-model-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ep-model-name.disabled { color: var(--text-muted); text-decoration: line-through; }
  .ep-toggle {
    flex-shrink: 0;
    width: 34px;
    height: 18px;
    border-radius: 20px;
    border: none;
    background: var(--border);
    position: relative;
    cursor: pointer;
    transition: background 0.15s;
  }
  .ep-toggle.on { background: var(--dc-blue); }
  .ep-toggle::after {
    content: '';
    position: absolute;
    top: 2px; left: 2px;
    width: 14px; height: 14px;
    border-radius: 50%;
    background: #fff;
    transition: transform 0.15s;
  }
  .ep-toggle.on::after { transform: translateX(16px); }
  .added-endpoints-empty {
    padding: 16px;
    border: 1px dashed var(--border);
    border-radius: 10px;
    text-align: center;
    font-size: 12px;
    color: var(--text-muted);
  }

  /* SIDEBAR OVERLAY (mobile) */
  .sidebar-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 99;
  }

  /* MOBILE */
  @media (max-width: 640px) {
    :root { --sidebar-w: 260px; }

    .sidebar {
      position: fixed;
      left: 0; top: 0; bottom: 0;
      margin: 0;
      border-radius: 0;
      border: none;
      transform: translateX(-100%);
    }
    .sidebar.open { transform: translateX(0); }

    .sidebar-overlay.visible { display: block; }

    .suggestion-grid { grid-template-columns: 1fr; max-width: 100%; }
    .welcome-title { font-size: 26px; }
    .chat-area { padding: 14px 12px; }
    /* Reclaim the side gutters — 40px of them is a lot of a phone's width. */
    .input-area { padding: 8px 10px 12px; display: flex; flex-direction: column; width: calc(100% - 20px); }
    /* The stacked composer is roughly twice as tall as the one-row desktop
       version, so the last message needs more room to clear it — and the
       scroll-in fade has to start correspondingly higher. */
    .main:not(.welcome-mode) .chat-area {
      padding-bottom: 250px;
      --chat-fade-start: 215px;
      --chat-fade-end: 60px;
    }

    /* Partner badges are the least important line here — push them below
       the legal disclaimer instead of sandwiching them right under the box. */
    .input-box { order: 1; }
    .legal-disclaimer { order: 2; }
    .input-tip { order: 3; }

    .status-chip { display: none; }

    .bubble { max-width: calc(100% - 38px); }

    .header { padding: 0 12px; gap: 6px; }
    .back-btn { font-size: 0; gap: 0; padding: 7px; }
    .header-actions { gap: 4px; }
    .icon-btn { width: 30px; height: 30px; }

    /* COMPOSER (mobile) — there's never enough room to keep the draft inline
       with the controls, so the stacked layout is permanent here: text on
       top, controls on a row beneath it. That also buys the model picker its
       place back; it used to be hidden on narrow screens and reachable only
       through the "+" menu. */
    .composer-controls { flex-wrap: wrap; }
    .composer-controls > #message-input {
      order: -1;
      flex: 1 0 100%;
    }
    .composer-controls > .model-select-btn { margin-left: auto; flex-shrink: 1; }

    /* iOS zooms the whole page in when a focused field is under 16px. */
    #message-input {
      font-size: 16px;
      padding: 8px 6px;
      max-height: 120px;
    }
    .composer-measure { font-size: 16px; }

    /* The model name is the first thing that should give up width when the
       row gets tight — the "+" and send buttons are fixed-size targets. */
    .model-select-btn { max-width: 46vw; }

    /* Clear the home-indicator / gesture bar on modern phones. */
    .input-area { margin-bottom: max(20px, env(safe-area-inset-bottom)); }

    /* Partner badges: force the label onto its own line so the 3 badges
       always wrap together as one centered group below it, instead of
       splitting lopsidedly (e.g. 2 + 1) mid-sentence with the label text. */
    .input-tip { flex-direction: column; }
    .input-tip-badges { flex-wrap: nowrap; }
  }

  /* CONTEXT NOTIFICATION */
  .context-bar {
    margin: 0 0 4px;
    padding: 8px 12px;
    background: var(--dc-blue-light);
    border: 1px solid color-mix(in srgb, var(--dc-blue) 20%, transparent);
    border-radius: var(--radius-sm);
    font-size: 11.5px;
    color: var(--dc-blue);
    display: flex;
    align-items: center;
    gap: 7px;
    font-weight: 500;
  }
  [data-theme="dark"] .context-bar { color: var(--dc-accent); }

  .scroll-bottom-btn {
    position: fixed;
    bottom: 100px;
    right: 20px;
    width: 36px; height: 36px;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 50%;
    display: none;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 3px 12px rgba(0,0,0,0.12);
    transition: all 0.2s;
    z-index: 50;
    color: var(--text-secondary);
  }
  .scroll-bottom-btn.visible { display: flex; }
  .scroll-bottom-btn:hover { background: var(--dc-blue); color: white; border-color: var(--dc-blue); }

  /* ERROR */
  /* ERROR CARD — an ordinary card that happens to carry a red glyph, rather
     than a red card. The recovery steps are the *fix*, not the failure, so
     they read in the normal ink scale and the primary action keeps the brand
     blue: "Open the setup guide" is constructive, and dressing it as a
     destructive button misreads what it does. */
  .error-bubble {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    font-size: 13px;
    color: var(--text-secondary);
    margin: 4px 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    box-shadow: var(--shadow-card);
  }
  .error-bubble > svg { color: var(--danger); }
  .error-bubble-top {
    display: flex;
    align-items: flex-start;
    gap: 10px;
  }
  .error-bubble-icon {
    width: 32px; height: 32px;
    background: var(--danger-tint);
    border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    color: var(--danger);
    box-shadow: inset 0 0 0 1px var(--danger-edge);
  }
  .error-bubble-title {
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 3px;
    line-height: 1.3;
  }
  .error-bubble-desc {
    font-size: 12.5px;
    color: var(--text-secondary);
    line-height: 1.6;
  }
  .error-bubble-steps {
    background: var(--border-light);
    box-shadow: inset 0 0 0 1px var(--border);
    border-radius: 10px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  [data-theme="dark"] .error-bubble-steps { background: rgba(255,255,255,0.035); }
  .error-bubble-steps-title {
    font-size: 10.5px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    margin-bottom: 2px;
  }
  .error-step {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.5;
  }
  .error-step-num {
    width: 16px; height: 16px;
    border-radius: 50%;
    background: var(--bg-panel);
    box-shadow: inset 0 0 0 1px var(--border);
    color: var(--text-secondary);
    display: flex; align-items: center; justify-content: center;
    font-size: 9px; font-weight: 700;
    flex-shrink: 0; margin-top: 1px;
  }
  .error-step code {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-primary);
    background: var(--bg-primary);
    box-shadow: inset 0 0 0 1px var(--border);
    padding: 1px 5px;
    border-radius: 4px;
  }
  [data-theme="dark"] .error-step code { background: rgba(0,0,0,0.28); }
  .error-bubble-dismiss {
    align-self: flex-end;
    background: none;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 6px 12px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
    font-family: var(--font-main);
    transition: background 0.15s, color 0.15s;
  }
  .error-bubble-dismiss:hover { background: var(--border-light); color: var(--text-primary); }
  .error-bubble-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
  }
  .error-bubble-cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--dc-blue);
    border: 1px solid var(--dc-blue);
    border-radius: 8px;
    padding: 6px 12px;
    font-size: 12px;
    font-weight: 700;
    color: #fff;
    cursor: pointer;
    font-family: var(--font-main);
    transition: background 0.15s, transform 0.05s;
  }
  .error-bubble-cta:hover { background: var(--dc-blue-dark); border-color: var(--dc-blue-dark); }
  .error-bubble-cta:active { transform: translateY(1px); }
  .error-bubble-cta svg { flex-shrink: 0; }
  /* TRUST PILLS */
  .trust-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: var(--dc-blue-light);
    border: 1px solid color-mix(in srgb, var(--dc-blue) 18%, transparent);
    border-radius: 20px;
    padding: 4px 11px 4px 8px;
    font-size: 11px;
    font-weight: 600;
    color: var(--dc-blue);
    letter-spacing: 0.1px;
    white-space: nowrap;
  }
  [data-theme="dark"] .trust-pill {
    background: color-mix(in srgb, var(--dc-blue) 15%, transparent);
    border-color: color-mix(in srgb, var(--dc-blue) 30%, transparent);
    color: var(--dc-accent);
  }

  .community-desc {
    width: 100%;
    max-width: 400px;
  }
  .community-desc-inner {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    background: var(--bg-panel);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: 11px 13px;
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.65;
    box-shadow: var(--shadow-card);
    text-align: left;
  }
  .community-desc-inner svg { color: var(--dc-blue); margin-top: 1px; }
  [data-theme="dark"] .community-desc-inner svg { color: var(--dc-accent); }
  .community-desc-inner strong { color: var(--text-primary); font-weight: 600; }

  /* LEGAL DISCLAIMER — lives inside the .input-area card. It used to be a
     docked footer bar of its own, which is where the fill and the rule came
     from; against the card they just drew a stray divider between the partner
     badges and this line, over a background that already matches. */
  .legal-disclaimer {
    padding: 5px 16px 6px;
    flex-shrink: 0;
  }
  .legal-disclaimer-inner {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 9.5px;
    color: var(--text-secondary);
    line-height: 1.4;
    justify-content: center;
    flex-wrap: wrap;
    text-align: center;
  }
  .legal-about-btn {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 9.5px;
    color: var(--dc-blue);
    font-family: var(--font-main);
    font-weight: 600;
    padding: 0;
    text-decoration: underline;
    text-underline-offset: 2px;
  }
  [data-theme="dark"] .legal-about-btn { color: var(--dc-accent); }

  /* WELCOME MODAL */
  .modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(14, 9, 32, 0.72);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    backdrop-filter: blur(3px);
    animation: fade-in 0.2s ease;
  }
  @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

  .modal-card {
    background: var(--bg-panel);
    border-radius: 20px;
    width: 100%;
    max-width: 440px;
    max-height: 88dvh;
    overflow-y: auto;
    box-shadow: 0 24px 64px rgba(0,0,0,0.3);
    animation: slide-up 0.25s cubic-bezier(0.34,1.56,0.64,1);
    border: 1px solid var(--border);
  }
  @keyframes slide-up { from { transform: translateY(24px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
  .modal-card::-webkit-scrollbar { width: 3px; }
  .modal-card::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

  /* Onboarding copy reads too dim on the dark theme's muted/secondary
     grays — every var(--text-secondary)/var(--text-muted) use in here
     (classes and inline styles alike) resolves to near-white instead. */
  [data-theme="dark"] .onboarding-card {
    --text-secondary: var(--text-primary);
    --text-muted: var(--text-primary);
  }

  .modal-header {
    padding: 22px 22px 0;
    display: flex;
    align-items: flex-start;
    gap: 14px;
  }
  .modal-logo {
    width: 46px; height: 46px;
    border-radius: 13px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    font-weight: 800;
    color: white;
    letter-spacing: -0.5px;
    flex-shrink: 0;
    box-shadow: 0 6px 20px color-mix(in srgb, var(--dc-blue) 30%, transparent);
  }
  .modal-header-text { flex: 1; }
  .modal-header-text h2 {
    font-size: 17px;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.2;
    margin-bottom: 3px;
  }
  .modal-header-text p {
    font-size: 11.5px;
    color: var(--text-muted);
    font-weight: 400;
  }
  .modal-mabuhay {
    font-size: 12px;
    font-weight: 700;
    color: var(--dc-blue);
    letter-spacing: 0.3px;
    margin-bottom: 4px;
  }
  [data-theme="dark"] .modal-mabuhay { color: var(--text-primary); }

  .lang-toggle-soon {
    display: flex;
    align-items: center;
    gap: 4px;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 4px 8px;
    font-size: 10.5px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: not-allowed;
    white-space: nowrap;
    user-select: none;
  }
  .soon-badge {
    background: #FEF9C3;
    border: 1px solid #FDE68A;
    color: #854D0E;
    border-radius: 4px;
    padding: 0 5px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.3px;
    text-transform: uppercase;
  }
  [data-theme="dark"] .soon-badge {
    background: rgba(133,77,14,0.2);
    border-color: rgba(133,77,14,0.4);
    color: #FCD34D;
  }
  .modal-close {
    width: 28px; height: 28px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    flex-shrink: 0;
    transition: all 0.15s;
    margin-top: -2px;
  }
  .modal-close:hover { background: var(--border-light); color: var(--text-primary); }

  .modal-tabs {
    display: flex;
    gap: 0;
    padding: 16px 22px 0;
    border-bottom: 1px solid var(--border-light);
    margin-top: 16px;
  }
  .modal-tab {
    padding: 7px 13px 9px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    cursor: pointer;
    font-family: var(--font-main);
    transition: all 0.15s;
    margin-bottom: -1px;
    white-space: nowrap;
  }
  .modal-tab.active {
    color: var(--dc-blue);
    border-bottom-color: var(--dc-blue);
  }
  [data-theme="dark"] .modal-tab.active { color: var(--dc-accent); border-bottom-color: var(--dc-accent); }

  .modal-body { padding: 20px 22px 22px; }
  .modal-panel { display: none; }
  .modal-panel.active { display: block; }

  .modal-section-title {
    font-size: 11px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.8px;
    margin-bottom: 10px;
  }
  .modal-text {
    font-size: 13px;
    color: var(--text-secondary);
    line-height: 1.7;
    margin-bottom: 14px;
  }
  .modal-text strong { color: var(--text-primary); font-weight: 600; }

  .modal-highlight {
    background: var(--dc-blue-light);
    border: 1px solid color-mix(in srgb, var(--dc-blue) 15%, transparent);
    border-radius: 10px;
    padding: 12px 14px;
    margin-bottom: 14px;
    font-size: 12.5px;
    color: var(--dc-blue);
    font-weight: 500;
    line-height: 1.6;
    display: flex;
    gap: 9px;
    align-items: flex-start;
  }
  [data-theme="dark"] .modal-highlight { color: var(--text-primary); background: color-mix(in srgb, var(--dc-blue) 10%, transparent); border-color: color-mix(in srgb, var(--dc-blue) 20%, transparent); }
  .modal-highlight svg { flex-shrink: 0; margin-top: 2px; }

  .stack-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
    margin-bottom: 14px;
  }
  .stack-item {
    background: var(--bg-primary);
    border: 1px solid var(--border-light);
    border-radius: 10px;
    padding: 10px 12px;
    display: flex;
    gap: 12px;
    align-items: flex-start;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s, background 0.15s;
  }
  a.stack-item:hover {
    border-color: var(--dc-blue);
    background: var(--dc-blue-light);
  }
  [data-theme="dark"] a.stack-item:hover {
    border-color: var(--dc-accent);
    background: color-mix(in srgb, var(--dc-blue) 12%, transparent);
  }
  .stack-link {
    color: var(--dc-blue);
    text-decoration: underline;
    text-underline-offset: 2px;
    font-weight: 700;
    font-size: inherit;
  }
  .stack-link:hover { color: var(--dc-blue-dark); }
  [data-theme="dark"] .stack-link { color: var(--dc-accent); }
  [data-theme="dark"] .stack-link:hover { color: var(--dc-blue-tint); }
  .stack-icon {
    width: 28px; height: 28px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    flex-shrink: 0;
  }
  .stack-item-text {}
  .stack-item-name {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.2;
    margin-bottom: 3px;
  }
  .stack-item-desc {
    font-size: 11.5px;
    color: var(--text-secondary);
    line-height: 1.5;
  }

  .open-source-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border-light);
    font-size: 12.5px;
  }
  .open-source-row:last-child { border-bottom: none; padding-bottom: 0; }
  .open-source-row svg { flex-shrink: 0; margin-top: 2px; color: var(--dc-blue); }
  [data-theme="dark"] .open-source-row svg { color: var(--dc-accent); }
  .open-source-row strong { color: var(--text-primary); font-weight: 600; }
  .open-source-row span { color: var(--text-secondary); line-height: 1.65; }
  .modal-why-row { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; color: var(--text-secondary); line-height: 1.65; }
  .modal-why-row strong { color: var(--text-primary); font-weight: 600; }
  .modal-why-row em { font-style: italic; }
  .modal-hour-row { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; color: var(--text-secondary); line-height: 1.5; }
  .modal-hour-row strong { color: var(--text-primary); font-weight: 600; }

  .modal-footer-btn {
    width: 100%;
    padding: 11px;
    background: var(--dc-blue);
    color: white;
    border: none;
    border-radius: 10px;
    font-family: var(--font-main);
    font-size: 13.5px;
    font-weight: 700;
    cursor: pointer;
    margin-top: 18px;
    transition: background 0.2s;
    letter-spacing: 0.2px;
  }
  .modal-footer-btn:hover { background: var(--dc-blue-dark); }

  /* ── ONBOARDING (single column — about + why up front, rest collapsed) ── */
  .onboarding-card { max-width: 480px; }

  /* Step 1 hero — full poster, shown at its natural aspect ratio */
  .onboard-poster {
    width: 100%;
    height: auto;
    border-radius: 14px;
    border: 1px solid var(--border-light);
    margin-bottom: 14px;
    display: block;
  }

  /* Step 2 — "works with any open-source model" logo chips */
  .model-chip-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
  }
  .model-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-light);
    border-radius: 10px;
    padding: 7px 11px 7px 8px;
  }
  .model-chip img { width: 20px; height: 20px; object-fit: contain; flex-shrink: 0; border-radius: 4px; }
  .model-chip-name { font-size: 12px; font-weight: 700; color: var(--text-primary); line-height: 1.3; }
  .model-chip-by { font-size: 10.5px; color: var(--text-muted); line-height: 1.3; }

  /* Step 2 — AI setup blocks */
  .onboard-setup-block {
    border: 1px solid var(--border-light);
    border-radius: 12px;
    padding: 14px;
    margin-bottom: 12px;
    background: var(--bg-secondary);
  }
  .onboard-setup-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 10px;
  }
  .onboard-setup-num {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--dc-blue);
    color: #fff;
    font-size: 11.5px;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .onboard-action-btn {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    background: var(--dc-blue-light);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
    color: var(--dc-blue);
    font-family: var(--font-main);
    font-size: 13.5px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
  }
  .onboard-action-btn:hover {
    background: var(--dc-blue);
    border-color: var(--dc-blue);
    color: #fff;
  }
  .onboard-action-btn > span { flex: 1; text-align: left; }
  .onboard-action-arrow { opacity: 0.7; }

  /* Step 2 — installation requirements (collapsible) */
  .install-req { margin-bottom: 14px; }
  .install-req summary {
    cursor: pointer; list-style: none; user-select: none;
    display: flex; align-items: center; gap: 7px;
    font-size: 12.5px; font-weight: 700; color: var(--dc-blue);
    padding: 9px 12px; border: 1px solid var(--border); border-radius: 10px;
    background: var(--bg-secondary);
  }
  .install-req summary::-webkit-details-marker { display: none; }
  .install-req summary::after { content: '▾'; margin-left: auto; font-size: 11px; opacity: 0.7; }
  .install-req[open] summary {
    border-bottom-left-radius: 0; border-bottom-right-radius: 0;
  }
  .install-req[open] summary::after { content: '▴'; }
  .install-req-body {
    border: 1px solid var(--border); border-top: none;
    border-radius: 0 0 10px 10px; padding: 10px 12px;
    background: var(--bg-secondary);
    display: flex; flex-direction: column; gap: 7px;
  }
  .install-req-row {
    display: flex; gap: 10px; font-size: 12px; line-height: 1.5;
    color: var(--text-secondary);
  }
  .install-req-row b { flex: 0 0 60px; color: var(--text-primary); }

  /* Step 2 — model recommender */
  .rec-select-row { display: flex; gap: 10px; margin-bottom: 12px; }
  .rec-select-row label {
    flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px;
    font-size: 11px; font-weight: 700; color: var(--text-secondary);
    text-transform: uppercase; letter-spacing: 0.4px;
  }
  .rec-select {
    width: 100%; background: var(--bg-secondary); border: 1px solid var(--border);
    border-radius: 10px; padding: 9px 10px; color: var(--text-primary);
    font-family: var(--font-main); font-size: 12.5px; font-weight: 600;
    outline: none; cursor: pointer;
  }
  .rec-select:invalid { color: var(--text-muted); }
  .rec-group { margin-bottom: 12px; }
  .rec-group-head {
    display: flex; align-items: center; gap: 7px; font-size: 11.5px; font-weight: 800;
    text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-secondary);
    margin: 10px 0 6px;
  }
  .rec-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
  .rec-row {
    display: flex; align-items: center; gap: 10px; padding: 8px 10px;
    border: 1px solid var(--border-light); border-radius: 10px;
    background: var(--bg-secondary); margin-bottom: 6px;
  }
  .rec-row.dim { opacity: 0.55; }
  .rec-logo { width: 20px; height: 20px; object-fit: contain; border-radius: 5px; flex-shrink: 0; }
  .rec-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
  .rec-name { font-size: 12.5px; font-weight: 700; color: var(--text-primary); font-family: var(--font-mono); }
  .rec-name em { font-style: normal; font-weight: 600; font-size: 11px; color: var(--text-muted); margin-left: 6px; }
  .rec-desc { font-size: 11.5px; color: var(--text-secondary); }
  .rec-copy {
    flex-shrink: 0; background: none; border: 1px solid var(--border); border-radius: 8px;
    padding: 5px 10px; font-family: var(--font-main); font-size: 11px; font-weight: 700;
    color: var(--dc-blue); cursor: pointer; transition: background 0.15s;
    min-width: 76px; text-align: center;
  }
  .rec-copy:hover { background: var(--dc-blue-light); }
  .rec-copy.checking { opacity: 0.65; cursor: default; }
  .rec-copy.downloading {
    background: var(--dc-blue); border-color: var(--dc-blue); color: white; cursor: default;
  }
  .rec-copy.done { color: #22C55E; border-color: #22C55E; cursor: default; }
  .rec-copy.error { color: #EF4444; border-color: #EF4444; }

  /* PULL TERMINAL — mimics a terminal window; stays dark in both themes */
  .pull-terminal-card {
    max-width: 520px;
    background: #141024;
    border: 1px solid #332B57;
    border-radius: 12px;
    overflow: hidden;
    padding: 0;
  }
  .pull-terminal-titlebar {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 12px;
    background: #1C1636;
    border-bottom: 1px solid #332B57;
  }
  .pull-terminal-dots { display: flex; gap: 6px; flex-shrink: 0; }
  .pull-terminal-dots span { width: 10px; height: 10px; border-radius: 50%; display: block; }
  .pull-terminal-dots span:nth-child(1) { background: #ff5f56; }
  .pull-terminal-dots span:nth-child(2) { background: #ffbd2e; }
  .pull-terminal-dots span:nth-child(3) { background: #27c93f; }
  .pull-terminal-title {
    flex: 1; font-family: var(--font-mono); font-size: 12px; color: #948DBA; text-align: center;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .pull-terminal-close {
    background: none; border: none; color: #948DBA; cursor: pointer; padding: 3px;
    display: flex; align-items: center; justify-content: center; border-radius: 4px; flex-shrink: 0;
  }
  .pull-terminal-close:hover { background: #332B57; color: #e6f7f2; }
  .pull-terminal-log {
    margin: 0; padding: 14px 16px;
    height: 260px; overflow-y: auto;
    font-family: var(--font-mono); font-size: 12px; line-height: 1.7;
    color: #D5D0E8; background: #141024;
    white-space: pre-wrap; word-break: break-all;
  }
  .pull-terminal-log::-webkit-scrollbar { width: 4px; }
  .pull-terminal-log::-webkit-scrollbar-thumb { background: #332B57; border-radius: 2px; }
  .pull-term-line.ok  { color: #7ee787; font-weight: 700; }
  .pull-term-line.err { color: #ff7b72; font-weight: 700; }
  .rec-cpu-note { font-size: 11.5px; color: var(--text-muted); margin: 2px 0 8px; }
  /* (i) spec help popover */
  .spec-help { display: inline-block; margin-left: auto; }
  .spec-help summary {
    list-style: none; cursor: pointer; width: 18px; height: 18px; border-radius: 50%;
    border: 1.5px solid var(--dc-blue); color: var(--dc-blue); font-size: 11px; font-weight: 800;
    font-style: italic; font-family: Georgia, serif;
    display: flex; align-items: center; justify-content: center;
  }
  .spec-help summary::-webkit-details-marker { display: none; }
  .spec-help[open] summary { background: var(--dc-blue); color: #fff; }
  .spec-help-body {
    position: absolute; right: 10px; top: 38px; z-index: 10;
    width: min(290px, calc(100% - 20px));
    background: var(--bg-panel); border: 1px solid var(--border); border-radius: 10px;
    box-shadow: var(--shadow-card); padding: 12px; font-size: 11.5px; line-height: 1.55;
    color: var(--text-secondary); font-weight: 500; text-transform: none; letter-spacing: 0;
  }
  .spec-help-body code, .spec-help-body kbd {
    font-family: var(--font-mono); font-size: 10.5px; background: var(--bg-secondary);
    border: 1px solid var(--border-light); border-radius: 4px; padding: 1px 4px;
  }

  /* ── CAMP GUIDE — floating + dockable book panel ──────────────── */
  .guide-panel {
    position: fixed;
    top: 74px;
    right: 18px;
    z-index: 600;
    width: 384px;
    max-width: calc(100vw - 24px);
    height: 580px;
    max-height: calc(100dvh - 92px);
    display: flex;
    flex-direction: column;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 16px;
    box-shadow: 0 24px 64px rgba(0,0,0,0.30);
    overflow: hidden;
    animation: slide-up 0.25s cubic-bezier(0.34,1.56,0.64,1);
  }
  .guide-panel[hidden] { display: none; }

  /* Docked: drop into the body flex flow as a right-side panel (VS Code style) */
  .guide-panel.docked {
    position: relative;
    top: auto; right: auto; left: auto !important;
    width: var(--guide-w, 384px);
    min-width: 240px;
    max-width: 80vw;
    height: auto;
    max-height: none;
    border-radius: 0;
    border-width: 0 0 0 1px;
    box-shadow: none;
    flex-shrink: 0;
    animation: none;
    transition: width 0.2s ease;
  }
  .gp-resizing .guide-panel.docked { transition: none; }   /* no lag while dragging */

  /* Resize splitter — draggable divider on the panel's left edge (docked only) */
  .gp-resizer { display: none; }
  .guide-panel.docked .gp-resizer {
    display: block;
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 7px;
    cursor: col-resize;
    z-index: 3;
  }
  .guide-panel.docked .gp-resizer::after {
    content: '';
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 2px;
    background: transparent;
    transition: background 0.15s;
  }
  .guide-panel.docked .gp-resizer:hover::after,
  .gp-resizing .guide-panel.docked .gp-resizer::after { background: var(--dc-blue); }
  [data-theme="dark"] .guide-panel.docked .gp-resizer:hover::after,
  [data-theme="dark"] .gp-resizing .guide-panel.docked .gp-resizer::after { background: var(--dc-accent); }
  .gp-resizing { cursor: col-resize; user-select: none; }

  .gp-head {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 10px 10px 14px;
    border-bottom: 1px solid var(--border-light);
    flex-shrink: 0;
    cursor: move;
    user-select: none;
    touch-action: none;
  }
  .guide-panel.docked .gp-head { cursor: default; }
  .gp-grip { display: flex; color: var(--text-muted); }
  .guide-panel.docked .gp-grip { display: none; }
  .gp-head-icon { display: flex; align-items: center; color: var(--text-secondary); }
  .gp-title { font-size: 13px; font-weight: 800; color: var(--text-primary); white-space: nowrap; }
  .gp-head-spacer { flex: 1; }
  .gp-btn {
    width: 27px; height: 27px;
    border: 1px solid var(--border);
    border-radius: 7px;
    background: none;
    cursor: pointer;
    color: var(--text-muted);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    transition: all 0.15s;
  }
  .gp-btn:hover { color: var(--text-primary); background: var(--border-light); border-color: var(--border); }
  .gp-btn.active { color: var(--dc-blue); border-color: var(--dc-blue); background: var(--dc-blue-light); }
  [data-theme="dark"] .gp-btn.active { color: var(--dc-accent); }

  .gp-tabs {
    display: flex; gap: 5px;
    padding: 9px 12px;
    border-bottom: 1px solid var(--border-light);
    overflow-x: auto;
    flex-shrink: 0;
    scrollbar-width: none;
  }
  .gp-tabs::-webkit-scrollbar { display: none; }
  .gp-tab {
    flex-shrink: 0;
    font-family: var(--font-main);
    font-size: 11px; font-weight: 700;
    color: var(--text-muted);
    background: var(--bg-secondary);
    border: 1px solid var(--border-light);
    border-radius: 999px;
    padding: 5px 11px;
    cursor: pointer;
    white-space: nowrap;
    transition: all 0.15s;
  }
  .gp-tab:hover { color: var(--text-primary); border-color: var(--border); }
  .gp-tab.active { background: var(--dc-blue); color: #fff; border-color: var(--dc-blue); }

  .gp-pages { flex: 1; overflow-y: auto; padding: 16px 16px 8px; }
  .gp-pages::-webkit-scrollbar { width: 4px; }
  .gp-pages::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
  .gp-page { display: none; animation: fade-in 0.2s ease; }
  .gp-page.active { display: block; }
  .gp-page-h {
    display: flex; align-items: center; gap: 9px;
    font-size: 15.5px; font-weight: 800;
    color: var(--text-primary);
    line-height: 1.2;
    margin-bottom: 5px;
  }
  .gp-chip {
    flex-shrink: 0;
    font-size: 10px; font-weight: 800; letter-spacing: 0.3px;
    color: var(--dc-blue);
    background: var(--dc-blue-light);
    border: 1px solid color-mix(in srgb, var(--dc-blue) 20%, transparent);
    border-radius: 6px;
    padding: 3px 7px;
  }
  [data-theme="dark"] .gp-chip { color: var(--dc-accent); background: color-mix(in srgb, var(--dc-blue) 15%, transparent); }
  .gp-chip.pre { color: var(--text-muted); background: var(--bg-secondary); border-color: var(--border-light); }
  .gp-page-sub { font-size: 12px; color: var(--text-muted); line-height: 1.55; margin-bottom: 14px; }
  .gp-map-row {
    display: flex; gap: 10px; align-items: flex-start;
    padding: 8px 0; border-bottom: 1px solid var(--border-light);
    font-size: 12.5px; color: var(--text-secondary); line-height: 1.5;
  }
  .gp-map-row:last-child { border-bottom: none; }
  .gp-map-row b { color: var(--dc-blue); font-weight: 800; flex-shrink: 0; width: 48px; }
  [data-theme="dark"] .gp-map-row b { color: var(--dc-accent); }

  .gp-foot {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 12px;
    border-top: 1px solid var(--border-light);
    flex-shrink: 0;
  }
  .gp-nav {
    display: inline-flex; align-items: center; gap: 5px;
    font-family: var(--font-main);
    font-size: 12.5px; font-weight: 700;
    border: 1px solid var(--border);
    border-radius: 9px;
    padding: 8px 12px;
    background: none;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.15s;
  }
  .gp-nav:hover:not(:disabled) { border-color: var(--dc-blue); color: var(--dc-blue); }
  .gp-nav:disabled { opacity: 0.4; cursor: not-allowed; }
  .gp-nav.primary { background: var(--dc-blue); color: #fff; border-color: var(--dc-blue); }
  .gp-nav.primary:hover:not(:disabled) { background: var(--dc-blue-dark); color: #fff; }
  .gp-progress { flex: 1; text-align: center; font-size: 11px; font-weight: 700; color: var(--text-muted); letter-spacing: 0.2px; }

  /* Guide panel — responsive */
  @media (max-width: 900px) {
    .guide-panel { width: 340px; }
    .guide-panel.docked { max-width: 60vw; }
  }
  @media (max-width: 640px) {
    /* Floating: near full-screen sheet */
    .guide-panel {
      top: 50px; right: 8px; left: 8px;
      width: auto;
      max-width: none;
      height: auto;
      bottom: 8px;
      max-height: none;
    }
    /* Docked: become an overlay drawer so it never crushes the chat */
    .guide-panel.docked {
      position: fixed;
      top: 0; right: 0; bottom: 0; left: auto !important;
      width: min(var(--guide-w, 384px), 90vw) !important;
      min-width: 0;
      max-width: 90vw;
      height: 100dvh;
      z-index: 600;
      border-left: 1px solid var(--border);
      box-shadow: -10px 0 40px rgba(0,0,0,0.28);
    }
    .guide-panel.docked .gp-resizer { display: none; }   /* no drag-resize on phones */
  }

  .wip-banner {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    background: #FEF9C3;
    border: 1px solid #FDE68A;
    border-radius: 10px;
    padding: 11px 13px;
    margin-bottom: 16px;
    font-size: 12px;
    color: #854D0E;
    line-height: 1.55;
  }
  .wip-banner svg { flex-shrink: 0; margin-top: 1px; }
  .wip-banner strong { font-weight: 800; }
  [data-theme="dark"] .wip-banner {
    background: rgba(133,77,14,0.18);
    border-color: rgba(133,77,14,0.4);
    color: #FCD34D;
  }
  .wip-pill {
    display: inline-block;
    background: #854D0E;
    color: #FEF9C3;
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    border-radius: 5px;
    padding: 1px 6px;
    margin-left: 6px;
    vertical-align: middle;
  }
  [data-theme="dark"] .wip-pill { background: #FCD34D; color: #422006; }

  /* Phase header (Before camp / Hour 1 … 4) */
  .guide-phase {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 22px 0 12px;
  }
  .guide-phase:first-of-type { margin-top: 4px; }
  .guide-phase-badge {
    flex-shrink: 0;
    min-width: 52px;
    text-align: center;
    background: var(--dc-blue);
    color: white;
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: 0.3px;
    border-radius: 7px;
    padding: 5px 8px;
    line-height: 1.1;
  }
  .guide-phase-badge.pre { background: var(--text-muted); }
  .guide-phase-title {
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.25;
  }
  .guide-phase-title small {
    display: block;
    font-size: 11px;
    font-weight: 500;
    color: var(--text-muted);
    margin-top: 1px;
  }

  /* Numbered step */
  .guide-step {
    display: flex;
    gap: 11px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border-light);
  }
  .guide-step:last-child { border-bottom: none; }
  .guide-step-num {
    flex-shrink: 0;
    width: 22px; height: 22px;
    border-radius: 50%;
    background: var(--dc-blue-light);
    border: 1px solid color-mix(in srgb, var(--dc-blue) 20%, transparent);
    color: var(--dc-blue);
    font-size: 11px;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 1px;
  }
  [data-theme="dark"] .guide-step-num { color: var(--dc-accent); background: color-mix(in srgb, var(--dc-blue) 15%, transparent); }
  .guide-step-body { flex: 1; min-width: 0; }
  .guide-step-body b {
    display: block;
    font-size: 13px;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 3px;
  }
  .guide-step-body p {
    font-size: 12.5px;
    color: var(--text-secondary);
    line-height: 1.6;
  }
  .guide-step-body p + p { margin-top: 5px; }
  .guide-step-body em { font-style: italic; color: var(--text-muted); }

  /* Inline command / code chip */
  .guide-cmd {
    display: block;
    background: var(--bg-primary);
    border: 1px solid var(--border-light);
    border-radius: 7px;
    padding: 7px 10px;
    margin-top: 6px;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 11.5px;
    color: var(--dc-blue);
    overflow-x: auto;
    white-space: pre;
  }
  [data-theme="dark"] .guide-cmd { color: var(--dc-accent); }
  .guide-step-body a { color: var(--dc-blue); font-weight: 600; text-decoration: none; }
  .guide-step-body a:hover { text-decoration: underline; }
  [data-theme="dark"] .guide-step-body a { color: var(--dc-accent); }

  .logo-wrapper {
    position: relative;
    display: inline-flex;
    cursor: default;
  }
  .sidebar-brand .logo-wrapper {
    flex: 1;
    min-width: 0;
  }

  /* ALIBABA CLOUD FOOTER (legacy) */
  .alibaba-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: linear-gradient(135deg, #FF6A00, #FF9A00);
    border-radius: 4px;
    padding: 1px 7px 1px 5px;
    font-size: 9px;
    font-weight: 800;
    color: white;
    letter-spacing: 0.4px;
    white-space: nowrap;
  }
  .alibaba-cloud-icon {
    display: inline-flex;
    opacity: 0.9;
  }

  /* SETTINGS MODAL */
  .settings-modal {
    position: fixed;
    inset: 0;
    background: rgba(2, 7, 18, 0.78);
    z-index: 500;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 16px;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    animation: fade-in 0.2s ease;
  }
  .settings-card {
    background: var(--bg-panel);
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    border-radius: 20px;
    width: 100%;
    max-width: 420px;
    max-height: 88dvh;
    overflow-y: auto;
    box-shadow: 0 24px 64px rgba(0,0,0,0.5), 0 0 30px rgba(0, 240, 255, 0.12);
    animation: slide-up 0.25s cubic-bezier(0.34,1.56,0.64,1);
    border: 1px solid var(--border);
  }
  .settings-card::-webkit-scrollbar { width: 3px; }
  .settings-card::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
  .settings-header {
    padding: 20px 22px 0;
    display: flex;
    align-items: center;
    gap: 12px;
    border-bottom: 1px solid var(--border-light);
    padding-bottom: 16px;
  }
  .settings-header-icon {
    width: 38px; height: 38px;
    background: var(--dc-blue-light);
    border: 1px solid color-mix(in srgb, var(--dc-blue) 18%, transparent);
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--dc-blue);
    flex-shrink: 0;
  }
  [data-theme="dark"] .settings-header-icon { background: color-mix(in srgb, var(--dc-blue) 15%, transparent); color: var(--dc-accent); }
  .settings-header-text { flex: 1; }
  .settings-header-text h2 {
    font-size: 15px;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 2px;
  }
  .settings-header-text p {
    font-size: 11px;
    color: var(--text-muted);
  }
  .settings-body { padding: 20px 22px; display: flex; flex-direction: column; gap: 18px; }
  .settings-field { display: flex; flex-direction: column; gap: 5px; }
  .settings-label {
    font-size: 11px;
    font-weight: 700;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.7px;
  }
  .settings-input {
    background: var(--bg-primary);
    border: 1.5px solid var(--border);
    border-radius: 8px;
    padding: 8px 11px;
    font-family: var(--font-main);
    font-size: 13px;
    color: var(--text-primary);
    outline: none;
    transition: border-color 0.2s;
    width: 100%;
  }
  .settings-input:focus { border-color: var(--dc-blue); }
  .settings-textarea {
    resize: vertical;
    min-height: 80px;
    max-height: 160px;
    line-height: 1.55;
  }
  .settings-hint {
    font-size: 10.5px;
    color: var(--text-muted);
    line-height: 1.5;
  }
  /* Guardrails: the rule is abstract until you see one refusal play out, so
     the field shows a worked example instead of explaining itself twice. */
  .guardrail-example {
    margin: 8px 0 6px;
    padding: 8px 10px;
    border: 1px solid var(--border-light);
    border-radius: 8px;
    background: var(--bg-secondary);
    display: flex;
    flex-direction: column;
    gap: 5px;
  }
  .guardrail-example-row {
    display: flex;
    gap: 8px;
    align-items: baseline;
    font-size: 11px;
    line-height: 1.45;
    color: var(--text-secondary);
  }
  .guardrail-example-tag {
    flex: 0 0 74px;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
  }
  .guardrail-example-row:last-child span:last-child {
    color: var(--text-primary);
    font-weight: 600;
  }
  /* Model-control sliders */
  .slider-head { display: flex; align-items: center; justify-content: space-between; }
  .slider-value {
    font-size: 12px;
    font-weight: 700;
    color: var(--dc-blue);
    font-variant-numeric: tabular-nums;
  }
  [data-theme="dark"] .slider-value { color: var(--dc-accent); }
  .settings-slider {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 4px;
    border-radius: 3px;
    background: var(--border);
    outline: none;
    margin: 4px 0 2px;
    cursor: pointer;
  }
  .settings-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--dc-blue);
    border: 2px solid var(--bg-card, #fff);
    box-shadow: 0 1px 3px rgba(0,0,0,0.25);
    cursor: pointer;
  }
  .settings-slider::-moz-range-thumb {
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--dc-blue);
    border: 2px solid var(--bg-card, #fff);
    cursor: pointer;
  }
  [data-theme="dark"] .settings-slider::-webkit-slider-thumb { background: var(--dc-accent); }
  [data-theme="dark"] .settings-slider::-moz-range-thumb { background: var(--dc-accent); }
  .slider-scale {
    display: flex;
    font-size: 10px;
    color: var(--text-muted);
    margin-top: 3px;
  }
  .slider-scale span { flex: 1; }
  .slider-scale span:first-child { text-align: left; }
  .slider-scale span:last-child { text-align: right; }
  .slider-scale span:not(:first-child):not(:last-child) { text-align: center; }
  /* Persona controls */
  .persona-select-row { display: flex; gap: 8px; align-items: stretch; }
  .persona-select-row select { flex: 1; min-width: 0; cursor: pointer; }
  .persona-new-btn {
    flex: 0 0 auto;
    padding: 0 14px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
    background: var(--bg-input, transparent);
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    font-family: var(--font-main);
    transition: all 0.15s;
    white-space: nowrap;
  }
  .persona-new-btn:hover { border-color: var(--dc-blue); color: var(--dc-blue); }
  .persona-prompt-wrap { position: relative; }
  .persona-expand-btn {
    position: absolute;
    right: 8px;
    bottom: 8px;
    padding: 5px 11px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--dc-blue);
    background: var(--bg-card, #fff);
    border: 1px solid var(--border);
    border-radius: 7px;
    cursor: pointer;
    font-family: var(--font-main);
    transition: all 0.15s;
  }
  .persona-expand-btn:hover { border-color: var(--dc-blue); background: var(--dc-blue); color: #fff; }
  .persona-expand-btn:disabled { opacity: 0.6; cursor: default; }
  [data-theme="dark"] .persona-expand-btn { color: var(--dc-accent); }
  [data-theme="dark"] .persona-expand-btn:hover { background: var(--dc-accent); color: #fff; border-color: var(--dc-accent); }
  .persona-delete-btn {
    align-self: flex-start;
    margin-top: 4px;
    padding: 0;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-main);
  }
  .persona-delete-btn:hover { color: #DC2626; text-decoration: underline; }
  .color-row {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
  }
  .color-pick-wrap {
    display: flex;
    align-items: center;
    gap: 7px;
    background: var(--bg-primary);
    border: 1.5px solid var(--border);
    border-radius: 8px;
    padding: 5px 10px 5px 7px;
    cursor: pointer;
    flex: 1;
    min-width: 120px;
    transition: border-color 0.2s;
  }
  .color-pick-wrap:focus-within { border-color: var(--dc-blue); }
  .color-pick-wrap input[type="color"] {
    width: 22px; height: 22px;
    border: none;
    background: none;
    padding: 0;
    cursor: pointer;
    border-radius: 4px;
    flex-shrink: 0;
  }
  .color-pick-label {
    font-size: 11.5px;
    color: var(--text-secondary);
    font-weight: 500;
    flex: 1;
  }
  .color-swatch-row { display: flex; gap: 5px; flex-wrap: wrap; }
  .color-swatch {
    width: 20px; height: 20px;
    border-radius: 5px;
    border: 2px solid transparent;
    cursor: pointer;
    transition: transform 0.15s, border-color 0.15s;
    outline: none;
  }
  .color-swatch:hover { transform: scale(1.2); }
  .color-swatch.active { border-color: var(--text-primary); }
  .settings-divider {
    border: none;
    border-top: 1px solid var(--border-light);
    margin: 0;
  }
  .settings-footer {
    padding: 14px 22px 20px;
    border-top: 1px solid var(--border-light);
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .settings-footer-row {
    display: flex;
    gap: 8px;
  }
  .settings-btn-secondary {
    flex: 1;
    padding: 9px;
    background: none;
    border: 1.5px solid var(--border);
    border-radius: 8px;
    font-family: var(--font-main);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.15s;
  }
  .settings-btn-secondary:hover { border-color: var(--dc-blue); color: var(--dc-blue); }
  .settings-btn-primary {
    width: 100%;
    padding: 11px;
    background: var(--dc-blue);
    border: none;
    border-radius: 8px;
    font-family: var(--font-main);
    font-size: 13px;
    font-weight: 700;
    color: white;
    cursor: pointer;
    transition: background 0.15s;
  }
  .settings-btn-primary:hover { background: var(--dc-blue-dark); }
  .settings-reset-btn {
    flex: 1;
    padding: 9px;
    background: none;
    border: 1.5px solid var(--border);
    border-radius: 8px;
    font-family: var(--font-main);
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    transition: all 0.15s;
    text-align: center;
  }
  .settings-reset-btn:hover { border-color: var(--border); color: var(--text-secondary); }

  /* TOAST */
  .lang-picker { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
  .lang-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 11px; font-size: 12px; font-weight: 600;
    background: var(--bg-secondary); color: var(--text-secondary);
    border: 1px solid var(--border-light); border-radius: 999px;
    cursor: pointer; font-family: var(--font-main);
    transition: all 0.15s;
  }
  .lang-chip:hover:not(.disabled):not(.active) { border-color: var(--dc-blue); color: var(--dc-blue); }
  .lang-chip.active { background: var(--dc-blue); color: #fff; border-color: var(--dc-blue); }
  .lang-chip.disabled { opacity: 0.55; cursor: not-allowed; }
  .lang-badge {
    font-size: 9.5px; font-weight: 800; letter-spacing: 0.5px;
    padding: 2px 5px; border-radius: 4px; line-height: 1;
  }
  .lang-badge.beta { background: #FEF3C7; color: #92400E; }
  .lang-badge.soon { background: #FDE68A; color: #78350F; }
  .lang-chip.active .lang-badge.beta { background: rgba(255,255,255,0.25); color: #fff; }

  #training-dropzone:hover, #training-dropzone.drag { border-color: var(--dc-blue); color: var(--text-primary); background: color-mix(in srgb, var(--dc-blue) 4%, transparent); }
  .training-file-item {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 10px; border: 1px solid var(--border-light); border-radius: 8px;
    background: var(--bg-secondary); font-size: 12.5px;
  }
  .training-file-item .tf-name { flex: 1; font-weight: 600; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .training-file-item .tf-size { color: var(--text-muted); font-size: 11.5px; }
  .training-file-item .tf-remove {
    background: none; border: none; color: var(--text-muted); cursor: pointer;
    padding: 4px 6px; border-radius: 4px; font-size: 14px; line-height: 1;
  }
  .training-file-item .tf-remove:hover { background: var(--border-light); color: #DC2626; }

  .settings-toast {
    position: fixed;
    bottom: 80px;
    left: 50%;
    transform: translateX(-50%) translateY(10px);
    background: #1A7A45;
    color: white;
    border-radius: 20px;
    padding: 8px 18px;
    font-size: 12.5px;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 7px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.2);
    opacity: 0;
    transition: opacity 0.2s, transform 0.2s;
    z-index: 9999;
    pointer-events: none;
    white-space: nowrap;
  }
  .settings-toast.visible { opacity: 1; transform: translateX(-50%) translateY(0); }
  .toast-icon { display: flex; flex-shrink: 0; opacity: 0.9; }

  /* SETTINGS PREVIEW CARD */
  .settings-preview-card {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--bg-primary);
    border: 1.5px solid var(--border);
    border-radius: 12px;
    padding: 12px 14px;
  }
  .preview-avatar {
    width: 42px; height: 42px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--dc-blue) 0%, color-mix(in srgb, var(--dc-blue) 73%, transparent) 100%);
    color: #fff;
    font-size: 14px;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    letter-spacing: 0.5px;
    transition: background 0.2s;
    overflow: hidden;
  }
  .preview-info { flex: 1; min-width: 0; }

  /* Profile picture control (Personalize tab).
     Round, because round is the only shape this picture is ever seen in — the
     squircle preview was quietly promising a crop the conversation never uses,
     so a face that fit here could still lose its ears in chat. */
  .settings-avatar-row {
    display: flex;
    align-items: center;
    gap: 14px;
  }
  .avatar-drop {
    position: relative;
    width: 56px; height: 56px;
    flex-shrink: 0;
    padding: 0;
    border: none;
    background: none;
    border-radius: 50%;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .avatar-drop:focus-visible { outline: 2px solid var(--dc-blue); outline-offset: 3px; }
  .settings-avatar-preview {
    width: 56px; height: 56px;
    border-radius: 50%;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    color: #fff;
    font-size: 18px;
    font-weight: 800;
    letter-spacing: 0.5px;
    box-shadow: 0 2px 8px rgba(22,32,46,0.14);
    transition: filter 0.15s, box-shadow 0.15s;
  }
  .avatar-drop:hover .settings-avatar-preview { filter: brightness(0.9); }
  /* The badge is the affordance: without it a bare picture is just a picture,
     and the only way to learn it was clickable was to click it. */
  .avatar-drop-badge {
    position: absolute;
    right: -1px; bottom: -1px;
    width: 22px; height: 22px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    color: var(--text-secondary);
    transition: color 0.15s, border-color 0.15s;
  }
  .avatar-drop:hover .avatar-drop-badge { color: var(--dc-blue); border-color: var(--dc-blue); }
  .settings-avatar-preview .avatar-img,
  .preview-avatar .avatar-img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
  }
  .settings-avatar-text {
    display: flex;
    flex-direction: column;
    gap: 7px;
    min-width: 0;
  }
  .settings-avatar-btns { display: flex; gap: 8px; }
  /* Remove is destructive and rarely what you came for, so it doesn't get the
     same outline as Upload — it stays quiet until you're on it, then commits
     to red rather than pretending the click is reversible. */
  .avatar-remove-btn {
    flex: 0 0 auto;
    padding: 0 12px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    background: none;
    border: 1px solid transparent;
    border-radius: 8px;
    cursor: pointer;
    font-family: var(--font-main);
    transition: all 0.15s;
    white-space: nowrap;
  }
  .avatar-remove-btn:hover {
    color: var(--danger);
    border-color: var(--danger-edge);
    background: var(--danger-tint);
  }
  .preview-greeting {
    font-size: 11px;
    color: var(--text-muted);
    margin-bottom: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .preview-name {
    font-size: 14px;
    font-weight: 700;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .preview-label {
    font-size: 10px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.8px;
    margin-left: auto;
    flex-shrink: 0;
    align-self: flex-start;
    padding-top: 2px;
  }

  /* TONE PRESET CHIPS */
  .tone-presets {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    margin-bottom: 2px;
  }
  .tone-preset-chip {
    padding: 7px 4px;
    background: var(--bg-primary);
    border: 1.5px solid var(--border);
    border-radius: 8px;
    font-family: var(--font-main);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.15s;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .tone-preset-chip:hover { border-color: var(--dc-blue); color: var(--dc-blue); }
  .tone-preset-chip.active {
    background: var(--dc-blue-light);
    border-color: var(--dc-blue);
    color: var(--dc-blue);
  }
  [data-theme="dark"] .tone-preset-chip.active { background: color-mix(in srgb, var(--dc-blue) 18%, transparent); }

  /* ── ICON RAIL ────────────────────────────────────────────────────── */
  .icon-rail {
    width: 58px;
    background: var(--bg-sidebar);
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    border: 1px solid var(--sb-border);
    border-right-color: transparent;
    border-radius: var(--radius-lg) 0 0 var(--radius-lg);
    margin: 10px 0 10px 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 14px 0 12px;
    gap: 6px;
    flex-shrink: 0;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
    z-index: 110;
    /* Snaps back to the square/joined shape as soon as the sidebar starts
       reopening — no delay, since the sidebar is visible from frame one. */
    transition: border-radius 0.15s ease, border-right-color 0.15s ease;
  }
  /* Sidebar panel collapsed — nothing left for the rail's right edge to
     join, so it becomes a standalone rounded pill instead of half-square.
     Delayed to start after the sidebar's own width/margin collapse
     (0.25s) has mostly finished, so the rail doesn't round off early
     while the still-shrinking sidebar is sitting flush against it. */
  .icon-rail:has(+ .sidebar.collapsed) {
    border-right-color: var(--sb-border);
    border-radius: var(--radius-lg);
    transition: border-radius 0.15s ease 0.2s, border-right-color 0.15s ease 0.2s;
  }
  .rail-toggle-btn { margin-bottom: 8px; }
  .rail-btn {
    width: 40px; height: 40px;
    border-radius: 12px;
    border: none; background: transparent;
    color: var(--sb-text-dim);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    position: relative;
    transition: all 0.15s;
    flex-shrink: 0;
  }
  .rail-btn:hover { color: var(--sb-text-strong); background: var(--sb-hover-bg); }
  .rail-btn.active {
    color: #ffffff;
    background: rgba(0, 240, 255, 0.16);
    box-shadow: 0 0 14px rgba(0, 240, 255, 0.2);
  }
  .rail-btn.active::before {
    content: '';
    position: absolute; left: -9px; top: 10px; bottom: 10px;
    width: 3px; border-radius: 3px;
    background: linear-gradient(to bottom, #00ff87, #00f0ff);
    box-shadow: 0 0 8px #00f0ff;
  }
  .rail-spacer { flex: 1; }
  .rail-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    margin: 4px 0 8px;
    flex-shrink: 0;
  }
  .rail-dot.ok {
    background: #00ff87;
    box-shadow: 0 0 10px rgba(0, 255, 135, 0.6), 0 0 18px rgba(0, 240, 255, 0.3);
  }
  .rail-dot.err { background: #EF4444; box-shadow: 0 0 0 4px rgba(239,68,68,0.15); }
  .rail-dot.checking { background: #F59E0B; box-shadow: 0 0 0 4px rgba(245,158,11,0.15); animation: pulse 1s infinite; }
  @media (max-width: 640px) { .icon-rail { display: none; } }

  /* ── MOBILE SIDEBAR TRIGGERS — stand in for the icon rail, which is
     hidden below 640px. One floats over the welcome screen (which has no
     header at all); the other lives inside the header once a chat starts. */
  .mobile-menu-btn, .header-menu-btn { display: none; }
  @media (max-width: 640px) {
    .mobile-menu-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      position: fixed;
      top: 12px; left: 12px;
      width: 38px; height: 38px;
      border-radius: 10px;
      border: 1px solid var(--border);
      background: var(--bg-panel);
      color: var(--text-secondary);
      z-index: 90;
      box-shadow: 0 2px 10px rgba(0,0,0,0.15);
      cursor: pointer;
    }
    /* Hide it once a conversation's header (with its own trigger) is showing,
       or while the drawer is already open. */
    body:has(.main:not(.welcome-mode)) .mobile-menu-btn,
    body:has(.sidebar.open) .mobile-menu-btn { display: none; }

    .header-menu-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 32px; height: 32px;
      border-radius: 8px;
      border: none;
      background: none;
      color: var(--text-secondary);
      cursor: pointer;
      flex-shrink: 0;
    }
    .header-menu-btn:hover { background: var(--border-light); color: var(--text-primary); }
  }

  /* Rail replaces these header buttons on desktop */
  @media (min-width: 641px) {
    .icon-btn[title^="Camp Guide"],
    .icon-btn[title="Personalize AI"],
    .icon-btn[title="Toggle theme"] { display: none; }
  }

  /* ── SIDEBAR COLLAPSE TOGGLE (desktop only — mobile uses the drawer) ── */
  .sidebar-collapse-btn {
    width: 26px; height: 26px;
    border-radius: 7px;
    border: none;
    background: transparent;
    color: var(--sb-text-dim);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
    transition: all 0.15s;
  }
  .sidebar-collapse-btn:hover { background: var(--sb-hover-bg); color: var(--sb-text-strong); }
  @media (max-width: 640px) { .sidebar-collapse-btn { display: none; } }

  /* ── SEGMENTED TABS (Chats / Sources) ────────────────────────────── */
  .seg-tabs {
    display: flex;
    gap: 4px;
    margin: 4px 12px 6px;
    background: rgba(0, 240, 255, 0.08);
    border: 1px solid rgba(0, 240, 255, 0.16);
    border-radius: 11px;
    padding: 3px;
    flex-shrink: 0;
  }
  .seg-tabs button {
    flex: 1;
    border: none;
    border-radius: 9px;
    background: transparent;
    font-family: var(--font-main);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--sb-text-dim);
    padding: 7px 0;
    cursor: pointer;
    transition: all 0.2s;
  }
  .seg-tabs button.on {
    background: linear-gradient(135deg, rgba(0, 255, 135, 0.18) 0%, rgba(0, 240, 255, 0.22) 100%);
    color: #ffffff;
    box-shadow: 0 2px 10px rgba(0, 240, 255, 0.2), inset 0 0 10px rgba(0, 255, 135, 0.1);
  }
  [data-theme="dark"] .seg-tabs button.on {
    background: linear-gradient(135deg, rgba(0, 255, 135, 0.22) 0%, rgba(0, 240, 255, 0.25) 100%);
  }
  #sidebar[data-tab="sources"] .sidebar-section,
  #sidebar[data-tab="sources"] .history-list { display: none; }
  #sidebar[data-tab="chats"] #kb-panel { display: none; }
  .sidebar.collapsed .seg-tabs,
  .sidebar.collapsed #kb-panel { display: none; }

  /* ── SOURCES PANEL ────────────────────────────────────────────────── */
  #kb-panel {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    padding: 4px 8px 8px;
    border-radius: 12px;
    transition: box-shadow 0.3s;
  }
  #kb-panel.flash { box-shadow: 0 0 0 2px var(--dc-blue); }
  .kb-head {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 8px 8px 6px;
    flex-shrink: 0;
  }
  .kb-title {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1.1px;
    text-transform: uppercase;
    color: var(--text-muted);
  }
  .kb-total {
    font-size: 9.5px;
    font-weight: 700;
    color: var(--text-muted);
    background: var(--border-light);
    border-radius: 10px;
    padding: 1px 7px;
  }
  .kb-add {
    margin-left: auto;
    border: 1px dashed var(--border);
    background: transparent;
    color: var(--dc-blue);
    font-family: var(--font-main);
    font-size: 10.5px;
    font-weight: 700;
    border-radius: 8px;
    padding: 3px 9px;
    cursor: pointer;
    transition: all 0.15s;
    white-space: nowrap;
  }
  .kb-add:hover { background: var(--dc-blue-light); border-color: var(--dc-blue); }
  [data-theme="dark"] .kb-add { color: var(--dc-blue-tint); }
  [data-theme="dark"] .kb-add:hover { background: color-mix(in srgb, var(--dc-blue) 18%, transparent); }
  .kb-list {
    overflow-y: auto;
    flex: 1;
    min-height: 60px;
    display: flex;
    flex-direction: column;
    gap: 1px;
  }
  .kb-list::-webkit-scrollbar { width: 3px; }
  .kb-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
  .kb-empty {
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.55;
    padding: 8px 10px 10px;
  }
  .kb-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 8px;
    border-radius: 9px;
    cursor: pointer;
    transition: background 0.12s;
    user-select: none;
  }
  .kb-item:hover { background: var(--bg-primary); }
  [data-theme="dark"] .kb-item:hover { background: rgba(255,255,255,0.04); }
  .kb-item.off { opacity: 0.45; }
  .kb-ico {
    width: 26px; height: 26px;
    border-radius: 7px;
    background: var(--border-light);
    display: flex; align-items: center; justify-content: center;
    font-size: 12px;
    flex-shrink: 0;
  }
  .kb-meta { flex: 1; min-width: 0; }
  .kb-meta b {
    display: block;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .kb-meta i {
    font-style: normal;
    font-size: 9.5px;
    color: var(--text-muted);
  }
  .kb-del {
    display: none;
    border: none; background: none;
    color: var(--text-muted);
    font-size: 11px;
    padding: 2px 5px;
    border-radius: 5px;
    cursor: pointer;
    flex-shrink: 0;
    line-height: 1;
  }
  .kb-item:hover .kb-del { display: block; }
  .kb-del:hover { color: #DC2626; background: rgba(220,38,38,0.1); }
  .kb-item input[type="checkbox"] {
    width: 14px; height: 14px;
    accent-color: var(--dc-blue);
    cursor: pointer;
    flex-shrink: 0;
  }

  /* ── FROSTED AURORA CHAT BUBBLES ──────────────────────────────── */
  .bubble.ai {
    background: transparent;
    border: none;
    box-shadow: none;
    border-radius: 0;
    padding: 4px 0 0;
    color: var(--text-primary);
  }
  .bubble.user {
    background: linear-gradient(135deg, rgba(0, 240, 255, 0.12) 0%, rgba(139, 92, 246, 0.14) 100%);
    color: var(--text-primary);
    border: 1px solid rgba(0, 240, 255, 0.28);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    font-weight: 500;
    border-radius: 20px 4px 20px 20px;
    padding: 10px 15px;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.15), 0 0 12px rgba(0, 240, 255, 0.08);
  }
  [data-theme="dark"] .bubble.user {
    background: linear-gradient(135deg, rgba(0, 240, 255, 0.16) 0%, rgba(139, 92, 246, 0.18) 100%);
    border-color: rgba(0, 240, 255, 0.35);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35), 0 0 16px rgba(0, 240, 255, 0.12);
  }

  /* Centered document column + composer — .message-row/.message-time/
     .msg-meta-wrap/.error-bubble are appended directly as #chat-area
     children (no wrapping group element), so each is centered individually */
  .message-row,
  .message-time,
  .error-bubble {
    max-width: 720px;
    width: 100%;
    margin-left: auto;
    margin-right: auto;
  }
  /* Keep its 42px indent (aligns under the bubble text, not the avatar) —
     use padding instead of margin-left so centering math still works */
  .msg-meta-wrap {
    max-width: 720px;
    width: 100%;
    margin-left: auto;
    margin-right: auto;
    padding-left: 42px;
  }
  /* Popover positions from the wrapper's own edge, before the padding —
     shift it to match the now-padded meta text it hangs off of */
  .msg-meta-wrap .msg-stats-popover { left: 42px; }
  .input-box {
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
    border-radius: 20px;
    box-shadow: 0 10px 34px rgba(22,32,46,0.08);
  }
  [data-theme="dark"] .input-box { box-shadow: 0 10px 34px rgba(0,0,0,0.45); }
  .input-tip, .legal-disclaimer-inner { max-width: 720px; margin-left: auto; margin-right: auto; }

/* ── PUBLISHED / VISITOR MODE ─────────────────────────────────────────
   A student's deployed AI: usable by anyone, editable by no one. The
   owner-only chrome is REMOVED from the DOM by lockVisitorUI() (see
   app/publish.js) — this rule is the safety net for anything rendered
   after that sweep, e.g. the welcome screen, which re-renders on every
   new conversation. */
body.visitor-mode [data-owner-only]:not([data-visitor-ok]) { display: none !important; }

/* Credit + the honesty line. The camp teaches "free, private, no subscription";
   this public copy answers through a hosted model, and saying so is the
   difference between proving the lesson and contradicting it. */




.welcome-credit {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 8px 18px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--dc-gold) 45%, transparent);
  background: color-mix(in srgb, var(--dc-gold) 11%, transparent);
  line-height: 1.15;
}
.welcome-credit-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-secondary);
  white-space: nowrap;
}
.welcome-credit-name {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.3px;
  color: var(--text-primary);
}
.welcome-credit-note {
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.05px;
}
@media (max-width: 640px) {
  .welcome-credit { padding: 7px 14px; gap: 7px; }
  .welcome-credit-name { font-size: 15px; }
  .welcome-credit-note { font-size: 11px; }
}

/* Read-only source rows — no remove button, no include/exclude checkbox */
body.visitor-mode .kb-item { cursor: default; }

/* ── PUBLISH TAB (owner side) ─────────────────────────────────────────── */
.publish-row {
  display: grid;
  grid-template-columns: 108px 1fr;
  gap: 8px;
  padding: 7px 10px;
  font-size: 12.5px;
  border-bottom: 1px solid var(--border-light);
}
.publish-row:last-child { border-bottom: none; }
.publish-row b { font-weight: 700; color: var(--text-secondary); }
.publish-row span { color: var(--text-primary); }
#publish-summary {
  border: 1px solid var(--border-light);
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 12px;
}
/* Rows that report a gap link to the tab that fixes it, so the summary is a
   starting point rather than a verdict. */
.publish-link {
  color: var(--dc-blue);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.publish-link:hover { text-decoration-thickness: 2px; }
.publish-warn { color: var(--danger); font-weight: 600; }




