/* ═══════════════════════════════════════════════════════
   DESKLOG AI CHAT — Refined timeline design
   Brand: var(--primary-color) #81B504 | var(--secondary-color) #045ba0
   Layout: left sidebar (brand + sessions) + main column
   (header / messages timeline / credit banner / composer).
   Dark mode = body.dark-mode; most colors flow through the
   --ai-* custom properties re-declared under body.dark-mode.
   ═══════════════════════════════════════════════════════ */

/* ─── Design Tokens ─────────────────────────────────── */
:root {
    --ai-green: #81B504;
    --ai-green-dark: #628a03;
    --ai-green-light: #9ada05;
    --ai-green-soft: rgba(129, 181, 4, 0.10);
    --ai-green-glow: rgba(129, 181, 4, 0.45);   /* empty-state mascot drop-shadow + resting glow */
    /* "Waiting on you" beam — the light that travels around a card the chat cannot
       move past until it is answered (see the beam section at the foot of this file).
       core = the head of the comet, tail = what trails behind it, void = the same
       green at zero alpha so the fade never interpolates through grey. */
    --ai-beam-core: #9ada05;
    --ai-beam-tail: rgba(129, 181, 4, 0.50);
    --ai-beam-void: rgba(129, 181, 4, 0);
    --ai-beam-halo: 0.40;      /* bloom opacity — lower in the light theme, it reads on white */
    --ai-beam-lap: 3.4s;       /* one lap of the border */
    --ai-blue: #045ba0;
    --ai-blue-dark: #024173;
    --ai-blue-light: #0673c9;
    /* Surfaces */
    --ai-surface: #fafafa;          /* header / input area / modals */
    --ai-surface-alt: #f4f6f8;      /* messages backdrop (app family) */
    --ai-sidebar-bg: rgba(4, 91, 160, 0.07);   /* sessions sidebar — same soft blue as the user bubble */
    --ai-card: #ffffff;             /* cards: tables, suggestions, packs */
    --ai-card-alt: #f3f9fc;         /* table header, kbd, skeletons */
    /* Lines & text */
    --ai-border: #e3eef4;
    --ai-border-strong: #d7e6ee;
    --ai-text: #17323f;
    --ai-text-body: #33505e;
    --ai-text-muted: #7a95a3;
    --ai-text-faint: #869cab;
    /* Accents */
    --ai-bubble-user: linear-gradient(135deg, rgba(4, 91, 160, 0.85) 0%, rgba(2, 63, 110, 0.85) 100%);
    --ai-danger: #dc2626;
    /* Depth */
    --ai-shadow-sm: 0 1px 3px rgba(9, 52, 77, 0.06);
    --ai-shadow-md: 0 8px 24px rgba(9, 52, 77, 0.10);
    --ai-shadow-lg: 0 24px 56px rgba(4, 42, 68, 0.22);
    --ai-radius: 14px;
    --ai-radius-lg: 18px;
    --ai-radius-sm: 10px;
    --ai-transition: 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Dark theme — swap the palette, every var consumer follows. */
body.dark-mode {
    --ai-green-soft: rgba(129, 181, 4, 0.09);
    --ai-green-glow: rgba(129, 181, 4, 0.22);
    /* Neon reads brighter and blooms harder on the dark card. */
    --ai-beam-core: #cdff5c;
    --ai-beam-tail: rgba(154, 218, 5, 0.55);
    --ai-beam-void: rgba(154, 218, 5, 0);
    --ai-beam-halo: 0.70;
    --ai-surface: #01101c;
    --ai-surface-alt: #010e18;
    --ai-sidebar-bg: #000d16;
    --ai-card: #021d31;
    --ai-card-alt: #04283f;
    --ai-border: rgba(255, 255, 255, 0.07);
    --ai-border-strong: rgba(255, 255, 255, 0.14);
    --ai-text: #dde9ef;
    --ai-text-body: #b9cdd7;
    --ai-text-muted: #7d98a5;
    --ai-text-faint: #64808d;
    --ai-bubble-user: linear-gradient(135deg, rgba(10, 103, 178, 0.5) 0%, rgba(3, 64, 110, 0.5) 100%);
    --ai-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35);
    --ai-shadow-md: 0 8px 24px rgba(0, 0, 0, 0.45);
    --ai-shadow-lg: 0 24px 56px rgba(0, 0, 0, 0.6);
}

/* ─── Header Trigger Button (app navbar) ────────────── */
.ai-header-trigger {
    display: flex !important;
    align-items: center;
    height: 50px;
    padding: 0 10px !important;
    cursor: pointer;
    position: relative;
    text-decoration: none !important;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

.ai-header-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    min-width: 30px;
    height: 30px;
    background: linear-gradient(135deg, var(--ai-green), var(--ai-green-dark));
    color: #fff;
    border-radius: 50%;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.5px;
    box-shadow: 0 2px 8px rgba(129, 181, 4, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.25);
    transition: transform var(--ai-transition), box-shadow var(--ai-transition);
    position: relative;
}

/* White robot glyph on the green circle */
.ai-header-icon img {
    width: 18px;
    height: 18px;
    object-fit: contain;
}

/* Red pulse dot removed — BETA badge now serves as the attention signal */

@keyframes aiPulse {

    0%,
    100% {
        opacity: 1;
        transform: scale(1);
    }

    50% {
        opacity: 0.5;
        transform: scale(0.85);
    }
}

.ai-header-trigger:hover .ai-header-icon,
.ai-header-trigger:focus .ai-header-icon {
    transform: scale(1.12) translateY(-1px);
    box-shadow: 0 4px 16px rgba(129, 181, 4, 0.45);
}

/* ─── Overlay ───────────────────────────────────────── */
.ai-chat-overlay {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 10001;
    background: rgba(2, 32, 54, 0.42);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    display: flex;
    justify-content: flex-end;
    animation: aiOverlayIn 0.25s ease-out;
}

@keyframes aiOverlayIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

/* ─── Panel (right drawer) ──────────────────────────── */
.ai-chat-panel {
    width: 100%;
    max-width: 720px;
    height: 100%;
    background: var(--ai-surface-alt);
    /* No left border — the pale --ai-border rendered as a stark white line
       against the dark blurred scrim in light mode. The drop-shadow below
       already separates the drawer from the page behind it. */
    box-shadow: -24px 0 64px rgba(2, 32, 54, 0.18);
    display: flex;
    flex-direction: row;
    overflow: hidden;
    animation: aiSlideIn 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
    position: relative;
}

@keyframes aiSlideIn {
    from {
        transform: translateX(60px);
        opacity: 0;
    }

    to {
        transform: translateX(0);
        opacity: 1;
    }
}

.ai-chat-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* ═══════════════════════════════════════════════════════
   SIDEBAR — brand block, new chat, session history
   ═══════════════════════════════════════════════════════ */
.ai-chat-sidebar {
    width: 232px;
    flex: 0 0 232px;
    display: flex;
    flex-direction: column;
    background: var(--ai-sidebar-bg);
    border-right: 1px solid var(--ai-border);
    overflow: hidden;
    transition: flex-basis var(--ai-transition), width var(--ai-transition), opacity var(--ai-transition);
}

/* Collapsed (desktop): squeeze to zero width, fade out */
.ai-chat-panel.ai-chat-sidebar-collapsed .ai-chat-sidebar {
    flex-basis: 0;
    width: 0;
    opacity: 0;
    border-right-width: 0;
    pointer-events: none;
}

/* Brand block */
.ai-chat-sidebar-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 14px 10px;
    flex-shrink: 0;
}

/* The chatbot glyph is white-on-transparent, so every logo tile
   sits on a brand-green gradient. */
.ai-chat-brand-logo {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--ai-green), var(--ai-green-dark));
    box-shadow: 0 3px 10px rgba(129, 181, 4, 0.3);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.ai-chat-brand-logo img {
    width: 22px;
    height: 22px;
    object-fit: contain;
}

.ai-chat-brand-text {
    flex: 1;
    min-width: 0;
}

.ai-chat-brand-name {
    font-size: 13.5px;
    font-weight: 700;
    color: var(--ai-text);
    line-height: 1.2;
    white-space: nowrap;
}

.ai-chat-brand-sub {
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--ai-text-faint);
    margin-top: 2px;
    white-space: nowrap;
}

.ai-chat-sidebar-toggle {
    width: 26px;
    height: 26px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--ai-text-faint);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    flex-shrink: 0;
    transition: all var(--ai-transition);
    touch-action: manipulation;
}

.ai-chat-sidebar-toggle:hover {
    background: var(--ai-card);
    color: var(--ai-text-body);
}

/* New chat */
.ai-chat-sidebar-header {
    padding: 4px 14px 12px;
    border-bottom: 1px solid var(--ai-border);
    flex-shrink: 0;
}

.ai-chat-new-btn {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 14px;
    background: var(--ai-card);
    border: 1px solid rgba(129, 181, 4, 0.35);
    border-radius: 12px;
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    color: var(--ai-text);
    cursor: pointer;
    box-shadow: none;
    transition: all var(--ai-transition);
    touch-action: manipulation;
}

.ai-chat-new-btn i {
    font-size: 12px;
    color: var(--ai-green-dark);
}

/* Neutral hover — no green glow, just a soft surface lift */
.ai-chat-new-btn:hover {
    border-color: var(--ai-border-strong);
    color: var(--ai-text);
    background: var(--ai-card-alt);
    transform: translateY(-1px);
}

.ai-chat-new-btn:active {
    transform: translateY(0);
}

/* Sessions list */
.ai-chat-sessions {
    flex: 1;
    overflow-y: auto;
    padding: 4px 10px 14px;
    -webkit-overflow-scrolling: touch;
}

.ai-chat-sessions::-webkit-scrollbar {
    width: 5px;
}

.ai-chat-sessions::-webkit-scrollbar-thumb {
    background: var(--ai-border-strong);
    border-radius: 4px;
}

.ai-chat-sessions-group {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--ai-text-faint);
    margin: 14px 6px 6px;
}

.ai-chat-session {
    position: relative;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 12px;
    border-radius: 12px;
    border: 1px solid transparent;
    cursor: pointer;
    color: var(--ai-text-body);
    font-size: 13px;
    margin-bottom: 3px;
    transition: background var(--ai-transition), border-color var(--ai-transition), box-shadow var(--ai-transition);
    -webkit-tap-highlight-color: transparent;
}

.ai-chat-session:hover {
    background: var(--ai-card);
}

.ai-chat-session.is-active {
    background: var(--ai-card);
    border-color: var(--ai-border);
    box-shadow: var(--ai-shadow-sm);
    color: var(--ai-text);
    font-weight: 600;
}

.ai-chat-session-icon {
    width: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--ai-green);
    font-size: 13px;
    flex-shrink: 0;
}

.ai-chat-session-icon svg {
    width: 14px;
    height: 14px;
}

.ai-chat-session:hover .ai-chat-session-icon {
    color: var(--ai-green-dark);
}

.ai-chat-session.is-active .ai-chat-session-icon {
    color: var(--ai-green);
}

.ai-chat-session-title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.4;
}

/* Row actions overlay the right edge on hover/active */
.ai-chat-session:hover .ai-chat-session-title,
.ai-chat-session.is-active:hover .ai-chat-session-title {
    padding-right: 56px;
}

.ai-chat-session-export,
.ai-chat-session-delete {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 24px;
    height: 24px;
    border: none;
    border-radius: 7px;
    background: var(--ai-card-alt);
    color: var(--ai-text-muted);
    cursor: pointer;
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    transition: all var(--ai-transition);
    touch-action: manipulation;
}

.ai-chat-session-export {
    right: 36px;
}

.ai-chat-session-delete {
    right: 8px;
}

.ai-chat-session:hover .ai-chat-session-export,
.ai-chat-session:hover .ai-chat-session-delete {
    display: inline-flex;
}

.ai-chat-session-export:hover {
    background: var(--ai-green-soft);
    color: var(--ai-green-dark);
}

.ai-chat-session-delete:hover {
    background: rgba(220, 38, 38, 0.12);
    color: var(--ai-danger);
}

/* Empty + loading states */
.ai-chat-sessions-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    text-align: center;
    color: var(--ai-text-faint);
    font-size: 12px;
    padding: 36px 12px;
}

.ai-chat-sessions-empty i {
    font-size: 22px;
    opacity: 0.7;
}

.ai-chat-sidebar-loading {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 2px;
}

.ai-chat-sidebar-loading-row {
    height: 34px;
    border-radius: 10px;
    background: linear-gradient(90deg, var(--ai-card-alt) 25%, var(--ai-card) 50%, var(--ai-card-alt) 75%);
    background-size: 400px 100%;
    animation: aiShimmer 1.5s infinite;
}

/* ═══════════════════════════════════════════════════════
   MAIN HEADER — identity, status, action buttons
   ═══════════════════════════════════════════════════════ */
.ai-chat-header {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-height: 64px;
    padding: 12px 16px;
    background: var(--ai-surface);
    border-bottom: 1px solid var(--ai-border);
}

.ai-chat-header-left {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

/* Title/status wrapper must be allowed to shrink so long chat
   names ellipsize instead of pushing the header buttons out. */
.ai-chat-header-left > div:last-child {
    min-width: 0;
}

.ai-chat-avatar {
    width: 38px;
    height: 38px;
    border-radius: 12px;
    background: linear-gradient(135deg, var(--ai-green), var(--ai-green-dark));
    box-shadow: 0 3px 10px rgba(129, 181, 4, 0.3);
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    flex-shrink: 0;
}

.ai-chat-avatar img {
    width: 24px;
    height: 24px;
    object-fit: contain;
}

/* Online dot */
.ai-chat-avatar::after {
    content: '';
    position: absolute;
    right: -2px;
    bottom: -2px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--ai-green);
    border: 2px solid var(--ai-surface);
}

.ai-chat-title {
    font-size: 14px;
    font-weight: 700;
    color: var(--ai-text);
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ai-chat-subtitle {
    font-size: 11.5px;
    color: var(--ai-text-muted);
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 1px;
    white-space: nowrap;
}

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

.ai-chat-btn-icon {
    width: 32px;
    height: 32px;
    border: 1px solid var(--ai-border-strong);
    border-radius: 9px;
    background: var(--ai-card);
    color: var(--ai-text-muted);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12.5px;
    transition: all var(--ai-transition);
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

.ai-chat-btn-icon:hover {
    border-color: var(--ai-green);
    color: var(--ai-green-dark);
    background: var(--ai-green-soft);
    transform: translateY(-1px);
}

.ai-chat-btn-icon:active {
    transform: translateY(0);
}

/* Destructive header action hovers red instead of green */
.ai-chat-btn-icon.ai-chat-btn-danger:hover {
    border-color: rgba(220, 38, 38, 0.4);
    color: var(--ai-danger);
    background: rgba(220, 38, 38, 0.07);
}

/* Show-sidebar button (JS toggles inline display) */
.ai-chat-sidebar-show {
    flex-shrink: 0;
}

/* Status dots */
.ai-status-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}

.ai-status-ready {
    background: var(--ai-green);
    box-shadow: 0 0 0 3px var(--ai-green-soft);
}

.ai-status-thinking {
    background: #f59e0b;
    box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.18);
    animation: aiDotPulse 1.2s infinite;
}

/* ═══════════════════════════════════════════════════════
   MESSAGES — timeline layout with avatar rail
   ═══════════════════════════════════════════════════════ */
.ai-chat-messages {
    flex: 1;
    overflow-y: auto;
    /* Wide content must scroll inside its own card (.ai-chat-table-wrap,
       pre) — never the conversation column itself. */
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    padding: 18px 18px 4px;
    background: var(--ai-surface-alt);
}

/* Tighten the gap to the credit banner below */
#aiChatMessages > .ai-chat-msg:last-child {
    margin-bottom: 6px;
}

.ai-chat-messages::-webkit-scrollbar {
    width: 6px;
}

.ai-chat-messages::-webkit-scrollbar-thumb {
    background: var(--ai-border-strong);
    border-radius: 4px;
}

.ai-chat-messages::-webkit-scrollbar-thumb:hover {
    background: var(--ai-text-faint);
}

/* One message row: avatar column + content */
.ai-chat-msg {
    position: relative;
    padding-left: 42px;
    margin-bottom: 18px;
    max-width: 100%;
    animation: aiFadeSlideIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes aiFadeSlideIn {
    from {
        opacity: 0;
        transform: translateY(8px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Vertical timeline rail connecting avatars */
.ai-chat-msg::before {
    content: '';
    position: absolute;
    left: 14px;
    top: 36px;
    bottom: -16px;
    width: 2px;
    border-radius: 1px;
    background: var(--ai-border);
}

#aiChatMessages > .ai-chat-msg:last-child::before {
    display: none;
}

/* Avatars on the rail (white logo glyph → green tile) */
.ai-chat-msg .ai-chat-msg-avatar {
    position: absolute;
    left: 0;
    top: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: linear-gradient(135deg, var(--ai-green), var(--ai-green-dark));
    box-shadow: 0 2px 8px rgba(129, 181, 4, 0.25);
    color: #fff;
    overflow: hidden;
}

.ai-chat-msg .ai-chat-msg-avatar img {
    width: 18px;
    height: 18px;
    object-fit: contain;
}

.ai-chat-msg .ai-chat-msg-avatar svg {
    width: 15px;
    height: 15px;
}

.ai-chat-msg .ai-chat-msg-avatar.ai-chat-msg-avatar-user {
    /* solid — the tiny avatar shouldn't go glassy with the bubble */
    background: linear-gradient(135deg, #045ba0 0%, #023f6e 100%);
    border: none;
    color: #fff;
    font-size: 12px;
}

/* Author + time header */
.ai-chat-msg-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 30px;
    margin-bottom: 4px;
}

.ai-chat-msg-author {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ai-text);
    line-height: 1;
}

.ai-chat-msg-time {
    font-size: 11px;
    color: var(--ai-text-faint);
    line-height: 1;
}

.ai-chat-content {
    min-width: 0;
    max-width: 100%;
}

/* User bubble — same glass treatment as the bot reply, in blue */
.ai-chat-msg-user .ai-chat-bubble {
    display: inline-block;
    background: rgba(4, 91, 160, 0.07);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border: 1px solid rgba(4, 91, 160, 0.14);
    color: var(--ai-text-body);
    border-radius: 4px 16px 16px 16px;
    padding: 10px 16px;
    font-size: 13.5px;
    line-height: 1.6;
    max-width: min(88%, 62ch);
    white-space: pre-wrap;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

/* Assistant reply — soft green glass card; rich blocks
   (tables, code, files) carry their own cards inside it.
   Block (not inline-block): shrink-to-fit sizing would let a wide
   table's intrinsic width grow the bubble past the column. */
.ai-chat-msg-assistant .ai-chat-bubble {
    display: block;
    /* Each bubble hugs its own content; the max-width caps below
       still clamp wide tables so they scroll inside their card. */
    width: -moz-fit-content;
    width: fit-content;
    background: rgba(129, 181, 4, 0.07);
    border: 1px solid rgba(129, 181, 4, 0.13);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border-radius: 4px 16px 16px 16px;
    padding: 11px 16px;
    color: var(--ai-text-body);
    font-size: 13.5px;
    line-height: 1.65;
    word-wrap: break-word;
    overflow-wrap: break-word;
    /* Reading measure cap, never wider than the column itself —
       fit-content's min-content floor would otherwise push a
       no-wrap table past the popup column and clip its columns. */
    max-width: min(70ch, 100%);
}

/* Rich replies — any bubble carrying a card (form, table/report, chart,
   file, error banner) takes the full column width instead of hugging its
   own content, so a Create Task / Create Project form renders at the same
   width as a wide attendance-report table. The max-width caps above (and
   the fullscreen override below) still bound it, so it stays responsive. */
.ai-chat-msg-assistant .ai-chat-bubble:has(.ai-chat-table-wrap, .ai-task-card, .ai-form-card, .ai-chart-card, .ai-file-card, .ai-task-error) {
    width: 100%;
}

/* Footer (copy action, hover-revealed) */
.ai-chat-msg-footer {
    display: flex;
    align-items: center;
    margin-top: 2px;
    min-height: 22px;
}

.ai-chat-msg-actions {
    display: flex;
    gap: 2px;
    opacity: 0;
    transition: opacity var(--ai-transition);
}

.ai-chat-msg-assistant:hover .ai-chat-msg-actions {
    opacity: 1;
}

.ai-chat-action-btn {
    border: none;
    background: none;
    color: var(--ai-text-faint);
    cursor: pointer;
    padding: 4px 8px;
    font-size: 12px;
    border-radius: 7px;
    transition: all var(--ai-transition);
    touch-action: manipulation;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ai-chat-action-btn:hover {
    color: var(--ai-green-dark);
    background: var(--ai-green-soft);
}

.ai-chat-action-btn:active {
    transform: scale(0.92);
}

.ai-action-success {
    color: var(--ai-green) !important;
}

/* Typewriter reveal */
.ai-chat-typewriter {
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 0.4s ease, transform 0.4s ease;
}

.ai-chat-typewriter.ai-chat-typewriter-done {
    opacity: 1;
    transform: translateY(0);
}

/* ─── Streaming ─────────────────────────────────────── */
/* The streamed row is finalized IN PLACE (same element) — this class
   additionally suppresses every animation/transition inside it so the
   final content settles with zero fade, ease, or re-reveal of any part
   of the message. */
.ai-chat-msg.ai-chat-msg-instant,
.ai-chat-msg.ai-chat-msg-instant * {
    animation: none !important;
    transition: none !important;
}

.ai-chat-msg.ai-chat-msg-instant .ai-chat-typewriter {
    opacity: 1;
    transform: none;
}

/* Quiet note shown while an interactive block (deskchart / deskchoices /
   deskdata) is still streaming in — its raw JSON must never be visible. */
.ai-stream-preparing {
    opacity: 0.55;
    font-style: italic;
    font-size: 12px;
    padding: 4px 0;
}

/* ─── Tool Call Chips ───────────────────────────────── */
.ai-chat-tools {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 8px;
}

.ai-chat-tool-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 11px;
    background: var(--ai-green-soft);
    border: 1px solid rgba(129, 181, 4, 0.28);
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 600;
    color: var(--ai-green-dark);
    letter-spacing: 0.2px;
    animation: aiFadeSlideIn 0.3s ease backwards;
    /* animation-delay comes inline from JS */
}

.ai-chat-tool-badge i {
    font-size: 10px;
}

/* ═══════════════════════════════════════════════════════
   WELCOME SCREEN + SUGGESTIONS
   ═══════════════════════════════════════════════════════ */
.ai-chat-welcome {
    max-width: 400px;
    margin: 0 auto;
    padding: 36px 12px 24px;
    text-align: center;
}

.ai-chat-welcome.hidden {
    display: none;
}

.ai-chat-welcome-icon {
    width: 64px;
    height: 64px;
    margin: 0 auto 16px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--ai-green), var(--ai-green-dark));
    box-shadow: 0 10px 28px rgba(129, 181, 4, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
}

.ai-chat-welcome-icon img {
    width: 38px;
    height: 38px;
    object-fit: contain;
}

.ai-chat-welcome-icon i {
    font-size: 26px !important;
    color: #fff !important;
}

@keyframes aiWelcomeFloat {

    0%,
    100% {
        transform: translateY(0);
    }

    50% {
        transform: translateY(-6px);
    }
}

.ai-chat-welcome h4 {
    font-size: 17px;
    font-weight: 700;
    color: var(--ai-text);
    margin: 0 0 6px;
}

.ai-chat-welcome p {
    font-size: 12.5px;
    color: var(--ai-text-muted);
    line-height: 1.6;
    margin: 0 0 20px;
}

.ai-chat-suggestions {
    display: flex;
    flex-direction: column;
    gap: 8px;
    text-align: left;
}

.ai-chat-suggestions button {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 12px;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: 12px;
    font-size: 12.5px;
    font-weight: 500;
    font-family: inherit;
    color: var(--ai-text-body);
    cursor: pointer;
    box-shadow: var(--ai-shadow-sm);
    transition: all var(--ai-transition);
    text-align: left;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

.ai-chat-suggestions button i {
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background: var(--ai-green-soft);
    color: var(--ai-green-dark);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    flex-shrink: 0;
}

.ai-chat-suggestions button:hover {
    border-color: var(--ai-green);
    transform: translateY(-1px);
    box-shadow: var(--ai-shadow-md);
}

.ai-chat-suggestions button:active {
    transform: translateY(0);
}

/* ═══════════════════════════════════════════════════════
   WELCOME / EMPTY-STATE HERO  (redesigned, live panel only)
   Two layouts, chosen by PANEL STATE (not viewport), because the
   docked panel is always narrow while fullscreen is wide:
     • DEFAULT (docked / mobile): mascot stacked ON TOP of a centered
       caption, then a "TRY ASKING" eyebrow over chips stacked one
       per row — all equal width, inner text centred.
     • .ai-chat-fullscreen (≥621px): horizontal hero (mascot left,
       bold caption right) + a bigger 3-over-2 chip pyramid, centred.
   Presentation only — every chip keeps its sendAiQuick() onclick.
   Reuses the --ai-* tokens so light/dark both theme automatically.
   The legacy .ai-chat-welcome-icon / .ai-chat-suggestions rules
   above are left intact on purpose (backward-compatible).
   ═══════════════════════════════════════════════════════ */

/* ── DEFAULT: stacked hero (docked panel + mobile) ── */
.ai-chat-hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    text-align: center;
    margin-top: 26px;                /* bring the mascot + caption a little further down */
    animation: aiFadeSlideIn 0.6s ease backwards;
}

/* Mascot: sits upright with a soft green halo + gentle bob.
   (In fullscreen it leans toward the caption and sways instead.) */
.ai-chat-hero-mascot {
    position: relative;
    width: 116px;
    height: 116px;
    flex-shrink: 0;
    /* The mascot is a cut-out 3D render (no disc behind it), so the shadow
       stack does the grounding the disc used to do: a tight contact shadow
       hugging the silhouette, a mid shadow for form, and a long soft cast
       shadow below. drop-shadow follows the PNG's alpha, so each one traces
       the robot's real outline instead of a box. */
    filter: drop-shadow(0 1px 1px rgba(3, 32, 52, 0.28))
            drop-shadow(0 6px 10px rgba(3, 32, 52, 0.22))
            drop-shadow(0 18px 22px rgba(3, 32, 52, 0.18));
    animation: aiMascotFloat 5.5s ease-in-out infinite;
}

/* Ground shadow: an ellipse on the floor beneath the robot. It is what
   sells "floating object" — as the mascot rises it shrinks and fades, and
   it is timed to the same 5.5s loop so the two read as one motion. */
.ai-chat-hero-mascot::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: -10px;
    width: 62%;
    height: 12px;
    transform: translateX(-50%) scale(1);
    border-radius: 50%;
    background: radial-gradient(ellipse at center,
                rgba(3, 32, 52, 0.34) 0%,
                rgba(3, 32, 52, 0.16) 45%,
                rgba(3, 32, 52, 0) 72%);
    animation: aiMascotGroundShadow 5.5s ease-in-out infinite;
    pointer-events: none;
}

/* DARK theme: a dark shadow on a near-black panel is invisible, so the
   grounding is inverted — a soft OFF-WHITE light pool on the floor plus a
   cool off-white ambient rim on the robot itself. Reads as a lit surface
   under a floating object instead of a shadow nobody can see. */
body.dark-mode .ai-chat-hero-mascot {
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.55))
            drop-shadow(0 10px 18px rgba(0, 0, 0, 0.5))
            drop-shadow(0 0 20px rgba(226, 240, 247, 0.17));
}

body.dark-mode .ai-chat-hero-mascot::after {
    background: radial-gradient(ellipse at center,
                rgba(226, 240, 247, 0.24) 0%,
                rgba(226, 240, 247, 0.11) 45%,
                rgba(226, 240, 247, 0) 72%);
}

@keyframes aiMascotGroundShadow {

    0%,
    100% {
        transform: translateX(-50%) scale(1);
        opacity: 1;
    }

    50% {
        transform: translateX(-50%) scale(0.82);
        opacity: 0.65;
    }
}

.ai-chat-hero-mascot img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* ── Galaxy Particles Background ── */
.ai-chat-welcome {
    position: relative;
}

.ai-chat-particles {
    display: none;
}

.ai-chat-fullscreen .ai-chat-particles {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 0;
}

.ai-chat-hero, .ai-chat-suggest, .ai-chat-welcome-icon, .ai-chat-welcome h4, .ai-chat-welcome p {
    position: relative;
    z-index: 1;
}

.ai-particle {
    position: absolute;
    border-radius: 50%;
    filter: blur(50px);
    opacity: 0.5;
    /* near-linear soft-S easing: velocity stays ~85% of segment speed at
       every keyframe boundary, so segments blend instead of stop-starting */
    animation: aiGalaxyFloat cubic-bezier(0.33, 0.28, 0.67, 0.72) infinite;
}

.ai-p1 {
    width: 250px;
    height: 250px;
    top: 10%;
    left: 20%;
    background: var(--ai-green);
    animation-duration: 14s;
}

.ai-p2 {
    width: 300px;
    height: 300px;
    top: 40%;
    right: 15%;
    left: auto;
    background: var(--ai-green-light);
    animation-duration: 18s;
    animation-delay: -5s;
}

.ai-p3 {
    width: 250px;
    height: 250px;
    bottom: 5%;
    left: 5%;
    top: auto;
    background: var(--ai-green-glow);
    animation-duration: 16s;
    animation-delay: -10s;
}

/* Liquid flow, velocity-smoothed: the blobs travel one continuous curving
   loop (no direction reversals) and the speed comes from keyframe spacing —
   px-per-% ramps ~2.2 → 5 → 10.5 → 5 → 2.3 and again, so the slow→fast→slow
   rhythm builds and releases gradually instead of jumping. Easing lives on
   .ai-particle (soft-S, near-linear); keyframes stay easing-free. */
@keyframes aiGalaxyFloat {
    0% {
        transform: translate(0, 0) scale(1, 1) rotate(0deg);
        border-radius: 50%;
        opacity: 0.35;
    }
    12% {
        transform: translate(22px, -14px) scale(1.03, 0.97) rotate(1deg);
        border-radius: 53% 47% 55% 45% / 47% 53% 47% 53%;
        opacity: 0.38;
    }
    22% {
        transform: translate(66px, -38px) scale(1.1, 0.9) rotate(3deg);
        border-radius: 48% 52% 62% 38% / 52% 46% 58% 46%;
        opacity: 0.46;
    }
    30% {
        transform: translate(140px, -78px) scale(1.22, 0.84) rotate(6deg);
        border-radius: 40% 60% 70% 30% / 55% 40% 60% 45%;
        opacity: 0.58;
    }
    40% {
        transform: translate(183px, -52px) scale(1.08, 0.95) rotate(3deg);
        border-radius: 55% 45% 58% 42% / 48% 56% 44% 54%;
        opacity: 0.48;
    }
    52% {
        transform: translate(192px, -25px) scale(0.98, 1.04) rotate(0deg);
        border-radius: 60% 40% 48% 52% / 46% 60% 40% 54%;
        opacity: 0.4;
    }
    62% {
        transform: translate(162px, 15px) scale(1.08, 0.94) rotate(-3deg);
        border-radius: 44% 56% 52% 48% / 56% 42% 60% 44%;
        opacity: 0.46;
    }
    70% {
        transform: translate(88px, 55px) scale(1.2, 0.86) rotate(-7deg);
        border-radius: 35% 65% 55% 45% / 60% 35% 65% 40%;
        opacity: 0.56;
    }
    80% {
        transform: translate(44px, 32px) scale(1.05, 0.98) rotate(-4deg);
        border-radius: 52% 48% 44% 56% / 46% 52% 48% 54%;
        opacity: 0.44;
    }
    100% {
        transform: translate(0, 0) scale(1, 1) rotate(0deg);
        border-radius: 50%;
        opacity: 0.35;
    }
}

body.dark-mode .ai-particle {
    opacity: 0.2;
    animation-name: aiGalaxyFloatDark;
}

body.dark-mode .ai-p1 {
    background: var(--ai-green);
}

body.dark-mode .ai-p2 {
    background: var(--ai-green-light);
}

body.dark-mode .ai-p3 {
    background: var(--ai-green-glow);
}

/* Same velocity-smoothed liquid loop as aiGalaxyFloat, dimmed for dark mode. */
@keyframes aiGalaxyFloatDark {
    0% {
        transform: translate(0, 0) scale(1, 1) rotate(0deg);
        border-radius: 50%;
        opacity: 0.15;
    }
    12% {
        transform: translate(22px, -14px) scale(1.03, 0.97) rotate(1deg);
        border-radius: 53% 47% 55% 45% / 47% 53% 47% 53%;
        opacity: 0.17;
    }
    22% {
        transform: translate(66px, -38px) scale(1.1, 0.9) rotate(3deg);
        border-radius: 48% 52% 62% 38% / 52% 46% 58% 46%;
        opacity: 0.21;
    }
    30% {
        transform: translate(140px, -78px) scale(1.22, 0.84) rotate(6deg);
        border-radius: 40% 60% 70% 30% / 55% 40% 60% 45%;
        opacity: 0.28;
    }
    40% {
        transform: translate(183px, -52px) scale(1.08, 0.95) rotate(3deg);
        border-radius: 55% 45% 58% 42% / 48% 56% 44% 54%;
        opacity: 0.22;
    }
    52% {
        transform: translate(192px, -25px) scale(0.98, 1.04) rotate(0deg);
        border-radius: 60% 40% 48% 52% / 46% 60% 40% 54%;
        opacity: 0.18;
    }
    62% {
        transform: translate(162px, 15px) scale(1.08, 0.94) rotate(-3deg);
        border-radius: 44% 56% 52% 48% / 56% 42% 60% 44%;
        opacity: 0.21;
    }
    70% {
        transform: translate(88px, 55px) scale(1.2, 0.86) rotate(-7deg);
        border-radius: 35% 65% 55% 45% / 60% 35% 65% 40%;
        opacity: 0.27;
    }
    80% {
        transform: translate(44px, 32px) scale(1.05, 0.98) rotate(-4deg);
        border-radius: 52% 48% 44% 56% / 46% 52% 48% 54%;
        opacity: 0.2;
    }
    100% {
        transform: translate(0, 0) scale(1, 1) rotate(0deg);
        border-radius: 50%;
        opacity: 0.15;
    }
}

body.dark-mode .ai-particle {
    animation-name: aiGalaxyFloatDark;
}

@keyframes aiMascotFloat {

    0%,
    100% {
        transform: translateY(0);
    }

    50% {
        transform: translateY(-5px);
    }
}

@keyframes aiMascotSway {

    0%,
    100% {
        transform: rotate(-8deg) translateY(0);
    }

    50% {
        transform: rotate(-6deg) translateY(-4px);
    }
}

.ai-chat-hero-text {
    text-align: center;
    max-width: 300px;
}

.ai-chat-hero-text h4 {
    font-size: 19px;
    font-weight: 800;
    letter-spacing: -0.3px;
    line-height: 1.22;
    color: var(--ai-text);
    margin: 0 0 6px;
}

.ai-chat-hero-text p {
    font-size: 13px;
    font-weight: 500;
    color: var(--ai-text-body);
    line-height: 1.55;
    margin: 0;
}

.ai-chat-hero-beta {
    position: absolute;
    top: 4px;
    right: 0;
    background: #e8f5c8;
    color: #4d6b00;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.5px;
    line-height: 1;
    padding: 3px 7px;
    border-radius: 10px;
    border: 1px solid #c5e08a;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
    text-transform: uppercase;
    z-index: 5;
}

/* ── Suggestion chips ── */
.ai-chat-suggest {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    margin-top: 26px;
    width: 100%;
}

.ai-chat-suggest-eyebrow {
    font-size: 10px;
    letter-spacing: 2.4px;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--ai-text-faint);
    animation: aiFadeSlideIn 0.5s ease backwards;
    animation-delay: 0.25s;
}

/* DEFAULT: each row is a vertical stack; both rows share one width so
   all five chips line up equal-width and centred, one below another. */
.ai-chat-suggest-row {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    width: 100%;
    max-width: 290px;
}

.ai-chat-suggest-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;         /* centre the inner icon + text */
    gap: 8px;
    width: 100%;
    padding: 10px 14px;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
    font-family: inherit;
    color: var(--ai-text-body);
    cursor: pointer;
    box-shadow: var(--ai-shadow-sm);
    transition: all var(--ai-transition);
    white-space: nowrap;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    animation: aiFadeSlideIn 0.5s ease backwards;
}

.ai-chat-suggest-chip i {
    color: var(--ai-green-dark);
    font-size: 12px;
    flex-shrink: 0;
}

.ai-chat-suggest-chip:hover {
    border-color: var(--ai-green);
    transform: translateY(-1px);
    box-shadow: var(--ai-shadow-md);
}

.ai-chat-suggest-chip:active {
    transform: translateY(0);
}

/* gentle staggered entrance (per-row, robust to sibling order) */
.ai-chat-suggest-row .ai-chat-suggest-chip:nth-child(1) { animation-delay: 0.30s; }
.ai-chat-suggest-row .ai-chat-suggest-chip:nth-child(2) { animation-delay: 0.37s; }
.ai-chat-suggest-row .ai-chat-suggest-chip:nth-child(3) { animation-delay: 0.44s; }

body.dark-mode .ai-chat-suggest-chip i {
    color: rgba(154, 218, 5, 0.85);
}

/* ── FULLSCREEN (≥621px): horizontal hero + bigger 3-over-2 pyramid ──
   Scoped to a real viewport width so that fullscreen on a phone falls
   back to the default stacked layout automatically. The extra
   .ai-chat-messages qualifier keeps the widened container ahead of the
   legacy `.ai-chat-fullscreen .ai-chat-welcome { max-width:640px }`. */
@media (min-width: 621px) {

    .ai-chat-fullscreen .ai-chat-messages .ai-chat-welcome {
        max-width: 800px;            /* wide enough for the 3-chip row to stay on one line */
        transform: translateY(-64px); /* sit above dead-centre, toward the upper-middle */
    }

    /* Vertically centre the empty-state hero in the tall fullscreen area.
       Scoped with :has() to the VISIBLE welcome only — once a chat starts
       the welcome gets .hidden, so an active conversation keeps its normal
       top-aligned, scrollable layout. */
    .ai-chat-fullscreen .ai-chat-messages:has(> #aiChatWelcome:not(.hidden)) {
        display: flex;
        flex-direction: column;
        justify-content: center;
    }

    .ai-chat-fullscreen .ai-chat-hero {
        flex-direction: row;
        gap: 65px;                    /* wider split: mascot sits further left, caption further right */
        text-align: left;
        margin-top: 8px;
    }

    .ai-chat-fullscreen .ai-chat-hero-mascot {
        width: 156px;
        height: 156px;
        transform: rotate(-8deg);
        transform-origin: bottom right;
        animation: aiMascotSway 5.5s ease-in-out infinite;
    }

    .ai-chat-fullscreen .ai-chat-hero-text {
        text-align: left;
        max-width: 360px;
    }

    .ai-chat-fullscreen .ai-chat-hero .ai-chat-hero-text h4 {
        font-size: 27px;
    }

    .ai-chat-fullscreen .ai-chat-hero .ai-chat-hero-text p {
        font-size: 14.5px;
        line-height: 1.5;
    }

    .ai-chat-fullscreen .ai-chat-suggest {
        margin-top: 34px;
    }

    /* pyramid: chips flow horizontally and wrap centred (3 then 2) */
    .ai-chat-fullscreen .ai-chat-suggest-row {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: stretch;
        justify-content: center;
        width: auto;
        max-width: none;
        gap: 12px;
    }

    .ai-chat-fullscreen .ai-chat-suggest-chip {
        width: auto;
        justify-content: flex-start;
        padding: 10px 16px;
        font-size: 13px;
    }

    .ai-chat-fullscreen .ai-chat-suggest-chip i {
        font-size: 13px;
    }
}

/* Respect users who prefer no motion (any static lean stays; the
   float/sway + entrance fades drop) */
@media (prefers-reduced-motion: reduce) {

    .ai-chat-hero,
    .ai-chat-hero-mascot,
    .ai-chat-suggest-eyebrow,
    .ai-chat-suggest-chip {
        animation: none !important;
    }

    .ai-chat-suggest-chip {
        transition: none !important;
    }
}

/* ═══════════════════════════════════════════════════════
   MARKDOWN INSIDE BUBBLES
   ═══════════════════════════════════════════════════════ */
.ai-chat-bubble p {
    margin: 0 0 8px;
}

.ai-chat-bubble p:last-child {
    margin: 0;
}

.ai-chat-bubble strong {
    font-weight: 700;
    color: var(--ai-text);
}

.ai-chat-bubble em {
    font-style: italic;
}

.ai-chat-bubble code {
    background: rgba(4, 91, 160, 0.08);
    color: var(--ai-blue);
    padding: 2px 6px;
    border-radius: 5px;
    font-family: 'Consolas', 'Courier New', monospace;
    font-size: 12px;
    word-break: break-all;
}

.ai-chat-bubble h3 {
    font-size: 15px;
    font-weight: 700;
    margin: 12px 0 6px;
    color: var(--ai-text);
}

.ai-chat-bubble h4 {
    font-size: 13.5px;
    font-weight: 700;
    margin: 10px 0 4px;
    color: var(--ai-text);
}

/* Lists */
.ai-chat-bubble ul,
.ai-chat-bubble ol {
    margin: 8px 0;
    padding-left: 0;
    list-style: none;
}

.ai-chat-bubble ol {
    counter-reset: ai-list;
}

.ai-chat-bubble li {
    margin-bottom: 5px;
    font-size: 13.5px;
    line-height: 1.55;
    position: relative;
}

.ai-chat-bubble ul>li {
    padding-left: 18px;
}

.ai-chat-bubble ul>li::before {
    content: "";
    position: absolute;
    left: 5px;
    top: 0.62em;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--ai-green);
}

.ai-chat-bubble ol>li {
    counter-increment: ai-list;
    padding-left: 28px;
    min-height: 20px;
}

.ai-chat-bubble ol>li::before {
    content: counter(ai-list);
    position: absolute;
    left: 0;
    top: 1px;
    width: 19px;
    height: 19px;
    background: linear-gradient(135deg, var(--ai-green), var(--ai-green-dark));
    color: #fff;
    border-radius: 6px;
    font-size: 10px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.ai-chat-bubble a {
    color: var(--ai-blue);
    text-decoration: none;
    font-weight: 500;
    border-bottom: 1px dashed rgba(4, 91, 160, 0.3);
    transition: all var(--ai-transition);
}

.ai-chat-bubble a:hover {
    color: var(--ai-green-dark);
    border-bottom-color: var(--ai-green);
}

/* ─── Code Blocks ───────────────────────────────────── */
.ai-code-block {
    margin: 10px 0;
    border-radius: var(--ai-radius-sm);
    overflow: hidden;
    border: 1px solid #1e293b;
    box-shadow: var(--ai-shadow-sm);
}

.ai-code-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 12px;
    background: #1e293b;
    border-bottom: 1px solid #334155;
    min-height: 32px;
}

.ai-code-lang {
    font-size: 10px;
    font-weight: 600;
    color: #94a3b8;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.ai-code-copy {
    border: none;
    background: rgba(255, 255, 255, 0.06);
    color: #94a3b8;
    cursor: pointer;
    padding: 3px 8px;
    font-size: 11px;
    border-radius: 6px;
    transition: all var(--ai-transition);
    display: flex;
    align-items: center;
    gap: 4px;
}

.ai-code-copy:hover {
    background: rgba(255, 255, 255, 0.12);
    color: #e2e8f0;
}

.ai-code-copy.ai-action-success {
    color: var(--ai-green-light) !important;
}

.ai-code-block pre {
    margin: 0;
    border: none;
    border-radius: 0;
}

.ai-chat-bubble pre {
    background: #0f172a;
    color: #e2e8f0;
    padding: 12px 14px;
    border-radius: var(--ai-radius-sm);
    overflow-x: auto;
    margin: 10px 0;
    font-size: 12px;
    line-height: 1.55;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
    border: 1px solid #1e293b;
}

.ai-chat-bubble pre code {
    background: none;
    color: inherit;
    padding: 0;
    font-size: inherit;
}

/* ─── CSV / Excel download chips ────────────────────── */
.ai-dl-actions {
    display: flex;
    justify-content: flex-end;
    gap: 6px;
    margin: 0 0 6px;
}

.ai-csv-dl {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
    border: 1px solid var(--ai-border-strong);
    background: var(--ai-card);
    color: var(--ai-text-body);
    font-size: 11px;
    font-weight: 600;
    font-family: inherit;
    padding: 4px 10px;
    border-radius: 7px;
    transition: all var(--ai-transition);
    white-space: nowrap;
    touch-action: manipulation;
}

.ai-csv-dl:hover {
    border-color: var(--ai-blue);
    color: var(--ai-blue);
    background: rgba(4, 91, 160, 0.06);
}

.ai-csv-dl.ai-xls-dl:hover {
    border-color: var(--ai-green);
    color: var(--ai-green-dark);
    background: var(--ai-green-soft);
}

.ai-csv-dl.ai-action-success {
    background: var(--ai-green);
    border-color: var(--ai-green);
    color: #fff !important;
}

/* ─── File data card ────────────────────────────────── */
.ai-file-card {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 10px 0;
    padding: 12px 14px;
    border: 1px solid var(--ai-border);
    border-radius: 12px;
    background: var(--ai-card);
    box-shadow: var(--ai-shadow-sm);
    flex-wrap: wrap;
}

.ai-file-icon {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--ai-green), var(--ai-green-dark));
    color: #fff;
    font-size: 16px;
    flex-shrink: 0;
}

.ai-file-meta {
    flex: 1;
    min-width: 0;
}

.ai-file-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--ai-text);
}

.ai-file-sub {
    font-size: 11px;
    color: var(--ai-text-muted);
    margin-top: 2px;
}

.ai-file-card .ai-dl-actions {
    margin: 0;
}

/* ─── Tables — card with horizontal scroll ──────────── */
.ai-chat-table-wrap {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    margin: 12px 0;
    padding: 10px 12px 6px;
    max-width: 100%;
    background: var(--ai-card);
    border: 1px solid var(--ai-border);
    border-radius: 14px;
    box-shadow: var(--ai-shadow-sm);
}

/* Keep the export buttons pinned while the table scrolls sideways */
.ai-chat-table-wrap .ai-dl-actions {
    position: sticky;
    left: 0;
    margin: 0 0 8px;
}

.ai-chat-bubble table {
    border-collapse: separate;
    border-spacing: 0;
    margin: 0;
    font-size: 12.5px;
    min-width: 100%;
    width: max-content;
    max-width: none;
}

.ai-chat-bubble th {
    background: transparent;
    color: var(--ai-text-muted);
    padding: 8px 12px;
    text-align: left;
    font-weight: 700;
    font-size: 10.5px;
    white-space: nowrap;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    border-bottom: 1px solid var(--ai-border-strong);
}

.ai-chat-bubble td {
    padding: 9px 12px;
    border-bottom: 1px solid var(--ai-border);
    font-size: 12.5px;
    white-space: nowrap;
    color: var(--ai-text-body);
}

/* Reference-style emphasis: names (first column) read dark and
   medium, the trailing metric column reads bold green. */
.ai-chat-bubble td:first-child {
    font-weight: 600;
    color: var(--ai-text);
}

.ai-chat-bubble td:last-child {
    font-weight: 700;
    color: var(--ai-green-dark);
}

.ai-chat-bubble tbody tr:last-child td,
.ai-chat-bubble tr:last-child td {
    border-bottom: none;
}

.ai-chat-bubble tr:nth-child(even) td {
    background: rgba(129, 181, 4, 0.045);
}

.ai-chat-bubble tr:hover td {
    background: var(--ai-green-soft);
}

/* Profit / loss coloring */
.ai-pl-loss {
    color: #e05252;
    font-weight: 600;
}

.ai-pl-profit {
    color: var(--ai-green-dark);
    font-weight: 600;
}

/* Check-in / activity status coloring */
.ai-st-working {
    color: #6b9a03;
    font-weight: 600;
}

.ai-st-idle {
    color: #d9a80c;
    font-weight: 600;
}

.ai-st-offline {
    color: #e0455c;
    font-weight: 600;
}

/* Time-request "Other Time" from-status — neutral grey. (Private reuses .ai-st-offline red,
   Focus reuses .ai-st-working green, Idle reuses .ai-st-idle yellow — see aiColorSignedPct.) */
.ai-st-other {
    color: #8990aa;
    font-weight: 600;
}

/* ─── Chart & choice-chip brand overrides ───────────── */
/* These elements carry inline light-theme styles from JS;
   brand-align them here (hence the !important). */
.ai-chart-card {
    border-color: var(--ai-border) !important;
    border-radius: 14px !important;
    padding: 14px 16px 12px !important;
    box-shadow: var(--ai-shadow-sm);
}

.ai-choice-chip {
    border-color: rgba(4, 91, 160, 0.35) !important;
    background: rgba(4, 91, 160, 0.06) !important;
    color: var(--ai-blue-dark) !important;
    font-family: inherit !important;
    transition: all var(--ai-transition);
}

.ai-choice-chip:hover {
    background: rgba(4, 91, 160, 0.12) !important;
    transform: translateY(-1px);
}

/* ═══════════════════════════════════════════════════════
   MULTI-PICK TOGGLES (the seven weekday chips)

   These share .ai-choice-chip, whose background, border and colour are all
   !important — so an inline style on the selected chip did nothing and every
   day looked identical whether or not it was picked. The selected state
   therefore lives HERE, at the same weight.

   It is deliberately NOT signalled by colour alone: a tick is added, the
   border thickens and the weight lifts, so the difference survives a
   colour-blind reader, a dim screen and either theme.
   ═══════════════════════════════════════════════════════ */

.ai-sp-toggle {
    position: relative;
    padding-left: 30px !important;   /* room for the tick, reserved in BOTH states
                                        so selecting one never reflows the row */
}

.ai-sp-toggle::before {
    content: '';
    position: absolute;
    left: 11px;
    top: 50%;
    width: 12px;
    height: 12px;
    margin-top: -6px;
    border: 1.5px solid currentColor;
    border-radius: 3px;
    opacity: 0.45;
    box-sizing: border-box;
}

.ai-sp-toggle[aria-pressed="true"] {
    background: var(--ai-green) !important;
    border-color: var(--ai-green-dark) !important;
    color: #ffffff !important;
    font-weight: 700 !important;
    box-shadow: 0 0 0 1px var(--ai-green-dark) inset;
}

/* The empty box becomes a tick. Drawn rather than typed so it cannot land as a
   missing-glyph box on a machine without the emoji font. */
.ai-sp-toggle[aria-pressed="true"]::before {
    border-width: 0 2px 2px 0;
    border-radius: 0;
    width: 6px;
    height: 11px;
    margin-top: -7px;
    left: 13px;
    opacity: 1;
    transform: rotate(45deg);
}

.ai-sp-toggle[aria-pressed="true"]:hover {
    background: var(--ai-green-dark) !important;
}

/* Dark mode keeps the same green fill — it reads on both grounds — and only the
   UNSELECTED chip needs restating, because the dark .ai-choice-chip rule above
   would otherwise win on specificity order. */
body.dark-mode .ai-sp-toggle[aria-pressed="true"] {
    background: var(--ai-green) !important;
    border-color: var(--ai-green-light) !important;
    color: #10240a !important;
}

body.dark-mode .ai-sp-toggle[aria-pressed="true"]:hover {
    background: var(--ai-green-light) !important;
}

/* Done stays out of the way until it can do something. */
.ai-sp-done[disabled] {
    cursor: not-allowed;
}

/* ── A chip that OPENS a setting's list, rather than sending a sentence ──────
   Same selected treatment as the multi-select toggles above, and for the same
   reason: without it there is nothing on screen tying the open dropdown to the
   setting it belongs to. `!important` matches the weight .ai-choice-chip already
   carries — an equal-weight rule later in the file, never an inline style, which
   is what silently lost this fight the first time. */
.ai-choice-picker-chip[aria-pressed="true"] {
    background: var(--ai-green) !important;
    border-color: var(--ai-green-dark) !important;
    color: #ffffff !important;
    font-weight: 700 !important;
    box-shadow: 0 0 0 1px var(--ai-green-dark) inset;
}

.ai-choice-picker-chip[aria-pressed="true"]:hover {
    background: var(--ai-green-dark) !important;
}

body.dark-mode .ai-choice-picker-chip[aria-pressed="true"] {
    background: var(--ai-green) !important;
    border-color: var(--ai-green-light) !important;
    color: #10240a !important;
}

body.dark-mode .ai-choice-picker-chip[aria-pressed="true"]:hover {
    background: var(--ai-green-light) !important;
}

/* The list opens under the chips, behind a rule.
   Without the rule the two rows of chips run together and the options read as a
   SECOND question rather than as the answer to the one above — which is exactly
   how it was reported. The line is the same divider weight the rest of the chat
   uses, and it appears only once something has actually opened. */
.ai-choices-picker:not(:empty) {
    margin-top: 10px;
    padding-top: 10px;
    padding-left: 2px;
    border-top: 1px solid var(--ai-border-strong);
}

/* ═══════════════════════════════════════════════════════
   LOADING SKELETON
   ═══════════════════════════════════════════════════════ */
.ai-chat-loading {
    position: relative;
    padding-left: 42px;
    margin-bottom: 18px;
    animation: aiFadeSlideIn 0.3s ease;
}

.ai-chat-loading-avatar {
    position: absolute;
    left: 0;
    top: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--ai-green), var(--ai-green-dark));
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    animation: aiAvatarPulse 2s infinite;
}

.ai-chat-loading-avatar svg {
    width: 15px;
    height: 15px;
}

.ai-chat-loading-avatar img {
    width: 18px;
    height: 18px;
    object-fit: contain;
}

@keyframes aiAvatarPulse {

    0%,
    100% {
        box-shadow: 0 0 0 0 rgba(129, 181, 4, 0.35);
    }

    50% {
        box-shadow: 0 0 0 7px rgba(129, 181, 4, 0);
    }
}

/* Skeleton bubble wears the same green glass as the bot reply */
.ai-chat-loading-bubble {
    background: rgba(129, 181, 4, 0.07);
    border: 1px solid rgba(129, 181, 4, 0.14);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border-radius: 4px 16px 16px 16px;
    padding: 14px 16px;
    max-width: 320px;
}

.ai-chat-loading-content {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ai-chat-shimmer-line {
    height: 9px;
    border-radius: 5px;
    background: linear-gradient(90deg, rgba(9, 52, 77, 0.08) 25%, rgba(9, 52, 77, 0.16) 50%, rgba(9, 52, 77, 0.08) 75%);
    background-size: 400px 100%;
    animation: aiShimmer 1.4s infinite;
}

@keyframes aiShimmer {
    from {
        background-position: -200px 0;
    }

    to {
        background-position: 200px 0;
    }
}

.ai-chat-loading-indicator {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: 10px;
}

.ai-chat-loading-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--ai-green);
    animation: aiDotPulse 1s infinite;
}

@keyframes aiDotPulse {

    0%,
    100% {
        opacity: 1;
        transform: scale(1);
    }

    50% {
        opacity: 0.4;
        transform: scale(0.75);
    }
}

.ai-chat-loading-label {
    font-size: 11.5px;
    color: var(--ai-text-muted);
}

/* ═══════════════════════════════════════════════════════
   ERROR CARDS
   ═══════════════════════════════════════════════════════ */
.ai-chat-error {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    background: var(--ai-card);
    border: 1px solid var(--ai-border);
    border-left: 3px solid var(--ai-danger);
    border-radius: 12px;
    padding: 13px 15px;
    margin-bottom: 14px;
    animation: aiFadeSlideIn 0.3s ease;
    box-shadow: var(--ai-shadow-sm);
}

.ai-chat-error-icon {
    width: 32px;
    height: 32px;
    border-radius: 9px;
    background: rgba(220, 38, 38, 0.1);
    color: var(--ai-danger);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    flex-shrink: 0;
}

.ai-chat-error-body {
    flex: 1;
    min-width: 0;
}

.ai-chat-error-text {
    color: var(--ai-text-body);
    font-size: 12.5px;
    line-height: 1.55;
    word-wrap: break-word;
    margin-bottom: 8px;
}

.ai-chat-error-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.ai-chat-error-retry {
    border: 1px solid rgba(220, 38, 38, 0.35);
    background: var(--ai-card);
    color: var(--ai-danger);
    cursor: pointer;
    padding: 5px 14px;
    font-size: 12px;
    font-weight: 600;
    font-family: inherit;
    border-radius: 8px;
    transition: all var(--ai-transition);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    touch-action: manipulation;
}

.ai-chat-error-retry:hover {
    background: rgba(220, 38, 38, 0.08);
    border-color: var(--ai-danger);
    transform: translateY(-1px);
}

.ai-chat-error-retry:active {
    transform: translateY(0);
}

.ai-chat-error-retry.ai-chat-error-secondary {
    border-color: var(--ai-border-strong);
    color: var(--ai-text-muted);
}

.ai-chat-error-retry.ai-chat-error-secondary:hover {
    background: var(--ai-card-alt);
    border-color: var(--ai-text-faint);
}

.ai-chat-error-retry:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

/* ═══════════════════════════════════════════════════════
   CREDIT BANNER — subtle link to the usage modal
   No token counts — all usage details are in the modal.
   ═══════════════════════════════════════════════════════ */
#aiChatCreditBanner {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 4px 16px 0;
    padding: 8px 14px;
    background: var(--ai-green-soft);
    border: 1px solid var(--ai-border);
    border-radius: 12px;
    font-size: 12.5px;
    color: var(--ai-text-body);
    cursor: default;
    transition: border-color 0.2s ease, background 0.2s ease;
}

#aiChatCreditBanner .ai-chat-credit-banner-label {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    font-weight: 500;
    color: var(--ai-text-muted);
    white-space: nowrap;
}

#aiChatCreditBanner .ai-chat-credit-banner-label::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--ai-green);
    box-shadow: 0 0 0 3px var(--ai-green-soft);
    flex-shrink: 0;
}

#aiChatCreditBanner .ai-chat-credit-banner-btn {
    border: none;
    background: transparent;
    color: var(--ai-blue);
    padding: 5px 10px;
    border-radius: 8px;
    font-size: 12px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex-shrink: 0;
    transition: background 0.15s ease, color 0.15s ease;
    touch-action: manipulation;
}

#aiChatCreditBanner .ai-chat-credit-banner-btn:hover {
    background: rgba(4, 91, 160, 0.08);
    color: var(--ai-blue-dark);
}

#aiChatCreditBanner .ai-chat-credit-banner-btn:active {
    transform: scale(0.97);
}

/* ═══════════════════════════════════════════════════════
   COMPOSER — input pill + send button
   ═══════════════════════════════════════════════════════ */
/* Composer floats on the chat backdrop — no white band behind it */
.ai-chat-input-area {
    flex-shrink: 0;
    padding: 12px 16px 8px;
    background: transparent;
    position: relative;
    z-index: 2;
}

.ai-chat-input-wrap {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    background: var(--ai-card);
    border: 1.5px solid var(--ai-border-strong);
    border-radius: 16px;
    padding: 8px 6px 8px 16px;
    transition: border-color var(--ai-transition), box-shadow var(--ai-transition);
}

.ai-chat-input-wrap:focus-within {
    border-color: var(--ai-green);
    box-shadow: 0 0 0 3px var(--ai-green-soft);
}

#aiChatInput {
    flex: 1;
    border: none;
    outline: none;
    background: transparent;
    resize: none;
    font-size: 13.5px;
    font-family: inherit;
    line-height: 1.5;
    color: var(--ai-text-body);
    max-height: 120px;
    padding: 6px 0;
    min-width: 0;
}

#aiChatInput::placeholder {
    color: var(--ai-text-faint);
}

#aiChatInput:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

#aiChatSend {
    width: 29px;
    height: 29px;
    border-radius: 50%;
    border: none;
    background: var(--ai-green);
    color: #fff;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    flex-shrink: 0;
    box-shadow: 0 3px 10px rgba(129, 181, 4, 0.35);
    transition: background var(--ai-transition), transform var(--ai-transition), box-shadow var(--ai-transition);
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

/* Icons scale with the smaller button (JS emits fixed svg sizes) */
#aiChatSend svg {
    width: 13px;
    height: 13px;
}

#aiChatSend:hover:not(:disabled) {
    background: var(--ai-green-dark);
    transform: scale(1.06);
}

#aiChatSend:active:not(:disabled) {
    transform: scale(0.96);
}

#aiChatSend:disabled {
    background: var(--ai-border-strong);
    box-shadow: none;
    cursor: not-allowed;
}

/* Stop state while generating (JS also sets inline colors) */
#aiChatSend.ai-chat-stop {
    background: var(--ai-blue);
    box-shadow: 0 3px 10px rgba(4, 91, 160, 0.35);
}

.ai-chat-input-hint {
    text-align: center;
    font-size: 10.5px;
    color: var(--ai-text-faint);
    padding: 6px 4px 0;
}

.ai-chat-input-hint kbd {
    background: var(--ai-card-alt);
    border: 1px solid var(--ai-border-strong);
    border-radius: 4px;
    padding: 1px 5px;
    font-size: 10px;
    font-family: inherit;
    color: var(--ai-text-muted);
    box-shadow: none;
}

.ai-chat-disclaimer {
    text-align: center;
    font-size: 10px;
    color: var(--ai-text-faint);
    opacity: 0.85;
    padding: 3px 4px 0;
}

/* ═══════════════════════════════════════════════════════
   FULLSCREEN MODE — same language, centered column
   ═══════════════════════════════════════════════════════ */
.ai-chat-panel.ai-chat-fullscreen {
    max-width: 100vw !important;
    width: 100vw !important;
    border-left: none;
    animation: aiExpandFull 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes aiExpandFull {
    from {
        max-width: 760px;
    }

    to {
        max-width: 100vw;
    }
}

.ai-chat-fullscreen .ai-chat-sidebar {
    width: 280px;
    flex: 0 0 280px;
}

.ai-chat-fullscreen.ai-chat-sidebar-collapsed .ai-chat-sidebar {
    flex-basis: 0;
    width: 0;
}

/* Center the conversation on a wide column — fullscreen has the
   room, so replies (and their tables) get to use it. */
.ai-chat-fullscreen .ai-chat-messages {
    padding: 28px 28px 12px;
    padding-left: max(28px, calc((100% - 840px) / 2));
    padding-right: max(28px, calc((100% - 840px) / 2));
}

.ai-chat-fullscreen .ai-chat-input-area {
    padding: 14px 24px 10px;
    padding-left: max(24px, calc((100% - 840px) / 2));
    padding-right: max(24px, calc((100% - 840px) / 2));
}

.ai-chat-fullscreen #aiChatCreditBanner {
    margin-left: 24px;
    margin-right: 24px;
    margin-left: max(24px, calc((100% - 840px) / 2));
    margin-right: max(24px, calc((100% - 840px) / 2));
}

/* Replies drop the 70ch reading cap in fullscreen — wide tables
   spread into the free space instead of scrolling (scroll still
   kicks in only when a table outgrows even the full column). */
.ai-chat-fullscreen .ai-chat-msg-assistant .ai-chat-bubble {
    max-width: 100%;
}

.ai-chat-fullscreen .ai-chat-msg-user .ai-chat-bubble {
    max-width: 70ch;
}

.ai-chat-fullscreen .ai-chat-welcome {
    max-width: 640px;
    padding: 56px 20px 40px;
}

.ai-chat-fullscreen .ai-chat-welcome h4 {
    font-size: 20px;
}

.ai-chat-fullscreen .ai-chat-welcome p {
    font-size: 13.5px;
}

.ai-chat-fullscreen .ai-chat-suggestions {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    max-width: 640px;
    margin: 0 auto;
}

.ai-chat-fullscreen .ai-chat-suggestions button {
    width: auto;
}

@media (max-width: 768px) {
    .ai-chat-fullscreen .ai-chat-messages {
        padding: 18px 16px 10px;
    }

    .ai-chat-fullscreen .ai-chat-input-area {
        padding: 12px 16px 8px;
    }

    .ai-chat-fullscreen #aiChatCreditBanner {
        padding-left: 16px;
        padding-right: 16px;
    }

    .ai-chat-fullscreen .ai-chat-suggestions {
        flex-direction: column;
    }

    .ai-chat-fullscreen .ai-chat-suggestions button {
        width: 100%;
    }
}

/* ═══════════════════════════════════════════════════════
   DELETE CONFIRM MODAL (absolute inside panel)
   ═══════════════════════════════════════════════════════ */
.ai-chat-confirm {
    position: absolute;
    inset: 0;
    z-index: 30;
    background: rgba(2, 32, 54, 0.45);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    animation: aiOverlayIn 0.2s ease-out;
}

.ai-chat-confirm-box {
    width: min(340px, 100%);
    background: var(--ai-surface);
    border: 1px solid var(--ai-border);
    border-radius: 16px;
    padding: 20px;
    box-shadow: var(--ai-shadow-lg);
    animation: aiFadeSlideIn 0.25s ease-out;
}

.ai-chat-confirm-title {
    font-size: 14.5px;
    font-weight: 700;
    color: var(--ai-text);
    display: flex;
    align-items: center;
    gap: 8px;
}

.ai-chat-confirm-title i {
    color: var(--ai-danger);
}

.ai-chat-confirm-text {
    font-size: 12.5px;
    color: var(--ai-text-muted);
    line-height: 1.55;
    margin: 8px 0 16px;
    word-wrap: break-word;
}

.ai-chat-confirm-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.ai-chat-confirm-cancel,
.ai-chat-confirm-delete {
    border: none;
    padding: 7px 16px;
    border-radius: 9px;
    font-size: 12.5px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: all var(--ai-transition);
    touch-action: manipulation;
}

.ai-chat-confirm-cancel {
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    color: var(--ai-text-body);
}

.ai-chat-confirm-cancel:hover {
    background: var(--ai-card-alt);
}

.ai-chat-confirm-delete {
    background: var(--ai-danger);
    color: #fff;
}

.ai-chat-confirm-delete:hover {
    background: #b91c1c;
}

.ai-chat-confirm-delete:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ═══════════════════════════════════════════════════════
   TOKEN USAGE MODAL (absolute inside panel, z-index 40)
   ═══════════════════════════════════════════════════════ */
#aiChatUsagePopover {
    position: absolute;
    inset: 0;
    background: rgba(2, 32, 54, 0.38);
    -webkit-backdrop-filter: blur(1.5px);
    backdrop-filter: blur(1.5px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 40;
    padding: 24px;
    animation: aiOverlayIn 0.2s ease-out;
}

#aiChatUsagePopover .ai-chat-usage-card {
    width: min(420px, 100%);
    max-height: calc(100% - 32px);
    background: var(--ai-surface);
    border: 1px solid var(--ai-border);
    border-radius: 20px;
    box-shadow: var(--ai-shadow-lg);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    animation: aiFadeSlideIn 0.25s ease-out;
}

#aiChatUsagePopover .ai-chat-usage-header {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px 12px;
    background: var(--ai-surface);
}

#aiChatUsagePopover .ai-chat-usage-title-wrap {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

#aiChatUsagePopover .ai-chat-usage-icon {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--ai-green) 0%, var(--ai-green-dark) 100%);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 12px rgba(129, 181, 4, 0.3);
}

#aiChatUsagePopover .ai-chat-usage-title {
    font-weight: 700;
    font-size: 15px;
    color: var(--ai-text);
    letter-spacing: 0.2px;
}

#aiChatUsagePopover .ai-chat-usage-close {
    background: var(--ai-card-alt);
    border: 1px solid var(--ai-border);
    color: var(--ai-text-muted);
    width: 30px;
    height: 30px;
    border-radius: 9px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all 0.15s ease;
    touch-action: manipulation;
}

#aiChatUsagePopover .ai-chat-usage-close:hover {
    color: var(--ai-danger);
    border-color: rgba(220, 38, 38, 0.35);
    background: rgba(220, 38, 38, 0.06);
}

#aiChatUsagePopover .ai-chat-usage-body {
    padding: 0 20px 20px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

#aiChatUsagePopover .ai-chat-usage-body::-webkit-scrollbar {
    width: 5px;
}

#aiChatUsagePopover .ai-chat-usage-body::-webkit-scrollbar-thumb {
    background: var(--ai-border-strong);
    border-radius: 4px;
}

#aiChatUsagePopover .ai-chat-usage-loading,
#aiChatUsagePopover .ai-chat-usage-error {
    text-align: center;
    color: var(--ai-text-muted);
    font-size: 13px;
    padding: 24px 0;
}

#aiChatUsagePopover .ai-chat-usage-error {
    color: #dc2626;
}

/* Flat sections separated by hairlines — the tinted credit
   panel below is the only "card" inside the modal. */
#aiChatUsagePopover .ai-chat-usage-section {
    margin: 0;
    padding: 16px 2px;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    border-bottom: 1px solid var(--ai-border);
}

#aiChatUsagePopover .ai-chat-usage-section:last-child {
    border-bottom: none;
    padding-bottom: 4px;
}

#aiChatUsagePopover .ai-chat-usage-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 12px;
    gap: 10px;
}

#aiChatUsagePopover .ai-chat-usage-label {
    font-size: 10px;
    font-weight: 700;
    color: var(--ai-text-faint);
    text-transform: uppercase;
    letter-spacing: 1.1px;
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

#aiChatUsagePopover .ai-chat-usage-label::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ai-green);
    flex-shrink: 0;
}

#aiChatUsagePopover .ai-chat-usage-numbers {
    font-size: 13px;
    color: var(--ai-text-muted);
    font-variant-numeric: tabular-nums;
}

#aiChatUsagePopover .ai-chat-usage-numbers strong {
    color: var(--ai-text);
    font-weight: 700;
    font-size: 15px;
}

#aiChatUsagePopover .ai-chat-usage-bar {
    height: 10px;
    border-radius: 999px;
    background: rgba(9, 52, 77, 0.08);
    border: none;
    overflow: hidden;
    position: relative;
}

#aiChatUsagePopover .ai-chat-usage-bar-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--ai-green-dark) 0%, var(--ai-green) 100%);
    border-radius: 999px;
    transition: width 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
    width: 0%;
}

#aiChatUsagePopover .ai-chat-usage-bar-fill.is-warn {
    background: linear-gradient(90deg, #f59e0b 0%, #ef4444 100%);
}

#aiChatUsagePopover .ai-chat-usage-bar-fill.is-over {
    background: linear-gradient(90deg, #dc2626 0%, #991b1b 100%);
}

#aiChatUsagePopover .ai-chat-usage-meta {
    margin-top: 8px;
    font-size: 11px;
    color: var(--ai-text-muted);
    display: flex;
    justify-content: space-between;
    gap: 10px;
}

#aiChatUsagePopover .ai-chat-usage-meta span:last-child {
    color: var(--ai-text-body);
    font-weight: 600;
}

#aiChatUsagePopover .ai-chat-usage-unlimited {
    font-size: 13px;
    color: var(--ai-green-dark);
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

#aiChatUsagePopover .ai-chat-usage-unlimited::before {
    content: '';
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ai-green);
    box-shadow: 0 0 0 4px var(--ai-green-soft);
}

/* Credit section — the one tinted panel inside the modal */
#aiChatUsagePopover .ai-chat-usage-section-credit {
    background: var(--ai-green-soft);
    border: none;
    border-radius: 14px;
    padding: 14px 16px 18px;
    margin: 14px 0 6px;
}

#aiChatUsagePopover .ai-chat-credit-balance {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 4px;
}

#aiChatUsagePopover .ai-chat-credit-balance-label {
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--ai-text-muted);
}

#aiChatUsagePopover .ai-chat-credit-balance-value {
    font-size: 24px;
    font-weight: 700;
    color: var(--ai-text);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

#aiChatUsagePopover .ai-chat-credit-balance-unit {
    font-size: 12px;
    color: var(--ai-text-muted);
}

#aiChatUsagePopover .ai-chat-credit-balance.is-debt .ai-chat-credit-balance-label,
#aiChatUsagePopover .ai-chat-credit-balance.is-debt .ai-chat-credit-balance-value {
    color: #dc2626;
}

#aiChatUsagePopover .ai-chat-credit-balance.is-debt .ai-chat-credit-balance-value::before {
    content: '−';
    margin-right: 2px;
}

#aiChatUsagePopover .ai-chat-credit-balance.is-debt .ai-chat-credit-balance-unit {
    color: #ef4444;
}

#aiChatUsagePopover .ai-chat-credit-help {
    margin: 0 0 12px 0;
    font-size: 12px;
    color: var(--ai-text-muted);
    line-height: 1.45;
}

#aiChatUsagePopover .ai-chat-credit-packs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}

#aiChatUsagePopover .ai-chat-credit-pack {
    appearance: none;
    border: 1px solid var(--ai-border-strong);
    background: var(--ai-card);
    border-radius: 12px;
    padding: 12px 10px 10px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease, background 0.15s ease;
    box-shadow: var(--ai-shadow-sm);
    touch-action: manipulation;
}

#aiChatUsagePopover .ai-chat-credit-pack:hover:not(:disabled) {
    transform: translateY(-2px);
    border-color: var(--ai-green);
    box-shadow: var(--ai-shadow-md);
}

#aiChatUsagePopover .ai-chat-credit-pack:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

#aiChatUsagePopover .ai-chat-credit-pack-tokens {
    font-size: 18px;
    font-weight: 800;
    color: var(--ai-text);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

#aiChatUsagePopover .ai-chat-credit-pack-tokens-label {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--ai-text-muted);
    margin-bottom: 6px;
}

#aiChatUsagePopover .ai-chat-credit-pack-price {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--ai-green-dark);
    background: var(--ai-green-soft);
    padding: 4px 10px;
    border-radius: 999px;
}

#aiChatUsagePopover .ai-chat-credit-empty {
    text-align: center;
    color: var(--ai-text-muted);
    font-size: 12px;
    padding: 12px;
    border: 1px dashed var(--ai-border-strong);
    border-radius: 12px;
}

#aiChatUsagePopover .ai-chat-credit-buy-error {
    margin-bottom: 10px;
    padding: 8px 12px;
    background: rgba(220, 38, 38, 0.08);
    color: #dc2626;
    font-size: 12px;
    border-radius: 8px;
    border: 1px solid rgba(220, 38, 38, 0.18);
}

#aiChatUsagePopover.is-buying .ai-chat-credit-pack,
#aiChatUsagePopover.is-buying .ai-chat-credit-method {
    pointer-events: none;
}

/* Payment-method chooser */
#aiChatUsagePopover .ai-chat-credit-back {
    background: none;
    border: none;
    color: var(--ai-text-body);
    font-size: 12px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 0.15s ease;
    touch-action: manipulation;
}

#aiChatUsagePopover .ai-chat-credit-back:hover {
    background: var(--ai-card-alt);
}

#aiChatUsagePopover .ai-chat-credit-selected-pack {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 10px 14px;
    margin: 4px 0 14px;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: 12px;
}

#aiChatUsagePopover .ai-chat-credit-selected-tokens {
    font-size: 14px;
    font-weight: 700;
    color: var(--ai-green-dark);
    font-variant-numeric: tabular-nums;
}

#aiChatUsagePopover .ai-chat-credit-selected-price {
    font-size: 15px;
    font-weight: 700;
    color: var(--ai-text);
    font-variant-numeric: tabular-nums;
}

#aiChatUsagePopover .ai-chat-credit-price-breakdown {
    margin: 4px 0 14px;
    padding: 10px 14px;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

#aiChatUsagePopover .ai-chat-credit-price-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 13px;
    color: var(--ai-text-body);
    font-variant-numeric: tabular-nums;
}

#aiChatUsagePopover .ai-chat-credit-price-row.is-total {
    border-top: 1px solid var(--ai-border);
    padding-top: 6px;
    margin-top: 2px;
    font-size: 15px;
    font-weight: 700;
    color: var(--ai-text);
}

#aiChatUsagePopover .ai-chat-credit-methods {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

#aiChatUsagePopover .ai-chat-credit-method {
    appearance: none;
    width: 100%;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: 12px;
    padding: 12px 14px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 12px;
    text-align: left;
    box-shadow: var(--ai-shadow-sm);
    transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
    touch-action: manipulation;
}

#aiChatUsagePopover .ai-chat-credit-method:hover:not(:disabled) {
    transform: translateY(-1px);
    border-color: var(--ai-green);
    box-shadow: var(--ai-shadow-md);
}

#aiChatUsagePopover .ai-chat-credit-method:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

#aiChatUsagePopover .ai-chat-credit-method-icon {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: linear-gradient(135deg, #635bff 0%, #4b3df4 100%);
    /* Stripe purple */
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    flex-shrink: 0;
}

#aiChatUsagePopover .ai-chat-credit-method-icon-rzp {
    background: linear-gradient(135deg, #0a2540 0%, #1e3a8a 100%);
    /* Razorpay dark blue */
}

#aiChatUsagePopover .ai-chat-credit-method-body {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

#aiChatUsagePopover .ai-chat-credit-method-name {
    font-size: 14px;
    font-weight: 700;
    color: var(--ai-text);
    line-height: 1.2;
}

#aiChatUsagePopover .ai-chat-credit-method-sub {
    margin-top: 2px;
    font-size: 11px;
    color: var(--ai-text-muted);
    line-height: 1.3;
}

#aiChatUsagePopover .ai-chat-credit-method-arrow {
    color: var(--ai-text-faint);
    font-size: 12px;
    flex-shrink: 0;
}

#aiChatUsagePopover .ai-chat-credit-method:hover:not(:disabled) .ai-chat-credit-method-arrow {
    color: var(--ai-green-dark);
}

/* ═══════════════════════════════════════════════════════
   DARK MODE ONE-OFFS — everything vars can't cover
   ═══════════════════════════════════════════════════════ */
body.dark-mode .ai-chat-overlay {
    background: rgba(0, 0, 0, 0.6);
}

body.dark-mode .ai-header-icon {
    box-shadow: 0 2px 10px rgba(129, 181, 4, 0.25);
}

body.dark-mode .ai-chat-hero-beta {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

/* Assistant glass bubble on dark — stronger fill so it reads */
body.dark-mode .ai-chat-msg-assistant .ai-chat-bubble {
    background: rgba(129, 181, 4, 0.11);
    border-color: rgba(129, 181, 4, 0.2);
}

/* User glass bubble on dark — stronger blue presence */
body.dark-mode .ai-chat-msg-user .ai-chat-bubble {
    background: rgba(10, 103, 178, 0.24);
    border-color: rgba(10, 103, 178, 0.4);
}

/* Loading skeleton matches the dark reply glass */
body.dark-mode .ai-chat-loading-bubble {
    background: rgba(129, 181, 4, 0.11);
    border-color: rgba(129, 181, 4, 0.2);
}

body.dark-mode .ai-chat-shimmer-line {
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.06) 25%, rgba(255, 255, 255, 0.13) 50%, rgba(255, 255, 255, 0.06) 75%);
    background-size: 400px 100%;
}

/* Markdown accents that need brighter tones on dark */
body.dark-mode .ai-chat-bubble code {
    background: rgba(125, 211, 252, 0.1);
    color: #7dd3fc;
}

body.dark-mode .ai-chat-bubble a {
    color: #6db9ea;
    border-bottom-color: rgba(109, 185, 234, 0.35);
}

body.dark-mode .ai-chat-bubble a:hover {
    color: var(--ai-green-light);
    border-bottom-color: var(--ai-green-light);
}

/* Tables in dark mode: a recessed near-black card (translucent, so
   it stays in the bubble's tonal family) with a green header band —
   crisp dashboard look instead of a flat gray block. */
body.dark-mode .ai-chat-table-wrap {
    background: rgba(0, 0, 0, 0.34);
    border-color: rgba(255, 255, 255, 0.08);
}

body.dark-mode .ai-chat-table-wrap .ai-csv-dl {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.16);
}

body.dark-mode .ai-chat-bubble th {
    background: rgba(129, 181, 4, 0.12);
    color: #c4dd93;
    border-bottom: none;
    padding-top: 9px;
    padding-bottom: 9px;
}

body.dark-mode .ai-chat-bubble th:first-child {
    border-radius: 8px 0 0 8px;
}

body.dark-mode .ai-chat-bubble th:last-child {
    border-radius: 0 8px 8px 0;
}

body.dark-mode .ai-chat-bubble td {
    color: #e6eef3;
    border-bottom-color: rgba(255, 255, 255, 0.06);
}

body.dark-mode .ai-chat-bubble td:first-child {
    color: var(--ai-text);
}

body.dark-mode .ai-chat-bubble td:last-child {
    color: rgba(154, 218, 5, 0.85);
}

body.dark-mode .ai-chat-bubble tr:nth-child(even) td {
    background: rgba(129, 181, 4, 0.05);
}

body.dark-mode .ai-chat-bubble tr:hover td {
    background: rgba(129, 181, 4, 0.1);
}

/* Status / profit colors brightened for the dark table */
body.dark-mode .ai-pl-profit {
    color: var(--ai-green-light);
}

body.dark-mode .ai-pl-loss {
    color: #ff7b72;
}

body.dark-mode .ai-st-working {
    color: var(--ai-green-light);
}

body.dark-mode .ai-st-idle {
    color: #f4d41f;
}

body.dark-mode .ai-st-offline {
    color: #ff6b81;
}

body.dark-mode .ai-st-other {
    color: #aab1c9;
}

/* Tool chips — muted green on dark */
body.dark-mode .ai-chat-tool-badge {
    color: rgba(154, 218, 5, 0.8);
    border-color: rgba(129, 181, 4, 0.22);
    background: rgba(129, 181, 4, 0.07);
}

/* Session icons — softened green on dark */
body.dark-mode .ai-chat-session-icon {
    color: rgba(129, 181, 4, 0.65);
}

/* CSV/Excel chips */
body.dark-mode .ai-csv-dl {
    color: #7dd3fc;
}

body.dark-mode .ai-csv-dl:hover {
    background: rgba(14, 165, 233, 0.15);
    border-color: #0ea5e9;
    color: #7dd3fc;
}

body.dark-mode .ai-csv-dl.ai-xls-dl {
    color: #86efac;
}

body.dark-mode .ai-csv-dl.ai-xls-dl:hover {
    background: rgba(22, 163, 74, 0.18);
    border-color: #16a34a;
    color: #86efac;
}

/* Error card */
body.dark-mode .ai-chat-error-icon {
    background: rgba(220, 38, 38, 0.18);
    color: #fca5a5;
}

body.dark-mode .ai-chat-error-retry {
    color: #fca5a5;
    border-color: rgba(252, 165, 165, 0.35);
}

body.dark-mode .ai-chat-error-retry:hover {
    background: rgba(220, 38, 38, 0.15);
}

body.dark-mode .ai-chat-error-retry.ai-chat-error-secondary {
    color: var(--ai-text-muted);
    border-color: var(--ai-border-strong);
}

/* Charts / choice chips (fight JS inline light styles) */
body.dark-mode .ai-chart-card {
    background: var(--ai-card) !important;
    border-color: var(--ai-border-strong) !important;
}

body.dark-mode .ai-chart-card div {
    color: var(--ai-text) !important;
}

body.dark-mode .ai-choice-chip {
    background: var(--ai-card) !important;
    border-color: rgba(109, 185, 234, 0.45) !important;
    color: #9fcdec !important;
}

body.dark-mode .ai-choice-chip:hover {
    background: rgba(10, 103, 178, 0.25) !important;
}

/* Credit banner tint on dark */
body.dark-mode #aiChatCreditBanner {
    background: rgba(129, 181, 4, 0.07);
}

body.dark-mode #aiChatCreditBanner .ai-chat-credit-banner-bar {
    background: rgba(255, 255, 255, 0.1);
}

/* Beats the legacy .dark-mode rule in dark_mode.css (#5c8300) */
body.dark-mode #aiChatCreditBanner .ai-chat-credit-banner-btn {
    background-color: var(--ai-card);
    border-color: var(--ai-border-strong);
    color: var(--ai-text);
}

body.dark-mode #aiChatCreditBanner.is-debt .ai-chat-credit-banner-label,
body.dark-mode #aiChatCreditBanner.is-debt .ai-chat-credit-banner-amount {
    color: #fca5a5;
}

/* Send button disabled state on dark */
body.dark-mode #aiChatSend:disabled {
    background: rgba(255, 255, 255, 0.12);
    color: rgba(255, 255, 255, 0.4);
}

/* Green glows softened across the dark chat */
body.dark-mode #aiChatSend {
    box-shadow: 0 3px 10px rgba(129, 181, 4, 0.18);
}

body.dark-mode .ai-chat-brand-logo {
    box-shadow: 0 3px 10px rgba(129, 181, 4, 0.15);
}

body.dark-mode .ai-chat-welcome-icon {
    box-shadow: 0 10px 28px rgba(129, 181, 4, 0.16);
}

body.dark-mode .ai-chat-msg .ai-chat-msg-avatar {
    box-shadow: 0 2px 8px rgba(129, 181, 4, 0.12);
}

body.dark-mode .ai-chat-new-btn {
    border-color: rgba(129, 181, 4, 0.25);
}

body.dark-mode .ai-chat-suggestions button i {
    background: rgba(129, 181, 4, 0.09);
    color: rgba(154, 218, 5, 0.8);
}

body.dark-mode .ai-chat-new-btn i,
body.dark-mode #aiChatCreditBanner .ai-chat-credit-banner-fill {
    opacity: 0.85;
}

/* Usage-bar warn/over shadows off on dark (cleaner) */
body.dark-mode #aiChatUsagePopover .ai-chat-usage-bar {
    background: rgba(255, 255, 255, 0.07);
    border-color: transparent;
}

/* ═══════════════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════════════ */
@media (min-width: 768px) {
    .ai-chat-panel {
        max-width: 720px;
    }
}

@media (min-width: 1200px) {
    .ai-chat-panel {
        max-width: 760px;
    }
}

/* Sidebar becomes an overlay drawer on small screens.
   Keep 820px in sync with the JS auto-collapse breakpoint. */
@media (max-width: 820px) {
    .ai-chat-panel {
        max-width: 100vw;
    }

    .ai-chat-sidebar {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 20;
        width: 264px;
        flex: none;
        opacity: 1;
        border-right: 1px solid var(--ai-border);
        box-shadow: 16px 0 40px rgba(2, 32, 54, 0.22);
        transform: translateX(0);
        transition: transform var(--ai-transition);
    }

    .ai-chat-panel.ai-chat-sidebar-collapsed .ai-chat-sidebar {
        transform: translateX(-100%);
        width: 264px;
        flex: none;
        opacity: 1;
        pointer-events: none;
        border-right-width: 1px;
    }

    .ai-chat-sidebar-show {
        display: inline-flex !important;
    }

    .ai-chat-fullscreen .ai-chat-sidebar {
        width: 264px;
        flex: none;
    }
}

/* Touch devices: keep message actions visible */
@media (hover: none) {
    .ai-chat-msg-actions {
        opacity: 1;
    }

    .ai-chat-session-export,
    .ai-chat-session-delete {
        display: inline-flex;
    }

    .ai-chat-session .ai-chat-session-title {
        padding-right: 56px;
    }
}

@media (max-width: 480px) {
    .ai-chat-panel {
        max-width: 100vw;
    }

    .ai-chat-messages {
        padding: 14px 12px 8px;
    }

    .ai-chat-msg {
        padding-left: 38px;
    }

    .ai-chat-loading {
        padding-left: 38px;
    }

    .ai-chat-msg .ai-chat-msg-avatar,
    .ai-chat-loading-avatar {
        width: 28px;
        height: 28px;
    }

    .ai-chat-msg::before {
        left: 13px;
        top: 34px;
    }

    .ai-chat-msg-user .ai-chat-bubble {
        max-width: 100%;
        font-size: 14px;
    }

    .ai-chat-msg-assistant .ai-chat-bubble {
        font-size: 14px;
    }

    .ai-chat-header {
        min-height: 58px;
        padding: 10px 12px;
    }

    .ai-chat-input-area {
        padding: 10px 12px 6px;
    }

    /* iOS zoom-on-focus guard */
    #aiChatInput {
        font-size: 16px;
    }

    .ai-chat-input-hint {
        display: none;
    }

    #aiChatCreditBanner {
        margin: 6px 12px 0;
        padding: 6px 12px;
        font-size: 12px;
    }

    #aiChatCreditBanner .ai-chat-credit-banner-btn {
        padding: 6px 10px;
        font-size: 11px;
    }

    #aiChatCreditBanner .ai-chat-credit-banner-unit {
        display: none;
    }

    #aiChatUsagePopover {
        padding: 14px;
    }

    #aiChatUsagePopover .ai-chat-credit-packs {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 360px) {
    .ai-chat-header {
        min-height: 54px;
        padding: 8px 10px;
    }

    .ai-chat-avatar {
        width: 32px;
        height: 32px;
        border-radius: 10px;
    }

    .ai-chat-avatar img {
        width: 20px;
        height: 20px;
    }

    .ai-chat-btn-icon {
        width: 30px;
        height: 30px;
    }

    .ai-chat-sidebar-brand {
        padding: 12px 12px 8px;
    }
}

/* ─── Reduced motion ────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {

    .ai-chat-overlay,
    .ai-chat-panel,
    .ai-chat-msg,
    .ai-chat-loading,
    .ai-chat-error,
    .ai-chat-welcome-icon,
    .ai-chat-welcome h4,
    .ai-chat-welcome p,
    .ai-chat-suggestions button,
    .ai-chat-tool-badge,
    .ai-chat-loading-avatar,
    .ai-chat-loading-dot,
    .ai-chat-shimmer-line,
    .ai-chat-sidebar-loading-row,
    .ai-header-icon::after,
    .ai-status-thinking,
    .ai-chat-confirm,
    .ai-chat-confirm-box,
    #aiChatUsagePopover,
    #aiChatUsagePopover .ai-chat-usage-card {
        animation: none !important;
    }

    .ai-chat-sidebar,
    .ai-chat-typewriter,
    .ai-chat-msg-actions,
    #aiChatSend,
    .ai-chat-btn-icon,
    .ai-chat-new-btn,
    .ai-chat-session,
    .ai-chat-suggestions button {
        transition: none !important;
    }

    .ai-chat-typewriter {
        opacity: 1;
        transform: none;
    }
}

/* ── Interactive task-creation card (desklog:task-card block, rule 59) ─────────────
   Rendered by aiRenderTaskCard() in ai_chat.js. Built entirely from the --ai-*
   tokens so it themes for light/dark automatically; the only hard-coded pieces
   are the Billable toggle + green submit button (no such components existed
   to reuse). */
.ai-task-card {
    margin: 10px 0;
    padding: 14px 16px 16px;
    border: 1px solid var(--ai-border);
    border-radius: 14px;
    background: var(--ai-card);
    box-shadow: var(--ai-shadow-sm);
    color-scheme: light;   /* native date-picker controls follow the theme */
}
body.dark-mode .ai-task-card { color-scheme: dark; border-color: var(--ai-border-strong); }

.ai-tc-head { display: flex; align-items: center; gap: 8px; margin: 0 0 12px; }
.ai-tc-head-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; border-radius: 7px; flex: 0 0 auto;
    background: var(--ai-green-soft); color: var(--ai-green-dark); font-size: 12px;
}
.ai-tc-head-title {
    font-size: 14px; font-weight: 700; color: var(--ai-green-dark);
    line-height: 1.3; word-break: break-word;
}

/* Title field — token-driven like .ai-form-input, so it stays light in the
   light theme and only goes dark under body.dark-mode. */
.ai-tc-title {
    display: block; width: 100%; box-sizing: border-box; margin: 0 0 12px;
    padding: 11px 14px;
    border: 1.5px solid var(--ai-border-strong); border-radius: 10px;
    background: var(--ai-card); color: var(--ai-text);
    font-family: inherit; font-size: 14px; font-weight: 600;
    outline: none; transition: border-color var(--ai-transition), box-shadow var(--ai-transition);
}
.ai-tc-title::placeholder { color: var(--ai-text-faint); font-weight: 500; }
.ai-tc-title:focus { border-color: var(--ai-green); box-shadow: 0 0 0 3px var(--ai-green-soft); }

.ai-tc-rows { border: 1px solid var(--ai-border); border-radius: 12px; overflow: hidden; }
/* The Assignee search list is a child of a row, so this box's overflow — which is only
   here to trim child borders to the rounded corners — would clip the dropdown out of
   sight. aiComboUnclip() adds this class for exactly as long as a list inside is open. */
.ai-tc-rows-open { overflow: visible; }
.ai-tc-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; padding: 11px 14px; min-height: 44px;
    border-top: 1px solid var(--ai-border);
}
.ai-tc-rows .ai-tc-row:first-child { border-top: none; }
.ai-tc-label {
    display: inline-flex; align-items: center; gap: 9px; flex: 0 0 auto;
    font-size: 13px; font-weight: 600; color: var(--ai-text-body); white-space: nowrap;
}
.ai-tc-label i { color: var(--ai-text-faint); width: 15px; text-align: center; }

/* Right-aligned inline value inputs (description / assignee / estimate). */
.ai-tc-input {
    flex: 1 1 auto; min-width: 0;
    border: none; outline: none; background: transparent; text-align: right;
    font-family: inherit; font-size: 13.5px; color: var(--ai-text);
}
.ai-tc-input::placeholder { color: var(--ai-text-faint); }
.ai-tc-input-sm { max-width: 120px; }
/* Search-box wrapper for an inline row value (Assignee). It takes over the input's flex
   role so the row lays out exactly as it did, and gives the absolutely-positioned results
   list something to anchor to — the list then spans the input, not the whole card. */
.ai-tc-combo { position: relative; display: flex; flex: 1 1 auto; min-width: 0; }
.ai-tc-estimate { font-weight: 700; }

.ai-tc-date-wrap { display: inline-flex; align-items: center; gap: 8px; }
.ai-tc-date {
    border: none; outline: none; background: transparent; text-align: right;
    font-family: inherit; font-size: 13.5px; color: var(--ai-text);
}
.ai-tc-pill {
    font-size: 11px; font-weight: 700; color: var(--ai-green-dark);
    background: var(--ai-green-soft); padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
.ai-tc-pill-off { display: none; }

/* Billable toggle switch (built from scratch — no toggle existed to reuse). */
.ai-tc-toggle { position: relative; display: inline-block; width: 40px; height: 22px; flex: 0 0 auto; }
.ai-tc-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.ai-tc-slider {
    position: absolute; inset: 0; cursor: pointer;
    background: var(--ai-border-strong); border-radius: 999px;
    transition: background var(--ai-transition);
}
.ai-tc-slider::before {
    content: ''; position: absolute; top: 3px; left: 3px;
    width: 16px; height: 16px; border-radius: 50%;
    background: #fff; box-shadow: var(--ai-shadow-sm);
    transition: transform var(--ai-transition);
}
.ai-tc-toggle input:checked + .ai-tc-slider { background: var(--ai-green); }
.ai-tc-toggle input:checked + .ai-tc-slider::before { transform: translateX(18px); }
body.dark-mode .ai-tc-slider { background: rgba(255, 255, 255, 0.14); }

.ai-tc-status { margin: 10px 2px 0; font-size: 12px; font-weight: 600; }
.ai-tc-status-err { color: var(--ai-danger); }
.ai-tc-status-ok { color: var(--ai-green-dark); }

.ai-tc-actions { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.ai-tc-create {
    flex: 1 1 auto; cursor: pointer;
    border: none; border-radius: 12px; padding: 11px 16px;
    background: var(--ai-green); color: #fff;
    font-family: inherit; font-size: 14px; font-weight: 700;
    box-shadow: 0 3px 10px rgba(129, 181, 4, 0.35);
    transition: background var(--ai-transition), box-shadow var(--ai-transition), transform var(--ai-transition);
}
.ai-tc-create:hover:not(:disabled) { background: var(--ai-green-dark); transform: translateY(-1px); }
.ai-tc-create:disabled { opacity: 0.75; cursor: default; box-shadow: none; }
body.dark-mode .ai-tc-create { box-shadow: 0 3px 10px rgba(129, 181, 4, 0.18); }

.ai-tc-defaults {
    flex: 0 0 auto; cursor: pointer;
    background: var(--ai-card); color: var(--ai-text-body);
    border: 1px solid var(--ai-border-strong); border-radius: 12px; padding: 11px 18px;
    font-family: inherit; font-size: 13px; font-weight: 600;
    transition: background var(--ai-transition);
}
.ai-tc-defaults:hover:not(:disabled) { background: var(--ai-card-alt); }
.ai-tc-defaults:disabled { opacity: 0.6; cursor: default; }

.ai-task-card-done { opacity: 0.92; }
.ai-task-card-done .ai-tc-rows { opacity: 0.75; }

/* ── Task-card: labelled Project/Title fields + inline error banner (rule 60) ─────
   The editable "Project Name (required)" field above the title, a flagged-field
   state, and the desklog:error banner (also used standalone) with suggestion chips.
   Token-driven so it themes for light/dark; amber has no token so it is hard-coded. */
.ai-tc-field { margin: 0 0 12px; }
.ai-tc-flabel {
    display: block; margin: 0 0 5px 2px;
    font-size: 12px; font-weight: 600; color: var(--ai-text-muted);
}
.ai-tc-req { color: var(--ai-danger); font-weight: 600; }
.ai-tc-field .ai-tc-title { margin: 0; }   /* the field wrapper now owns the spacing */

.ai-tc-project {
    display: block; width: 100%; box-sizing: border-box; padding: 10px 12px;
    border: 1.5px solid var(--ai-border-strong); border-radius: 10px;   /* match the title field */
    background: var(--ai-card); color: var(--ai-text);
    font-family: inherit; font-size: 13.5px;
    outline: none; transition: border-color var(--ai-transition), box-shadow var(--ai-transition);
}
.ai-tc-project::placeholder { color: var(--ai-text-faint); }
.ai-tc-project:focus { border-color: var(--ai-green); box-shadow: 0 0 0 3px var(--ai-green-soft); }
/* A resolved Parent Task is read-only (aiSubtaskContinue locks it). Now that the box is
   a search field, one that looks live but answers nothing reads as broken — so show the
   settled state. */
.ai-tc-project.ai-tc-locked {
    background: var(--ai-card-alt); color: var(--ai-text-muted); cursor: default;
}
.ai-tc-project.ai-tc-locked:focus { border-color: var(--ai-border-strong); box-shadow: none; }

/* Flagged field — red ring on whichever input the error banner points at. */
.ai-tc-flag, .ai-tc-flag:focus {
    border-color: var(--ai-danger) !important;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.14) !important;
}
.ai-tc-input.ai-tc-flag, .ai-tc-date.ai-tc-flag {
    border: 1.5px solid var(--ai-danger) !important; border-radius: 8px; padding: 4px 8px;
}

.ai-tc-banner { margin: 0 0 12px; }
.ai-tc-banner .ai-task-error { margin: 0; max-width: none; }

/* Inline error / warning banner (also rendered standalone for a desklog:error block). */
.ai-task-error {
    margin: 8px 0; padding: 11px 13px;
    border: 1px solid transparent; border-radius: 12px;
}
.ai-task-error-warning { background: rgba(217, 119, 6, 0.08); border-color: rgba(217, 119, 6, 0.30); }
.ai-task-error-error   { background: rgba(220, 38, 38, 0.07); border-color: rgba(220, 38, 38, 0.28); }
body.dark-mode .ai-task-error-warning { background: rgba(217, 119, 6, 0.15); border-color: rgba(217, 119, 6, 0.42); }
body.dark-mode .ai-task-error-error   { background: rgba(220, 38, 38, 0.15); border-color: rgba(220, 38, 38, 0.42); }

.ai-te-head { display: flex; align-items: flex-start; gap: 10px; }
.ai-te-icon { flex: 0 0 auto; font-size: 15px; line-height: 1.4; }
.ai-task-error-warning .ai-te-icon { color: #b45309; }
.ai-task-error-error   .ai-te-icon { color: var(--ai-danger); }
body.dark-mode .ai-task-error-warning .ai-te-icon { color: #f59e0b; }
body.dark-mode .ai-task-error-error   .ai-te-icon { color: #f87171; }
.ai-te-text { min-width: 0; }
.ai-te-title { font-size: 13px; font-weight: 700; line-height: 1.35; color: var(--ai-text); }
.ai-task-error-warning .ai-te-title { color: #92400e; }
.ai-task-error-error   .ai-te-title { color: #991b1b; }
body.dark-mode .ai-task-error-warning .ai-te-title { color: #fbbf24; }
body.dark-mode .ai-task-error-error   .ai-te-title { color: #fca5a5; }
.ai-te-msg { margin-top: 2px; font-size: 12.5px; line-height: 1.45; color: var(--ai-text-body); }

.ai-te-suglabel {
    margin: 10px 0 6px;
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
    color: var(--ai-text-faint);
}
.ai-te-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ai-te-chip {
    cursor: pointer; font-family: inherit; font-size: 12.5px; font-weight: 600;
    padding: 6px 13px; border-radius: 999px;
    overflow-wrap: anywhere; min-width: 0; max-width: 100%;
    border: 1px solid var(--ai-border-strong); background: var(--ai-card); color: var(--ai-text-body);
    transition: all var(--ai-transition);
}
.ai-te-chip:hover { border-color: var(--ai-green); color: var(--ai-green-dark); transform: translateY(-1px); }

/* Toasts must sit ABOVE the AI chat blurred overlay (.ai-chat-overlay, z-index 10001),
   never behind it. The snackbar plugin's own z-index (9999) is below the overlay, so a
   "Task added successfully" toast rendered under the blur — lift every toast above it. */
.snackbar-container { z-index: 100000 !important; }

/* ── Interactive create form (desklog:form block, rule 61) ────────────────────────
   project / sprint / client / tag form. Reuses the task-card shell + field classes
   (.ai-tc-head/-field/-flabel/-req/-banner/-status/-actions/-create/-flag); only the
   input/select/textarea and hint need their own token-driven, theme-aware styles. */
.ai-form-card {
    margin: 10px 0; padding: 14px 16px 16px;
    border: 1px solid var(--ai-border); border-radius: 14px;
    background: var(--ai-card); box-shadow: var(--ai-shadow-sm);
    color-scheme: light;
}
body.dark-mode .ai-form-card { color-scheme: dark; border-color: var(--ai-border-strong); }

.ai-form-input {
    display: block; width: 100%; box-sizing: border-box; padding: 9px 12px;
    border: 1.5px solid var(--ai-border-strong); border-radius: 9px;
    background: var(--ai-card); color: var(--ai-text);
    font-family: inherit; font-size: 13.5px; outline: none;
    transition: border-color var(--ai-transition), box-shadow var(--ai-transition);
}
.ai-form-input::placeholder { color: var(--ai-text-faint); }
.ai-form-input:focus { border-color: var(--ai-green); box-shadow: 0 0 0 3px var(--ai-green-soft); }
textarea.ai-form-input { min-height: 62px; resize: vertical; line-height: 1.5; }
select.ai-form-input { cursor: pointer; }

/* Searchable lookup (projects, parent tasks, people): a text box whose results float
   over the fields below it, so opening it never reflows the form or the card. Same
   tokens as .ai-form-input so it reads as one control in both themes. */
.ai-form-combo { position: relative; }
.ai-form-combo-list {
    position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 4px);
    max-height: 210px; overflow-y: auto;
    border: 1.5px solid var(--ai-border-strong); border-radius: 9px;
    background: var(--ai-card); box-shadow: 0 8px 24px rgba(0, 0, 0, .28);
}
.ai-form-combo-list[hidden] { display: none; }
.ai-form-combo-item {
    padding: 8px 12px; font-size: 13.5px; color: var(--ai-text); cursor: pointer;
    transition: background var(--ai-transition);
}
.ai-form-combo-item:hover { background: var(--ai-green-soft); }
.ai-form-combo-empty { padding: 8px 12px; font-size: 12.5px; color: var(--ai-text-faint); }

.ai-form-hint { margin: 5px 2px 0; font-size: 11.5px; color: var(--ai-text-faint); }

/* ── SUPPORT TICKET CARD: the thread, then the reply box ─────────────────────
   A form card may open a RECORD rather than a blank: the ticket's reference and
   status under the title, the conversation so far, and the reply box beneath it
   — the order a ticket reads everywhere else in the product. Every rule here is
   scoped to markup only the support card emits, so the create forms are
   untouched. Colours come from the same tokens as the rest of the card, so both
   themes follow automatically. */
.ai-tk-meta {
    margin: -6px 0 10px 30px;
    font-size: 11.5px; color: var(--ai-text-faint);
}
.ai-tk-status {
    display: inline-block; padding: 1px 7px; border-radius: 999px;
    font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em;
    background: var(--ai-green-soft); color: var(--ai-green);
}
.ai-tk-status.ai-tk-closed { background: var(--ai-surface-alt); color: var(--ai-text-faint); }
/* Support has answered and is waiting on the user — the one state worth drawing
   attention to, because it is the state a reply box exists for. */
.ai-tk-status.ai-tk-awaiting-your-reply { background: var(--ai-amber-soft, #fdf1dc); color: var(--ai-amber, #9a6b1a); }

/* Said before Send, not after: replying to a closed or resolved ticket reopens it. */
.ai-tk-notice {
    margin: 0 0 10px; padding: 7px 10px; border-radius: 8px;
    font-size: 11.5px; line-height: 1.45;
    background: var(--ai-amber-soft, #fdf1dc); color: var(--ai-amber, #9a6b1a);
}
.ai-tk-notice i { margin-right: 5px; }

.ai-tk-thread {
    max-height: 260px; overflow-y: auto;
    margin: 0 0 12px; padding: 10px 12px;
    border: 1px solid var(--ai-border); border-radius: 10px;
    background: var(--ai-surface-alt);
}
.ai-tk-msg { margin: 0 0 10px; max-width: 88%; }
.ai-tk-msg:last-child { margin-bottom: 0; }
/* The user's own messages sit right, support's left — the same reading order as
   the Ticket page's conversation, so the two do not contradict each other. */
.ai-tk-mine { margin-left: auto; }
.ai-tk-who {
    display: flex; gap: 8px; align-items: baseline;
    font-size: 11px; font-weight: 600; color: var(--ai-text-faint); margin: 0 0 3px;
}
.ai-tk-mine .ai-tk-who { justify-content: flex-end; }
.ai-tk-when { font-weight: 400; font-size: 10.5px; }
.ai-tk-body {
    padding: 8px 11px; border-radius: 10px;
    background: var(--ai-card); border: 1px solid var(--ai-border);
    font-size: 13px; line-height: 1.5; color: var(--ai-text);
    white-space: pre-wrap; word-break: break-word;
}
.ai-tk-mine .ai-tk-body { background: var(--ai-green-soft); border-color: transparent; }
.ai-tk-clip { margin: 5px 2px 0; font-size: 11.5px; display: flex; flex-wrap: wrap; gap: 8px; }
.ai-tk-mine .ai-tk-clip { justify-content: flex-end; }
.ai-tk-file {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px; border-radius: 999px;
    border: 1px solid var(--ai-border); background: var(--ai-card);
    color: var(--ai-green); text-decoration: none; word-break: break-all;
}
.ai-tk-file:hover { border-color: var(--ai-green); text-decoration: underline; }
/* Just sent: the desk has not given us a URL yet, so it is a label, not a link. */
.ai-tk-file-pending { color: var(--ai-text-faint); border-style: dashed; }
.ai-tk-body.ai-tk-empty { color: var(--ai-text-faint); font-style: italic; }

/* The picker on the reply box. */
.ai-form-file { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ai-form-fileinput { font-size: 12.5px; color: var(--ai-text); max-width: 100%; }
.ai-form-filename { font-size: 11.5px; color: var(--ai-text-faint); word-break: break-all; }

/* A support message that arrived while the card was open, rather than one that was
   there when it rendered. Marked so the eye finds it after a 30s gap; the highlight
   fades on its own so an old thread does not stay lit. */
.ai-tk-msg.ai-tk-new .ai-tk-body {
    border-color: var(--ai-green);
    animation: ai-tk-arrive 2.4s ease-out 1;
}
@keyframes ai-tk-arrive {
    0%   { background: var(--ai-green-soft); }
    100% { background: var(--ai-card); }
}
@media (prefers-reduced-motion: reduce) {
    .ai-tk-msg.ai-tk-new .ai-tk-body { animation: none; }
}

/* Multi-value picker (create-project Team Members): one search box over people AND
   teams, with the picks below it as removable chips. The chosen ids live in a hidden
   <select multiple> inside this wrapper — the chips are presentation, the select is
   the value the form submits. Positioned so .ai-form-combo-list floats over the
   fields below exactly as it does for a single lookup. */
.ai-form-multi-wrap { position: relative; }
.ai-form-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.ai-form-chips:empty { margin-top: 0; }
.ai-form-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 8px 4px 10px; border-radius: 999px;
    border: 1.5px solid var(--ai-border-strong); background: var(--ai-green-soft);
    font-size: 12.5px; color: var(--ai-text); line-height: 1.4;
}
.ai-form-chip-x {
    border: 0; background: none; padding: 0; cursor: pointer;
    font-size: 15px; line-height: 1; color: var(--ai-text-faint);
    transition: color var(--ai-transition);
}
.ai-form-chip-x:hover { color: var(--ai-text); }


/* ══ Slash-command palette (/ in the chat input) ══════════════════════════
   Anchored above the input inside .ai-chat-input-area (position:relative).
   Consumes only --ai-* tokens, so body.dark-mode is handled automatically. */
.ai-cmd-palette {
    position: absolute;
    bottom: 100%;
    left: 16px;
    right: 16px;
    margin-bottom: 8px;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: var(--ai-radius);
    box-shadow: var(--ai-shadow-lg);
    padding: 6px;
    max-height: 280px;
    overflow-y: auto;
    animation: aiFadeSlideIn 0.18s ease;
    z-index: 30;
}
.ai-cmd-title {
    padding: 4px 10px 6px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ai-text-faint);
}
.ai-cmd-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    background: none;
    border: none;
    border-radius: var(--ai-radius-sm);
    text-align: left;
    cursor: pointer;
    color: var(--ai-text);
    transition: background 0.12s ease;
}
.ai-cmd-item:hover,
.ai-cmd-item.is-active { background: var(--ai-card-alt); }
.ai-cmd-item.is-active { box-shadow: inset 2px 0 0 var(--ai-green); }
.ai-cmd-item-icon {
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: var(--ai-green-soft);
    color: var(--ai-green-dark);
    font-size: 13px;
}
.ai-cmd-item-text { min-width: 0; }
.ai-cmd-item-title { display: block; font-size: 13px; font-weight: 600; color: var(--ai-text); }
.ai-cmd-item-hint { display: block; font-size: 11.5px; color: var(--ai-text-muted); }
.ai-cmd-empty { padding: 10px 12px; font-size: 12.5px; color: var(--ai-text-muted); }
.ai-cmd-foot {
    display: flex;
    gap: 14px;
    margin-top: 4px;
    padding: 6px 10px 2px;
    border-top: 1px solid var(--ai-border);
    font-size: 11px;
    color: var(--ai-text-faint);
}
.ai-cmd-foot kbd {
    padding: 0 4px;
    background: var(--ai-card-alt);
    border: 1px solid var(--ai-border);
    border-radius: 4px;
    font-size: 10px;
    font-family: inherit;
    color: var(--ai-text-muted);
}

/* Fullscreen centers the input on an 840px column via .ai-chat-input-area
   PADDING — but the palette is absolutely positioned, and absolute insets
   ignore padding. Mirror the same formula so the palette tracks the input
   box width exactly (docked mode keeps the 16px insets above). */
.ai-chat-fullscreen .ai-cmd-palette {
    left: max(24px, calc((100% - 840px) / 2));
    right: max(24px, calc((100% - 840px) / 2));
}

/* ══ /ticket wizard — inline card in the chat timeline ════════════════════
   No max-width cap: the card fills the messages column, which is the SAME
   840px-centered column the input box uses in fullscreen (and the full panel
   width when docked) — so the card always lines up with the input below. */
.ai-ticket-wizard {
    width: 100%;
    margin: 10px 0;
    /* The fullscreen welcome turns .ai-chat-messages into a flex column;
       without this the card SHRINKS to fit the viewport (flex-shrink:1
       default) and overflow:hidden clips its bottom fields — the container
       never overflows, so no scroll can ever reveal them. */
    flex-shrink: 0;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: var(--ai-radius);
    box-shadow: var(--ai-shadow-md);
    overflow: hidden;
    animation: aiFadeSlideIn 0.2s ease;
}
.ai-tw-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    background: var(--ai-surface);
    border-bottom: 1px solid var(--ai-border);
}
.ai-tw-title { font-size: 13px; font-weight: 600; color: var(--ai-text); }
.ai-tw-title .fa { margin-right: 6px; color: var(--ai-green-dark); }
.ai-tw-close {
    width: 26px;
    height: 26px;
    border: none;
    background: none;
    border-radius: 8px;
    font-size: 17px;
    line-height: 1;
    color: var(--ai-text-muted);
    cursor: pointer;
}
.ai-tw-close:hover { background: var(--ai-card-alt); color: var(--ai-text); }
.ai-tw-body { padding: 14px; }
.ai-tw-question { margin-bottom: 10px; font-size: 13.5px; font-weight: 600; color: var(--ai-text); }
.ai-tw-options { display: flex; flex-direction: column; gap: 8px; }
.ai-tw-option {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: var(--ai-radius-sm);
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.ai-tw-option:hover {
    border-color: var(--ai-green);
    box-shadow: 0 0 0 3px var(--ai-green-soft);
}
.ai-tw-option-icon {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    background: var(--ai-green-soft);
    color: var(--ai-green-dark);
    font-size: 15px;
}
.ai-tw-option-text { min-width: 0; }
.ai-tw-option-text strong { display: block; font-size: 13px; color: var(--ai-text); }
.ai-tw-option-text small { display: block; font-size: 11.5px; color: var(--ai-text-muted); }
.ai-tw-crumb { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.ai-tw-back {
    padding: 3px 8px;
    background: none;
    border: 1px solid var(--ai-border-strong);
    border-radius: 999px;
    font-size: 11.5px;
    color: var(--ai-text-muted);
    cursor: pointer;
}
.ai-tw-back:hover { border-color: var(--ai-green); color: var(--ai-text); }
.ai-tw-crumb-label { font-size: 12px; font-weight: 600; color: var(--ai-text-muted); }
.ai-tw-note {
    margin-bottom: 10px;
    padding: 7px 10px;
    background: var(--ai-green-soft);
    border-radius: var(--ai-radius-sm);
    font-size: 12px;
    color: var(--ai-text-body);
}
.ai-tw-note .fa { margin-right: 5px; color: var(--ai-green-dark); }
.ai-tw-note-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.ai-tw-note-row > span { min-width: 0; }
.ai-tw-note-row strong { font-weight: 600; }
.ai-tw-link {
    flex: 0 0 auto;
    padding: 0;
    background: none;
    border: none;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ai-green-dark);
    text-decoration: underline;
    cursor: pointer;
}

/* Sub-heading over the fetched list when the current chat sits above it. */
.ai-tw-sublabel {
    margin: 12px 0 6px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ai-text-muted);
}

/* Set by the wizard while the card is parked at the bottom of a short
   conversation: the strip of padding under it (and the credit banner's top
   margin) would otherwise leave the card floating above the bar below.
   Present ONLY while the card is pinned — normal chat spacing is untouched. */
.ai-chat-messages.ai-tw-pinned { padding-bottom: 0; }
.ai-chat-messages.ai-tw-pinned + #aiChatCreditBanner { margin-top: 0; }

/* Chat picker — which conversation goes with an AI-chat ticket. Forced in
   when the current chat is empty (there is nothing to attach) and reachable
   any time from the form's Change link. Previous chats are scoped to the last
   7 days; the current one is always offered on top. */
.ai-tw-hint {
    margin-left: 6px;
    font-size: 11px;
    font-weight: 500;
    color: var(--ai-text-faint);
}
.ai-tw-picker {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 210px;
    margin-bottom: 12px;
    overflow-y: auto;
}
.ai-tw-chat {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: var(--ai-radius-sm);
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.ai-tw-chat:hover {
    border-color: var(--ai-green);
    box-shadow: 0 0 0 3px var(--ai-green-soft);
}
/* The chat currently set to go with the ticket — the current one by default,
   or whatever the user changed it to. */
.ai-tw-chat.is-active {
    border-color: var(--ai-green);
    background: var(--ai-green-soft);
}
.ai-tw-chat.is-active .ai-tw-chat-go { color: var(--ai-green-dark); }
.ai-tw-chat-icon {
    flex: 0 0 26px;
    width: 26px;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: var(--ai-green-soft);
    color: var(--ai-green-dark);
    font-size: 12px;
}
.ai-tw-chat-text { flex: 1; min-width: 0; }
.ai-tw-chat-text strong {
    display: block;
    font-size: 12.5px;
    color: var(--ai-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ai-tw-chat-text small { display: block; font-size: 11px; color: var(--ai-text-muted); }
.ai-tw-chat-go { flex: 0 0 auto; color: var(--ai-text-faint); font-size: 14px; }
.ai-tw-picker-empty {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 10px;
    border: 1px dashed var(--ai-border-strong);
    border-radius: var(--ai-radius-sm);
    font-size: 12px;
    color: var(--ai-text-muted);
}
.ai-tw-picker-loading { display: flex; flex-direction: column; gap: 6px; }
.ai-tw-picker-loading span {
    height: 42px;
    border-radius: var(--ai-radius-sm);
    background: var(--ai-card-alt);
    animation: aiTwPulse 1.1s ease-in-out infinite;
}
.ai-tw-picker-loading span:nth-child(2) { animation-delay: 0.12s; }
.ai-tw-picker-loading span:nth-child(3) { animation-delay: 0.24s; }
@keyframes aiTwPulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
.ai-tw-actions-end { justify-content: flex-end; }
.ai-tw-field { margin-bottom: 10px; }
.ai-tw-field label {
    display: block;
    margin-bottom: 4px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ai-text-muted);
}
.ai-tw-field .ai-form-input { width: 100%; box-sizing: border-box; }
.ai-tw-textarea { min-height: 84px; }
.ai-tw-error {
    margin-bottom: 10px;
    padding: 7px 10px;
    border: 1px solid rgba(220, 38, 38, 0.35);
    border-radius: var(--ai-radius-sm);
    background: rgba(220, 38, 38, 0.07);
    font-size: 12px;
    color: var(--ai-danger);
}
.ai-tw-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ai-tw-email-note { font-size: 11px; color: var(--ai-text-faint); }
.ai-tw-email-note .fa { margin-right: 4px; }
.ai-tw-btn {
    padding: 7px 14px;
    background: var(--ai-card);
    border: 1px solid var(--ai-border-strong);
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ai-text);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.ai-tw-btn:hover { border-color: var(--ai-green); }
/* "Attach no chat" while that is the standing choice. */
.ai-tw-btn.is-active { border-color: var(--ai-green); color: var(--ai-text); }
.ai-tw-btn-primary {
    background: var(--ai-green);
    border-color: var(--ai-green);
    color: #ffffff;
}
.ai-tw-btn-primary:hover { background: var(--ai-green-dark); border-color: var(--ai-green-dark); }
.ai-tw-btn-primary:disabled { opacity: 0.65; cursor: default; }
.ai-tw-spinner {
    display: inline-block;
    width: 11px;
    height: 11px;
    margin-right: 5px;
    border: 2px solid rgba(255, 255, 255, 0.45);
    border-top-color: #ffffff;
    border-radius: 50%;
    vertical-align: -1px;
    animation: aiTwSpin 0.7s linear infinite;
}
@keyframes aiTwSpin { to { transform: rotate(360deg); } }
.ai-tw-success { display: flex; align-items: center; gap: 12px; }
.ai-tw-success-icon {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--ai-green);
    color: #ffffff;
    font-size: 15px;
}
.ai-tw-success-text { flex: 1; min-width: 0; }
.ai-tw-success-text strong { display: block; font-size: 13px; color: var(--ai-text); }
.ai-tw-success-text small { display: block; font-size: 11.5px; color: var(--ai-text-muted); }

/* "Raise a ticket" chip on the welcome screen — same pill as the suggestion
   chips but green-accented so it reads as a support action, and it opens the
   ticket wizard (openAiTicketWizard) instead of sending a prompt. */
.ai-chat-suggest-chip.ai-chat-ticket-chip,
.ai-chat-suggestions .ai-chat-ticket-chip {
    border-color: var(--ai-green);
    color: var(--ai-green-dark);
}
.ai-chat-suggest-chip.ai-chat-ticket-chip:hover,
.ai-chat-suggestions .ai-chat-ticket-chip:hover {
    background: var(--ai-green-soft);
}
.ai-chat-suggest-chip.ai-chat-ticket-chip .fa,
.ai-chat-suggestions .ai-chat-ticket-chip .fa {
    color: var(--ai-green-dark);
}
body.dark-mode .ai-chat-suggest-chip.ai-chat-ticket-chip,
body.dark-mode .ai-chat-suggestions .ai-chat-ticket-chip {
    color: var(--ai-green);
}
body.dark-mode .ai-chat-suggest-chip.ai-chat-ticket-chip .fa,
body.dark-mode .ai-chat-suggestions .ai-chat-ticket-chip .fa {
    color: var(--ai-green);
}

/* While the ticket wizard is open on the welcome screen, drop the
   fullscreen vertical centering: a center-justified flex column spills
   overflow BOTH ways and the card's bottom becomes unreachable by
   scrolling. Top-aligned = normal scrollable timeline, card fully
   reachable. (Same :has(#id) specificity + later in file → wins.) */
@media (min-width: 621px) {
    .ai-chat-fullscreen .ai-chat-messages:has(> #aiChatWelcome:not(.hidden)):has(> .ai-ticket-wizard) {
        justify-content: flex-start;
    }
}

/* ── Settings preview card (docs/ai-v2/PREVIEW_CARD_UI.md) ──────────────────────
   A settings write is confirmed in two steps, and until now the user read the
   MODEL'S prose about the preview — so the counted headcount, the scope and the
   "their previous values cannot be restored" sentence reached the screen only if
   the model chose to retype them. This renders the structured payload instead.

   Deliberately built from the same tokens and the same primitives as the task and
   form cards (.ai-tc-head, .ai-tc-rows, .ai-tc-row, .ai-tc-actions, .ai-tc-create,
   .ai-tc-defaults, .ai-tc-status, .ai-form-input, .ai-task-error): one card idiom
   in this panel, not a second design system for one payload. Only what is genuinely
   new to this card is declared here. */
.ai-preview-card {
    margin: 10px 0 2px;
    padding: 14px 16px 16px;
    /* An even border on all four sides. The green rail this card used to carry down
       its left edge is gone: the travelling beam is the only green on the frame now,
       and a static rail beside it read as a second, competing signal. */
    border: 1px solid var(--ai-border);
    border-radius: 14px;
    background: var(--ai-card);
    box-shadow: var(--ai-shadow-sm);
    color-scheme: light;
}
body.dark-mode .ai-preview-card { color-scheme: dark; border-color: var(--ai-border-strong); }

/* The from → to rows. .ai-tc-row already lays out label/value; these are the two
   halves of that row. */
/* The row wraps before either half is squeezed: on a narrow panel the value
   drops to its own line rather than the label being crushed. */
.ai-preview-card .ai-tc-row { flex-wrap: wrap; row-gap: 4px; }
/* `word-break: break-word` is read as `overflow-wrap: anywhere`, which lets the
   label shrink to ONE CHARACTER and split a setting name mid-word ("timezon" /
   "e"). `overflow-wrap: break-word` leaves the longest word as the minimum, and
   dropping `min-width: 0` keeps flexbox from shrinking past it. */
.ai-preview-card .ai-pv-k {
    font-size: 13px; font-weight: 600; color: var(--ai-text-body);
    flex: 0 1 auto; word-break: normal; overflow-wrap: break-word;
}
/* ── THE PROFILE EDITOR (desklog:profile-form) ──────────────────────────────
   Same shell as the create forms — .ai-tc-head / .ai-tc-field / .ai-tc-actions
   already carry the card, the labels and the buttons — so only what is genuinely
   new is declared here. */
.ai-profile-form {
    margin: 10px 0; padding: 14px;
    border: 1px solid var(--ai-border); border-radius: 12px;
    background: var(--ai-surface, transparent);
}
.ai-profile-form .ai-tc-head { margin-bottom: 12px; }
.ai-pf-field { margin-bottom: 12px; }
/* A field the page itself does not let you edit. Shown, never hidden: a form that
   omits Status or a team lead's Team reads as "these do not exist", and the reason
   sits under it in .ai-tc-fhint. */
.ai-pf-locked {
    opacity: 0.65; cursor: not-allowed;
    background: var(--ai-surface-muted, transparent);
}
.ai-tc-fhint {
    margin: 4px 0 0 2px; font-size: 11.5px; line-height: 1.35;
    color: var(--ai-text-faint);
}
.ai-pf-preview:empty { display: none; }
.ai-pf-preview { margin-top: 10px; }
/* EVERY ROW STACKS, OR NONE DOES.
   The settings card lays a row out as "name ............ value", and wraps the
   value onto its own line only when it is too wide to fit. On a profile card that
   happens to exactly one row in four — two email addresses and an arrow are far
   longer than "not set -> India" — so a single row appeared stacked while its
   neighbours stayed inline, which reads as a broken row rather than a long one
   (reported 2026-08-31 with the Email row circled).
   Profile values are long by nature — addresses, designations, country names — so
   this card stacks EVERY row instead of guessing which will fit. It also matches
   the form directly above it, where each label already sits over its control.
   Scoped to .ai-pf-preview: the settings cards are unchanged. */
.ai-pf-preview .ai-tc-row {
    flex-direction: column; align-items: flex-start;
    row-gap: 2px; padding: 10px 14px;
}
/* Three classes deep on purpose: `.ai-preview-card .ai-pv-v` sets text-align
   right and is declared LATER in this file, so an equally specific rule here
   would lose to it. A stacked value aligned right is the odd look this block
   exists to remove. */
.ai-pf-preview .ai-preview-card .ai-pv-k { font-size: 12px; color: var(--ai-text-muted); }
.ai-pf-preview .ai-preview-card .ai-pv-v { text-align: left; font-size: 13px; }

/* THE PLAIN-ENGLISH LINE UNDER A SETTING'S NAME.
   Two accurate names off one word ("website address tracking" / "application
   usage tracking") tell apart only for a reader who already knows both; the
   server's `plain_note` says what each one DOES. Quieter and lighter than the
   name so the row still scans as one line of names — see plain_note in
   settings_capability_registry.php. */
.ai-preview-card .ai-pv-k-note {
    display: block; margin-top: 2px;
    font-size: 11.5px; font-weight: 400; line-height: 1.35;
    color: var(--ai-text-muted);
}
/* The key half is now two lines tall, and the row centres its children. Without
   this the value floats between the name and its note instead of sitting beside
   the name. Only rows that HAVE a note carry the class. */
.ai-preview-card .ai-tc-row-noted { align-items: flex-start; }
.ai-preview-card .ai-tc-flabel .ai-pv-k-note { color: var(--ai-text-faint); }
.ai-preview-card .ai-pv-v {
    font-size: 13px; color: var(--ai-text-muted);
    text-align: right; flex: 1 1 auto; min-width: 0;
    word-break: normal; overflow-wrap: break-word;
}
.ai-preview-card .ai-pv-v strong { color: var(--ai-text); font-weight: 700; }
.ai-pv-arrow { color: var(--ai-green-dark); font-weight: 700; padding: 0 2px; }

/* Who / how wide / when it lands. One line each, every one of them straight
   from the payload. */
.ai-pv-meta { margin: 11px 2px 0; display: flex; flex-direction: column; gap: 6px; }
.ai-pv-line {
    display: flex; align-items: flex-start; gap: 8px;
    font-size: 12.5px; line-height: 1.45; color: var(--ai-text-body);
}
.ai-pv-line .fa { width: 13px; margin-top: 2px; flex: 0 0 auto; color: var(--ai-text-faint); }
.ai-pv-line-strong { font-weight: 700; color: var(--ai-text); }
.ai-pv-line-strong .fa { color: var(--ai-green-dark); }
.ai-pv-dim { color: var(--ai-text-faint); font-weight: 500; }
.ai-pv-already { margin: 9px 2px 0; }

/* Said only when a re-previewed card could not be reconciled with the sentence
   above it — the model paraphrased the value, or what moved was who the change
   covers rather than what it is set to. Sits between the two so it reads as the
   bridge it is, and is removed again the moment a later change syncs cleanly. */
/* "Currently: On", above a settings picker's options — read before the click, the
   way the settings page puts the value in the control itself. */
.ai-sp-current-note { margin: 0 0 6px; font-size: 12px; opacity: 0.9; }
.ai-sp-current-note strong { font-weight: 700; }
/* The same fact on the row itself. .ai-choice-chip sets its background and colour
   !important, so the marker is a TAG rather than a colour that would be dropped. */
.ai-sp-now {
    display: inline-block; margin-left: 7px; padding: 1px 6px;
    border-radius: 9px; font-size: 10px; font-weight: 700;
    letter-spacing: 0.03em; text-transform: uppercase;
    background: rgba(0, 0, 0, 0.14);
}
.ai-choice-chip.ai-sp-chip-current { box-shadow: inset 0 0 0 2px currentColor; }

.ai-pv-stale { margin: 10px 2px 2px; font-style: italic; }
.ai-pv-stale .fa { margin-top: 3px; }

.ai-pv-fields { margin: 13px 0 0; }
.ai-pv-fields .ai-pv-field:last-child { margin-bottom: 0; }
.ai-preview-card select.ai-pv-select:disabled {
    background: var(--ai-card-alt); color: var(--ai-text-muted); cursor: default;
}

/* The consequences and the irreversibility wording, verbatim from the payload.
   Amber has no token in this file — the task-card error banner hard-codes it the
   same way, and this reuses that banner rather than restating the colour. */
.ai-pv-notices { margin: 13px 0 0; display: flex; flex-direction: column; gap: 8px; }
.ai-pv-notice { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ai-text-body); }

/* A retired card. It KEEPS showing what was proposed — it is the record of what
   the user was offered — and says why it can no longer be used. */
.ai-preview-card-locked { opacity: 0.85; }
.ai-preview-card-locked .ai-tc-rows { opacity: 0.8; }
.ai-preview-card-locked .ai-pv-notice { opacity: 0.85; }
.ai-preview-card .ai-pv-status { margin-top: 11px; font-weight: 600; color: var(--ai-text-muted); }
.ai-preview-card .ai-pv-status.ai-tc-status-ok { color: var(--ai-green-dark); }

/* Narrow panel: the two buttons stack rather than squeezing the labels. */
@media (max-width: 620px) {
    .ai-preview-card .ai-tc-actions { flex-wrap: wrap; }
    .ai-preview-card .ai-tc-defaults { flex: 1 1 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   "WAITING ON YOU" BEAM — settings preview / task / form cards
   ═══════════════════════════════════════════════════════════════════════════════
   A card that has asked a question the chat cannot move past — a settings preview
   waiting on Confirm, a task or form card waiting on its submit button — carries a
   green light that travels once around its border every --ai-beam-lap. It is the
   only thing that moves in the panel while nothing is loading, so a card the user
   has scrolled past, or come back to, still reads as "this one is waiting on you".

   STATE-DRIVEN, NO JAVASCRIPT. The states ai_chat.js already writes are the whole
   switch, so not a line of it changed to carry this and no flow moved:
     data-live="1"            a preview still holding a live confirmation token
     .ai-task-card-done       a task / form card that has been submitted
     button:disabled          a submit that is in flight (or a card frozen otherwise)
     data-stream-pending="1"  a block inside a reply that is still streaming
     data-repreviewing="1"    a preview re-resolving itself after a dropdown change

   IT GOES OUT ON THE CLICK, NOT ON THE RESPONSE. Confirm calls aiPreviewLock()
   before its request leaves and the submit buttons disable themselves the same way,
   so the travel stops the instant the user acts; aiBeamConfirm then flares once over
   the card that was acted on and fades, which is the acknowledgement.

   ONLY THE NEWEST CARD BEAMS. A reloaded conversation re-renders every past task and
   form card as a live one, and a wall of pulsing borders says nothing at all — so a
   card in a message that has a message after it is quiet, whatever its state. */

/* Smooth interpolation for the sweep. Without the registration the angle is an
   unregistered custom property, which animates in discrete steps rather than
   turning; every browser this panel supports registers it. */
@property --ai-beam-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}

@keyframes aiBeamTravel { to { --ai-beam-angle: 360deg; } }

/* The acknowledgement: one flare, then nothing. --ai-shadow-sm is carried through
   every stop so the card's own resting shadow never blinks off underneath it. */
@keyframes aiBeamConfirm {
    0%   { box-shadow: var(--ai-shadow-sm), 0 0 0 1px var(--ai-beam-core), 0 0 24px 2px var(--ai-green-glow); }
    35%  { box-shadow: var(--ai-shadow-sm), 0 0 0 2px var(--ai-beam-tail), 0 0 34px 7px var(--ai-green-glow); }
    100% { box-shadow: var(--ai-shadow-sm), 0 0 0 6px var(--ai-beam-void), 0 0 0 0 var(--ai-beam-void); }
}

/* Positioned in every state, not only while beaming, so a card cannot shift when
   the light goes out. */
.ai-preview-card,
.ai-task-card,
.ai-form-card { position: relative; }

/* The two rings. ::before is the light, ::after is its bloom; both are ring-only
   (the mask punches the middle out) and neither takes a pointer event, so the card
   underneath behaves exactly as it did. */
:is(.ai-preview-card[data-live="1"],
    .ai-task-card:not(.ai-task-card-done),
    .ai-form-card:not(.ai-task-card-done)):not([data-stream-pending="1"]):not(:has(.ai-tc-actions button:disabled))::before,
:is(.ai-preview-card[data-live="1"],
    .ai-task-card:not(.ai-task-card-done),
    .ai-form-card:not(.ai-task-card-done)):not([data-stream-pending="1"]):not(:has(.ai-tc-actions button:disabled))::after {
    content: '';
    position: absolute;
    pointer-events: none;
    background: conic-gradient(from var(--ai-beam-angle),
        var(--ai-beam-void) 0deg 200deg,
        var(--ai-beam-tail) 312deg,
        var(--ai-beam-core) 353deg,
        var(--ai-beam-void) 360deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    animation: aiBeamTravel var(--ai-beam-lap) linear infinite;
}

/* The light: a hairline sitting on the card's own 1px border. */
:is(.ai-preview-card[data-live="1"],
    .ai-task-card:not(.ai-task-card-done),
    .ai-form-card:not(.ai-task-card-done)):not([data-stream-pending="1"]):not(:has(.ai-tc-actions button:disabled))::before {
    inset: -1px;
    padding: 1.5px;
    border-radius: 15px;
    z-index: 2;
}

/* The bloom: the same ring, wider and blurred. This is what makes it read as neon
   rather than as a coloured border. */
:is(.ai-preview-card[data-live="1"],
    .ai-task-card:not(.ai-task-card-done),
    .ai-form-card:not(.ai-task-card-done)):not([data-stream-pending="1"]):not(:has(.ai-tc-actions button:disabled))::after {
    inset: -4px;
    padding: 3px;
    border-radius: 18px;
    filter: blur(6px);
    opacity: var(--ai-beam-halo);
    z-index: 1;
}

/* A preview re-resolving itself after a dropdown change is working, not waiting —
   the light holds still until the new preview is on screen. */
.ai-preview-card[data-repreviewing="1"]::before,
.ai-preview-card[data-repreviewing="1"]::after { animation-play-state: paused; }

/* Answered. One flare over the card that was acted on: Confirm on a preview, a
   created task, a submitted form. Cancelled and lapsed cards get nothing — they
   were not acted on. */
.ai-preview-card[data-locked-for="confirmed"],
.ai-task-card.ai-task-card-done,
.ai-form-card.ai-task-card-done {
    animation: aiBeamConfirm 900ms cubic-bezier(0.2, 0.8, 0.2, 1) 1;
}

/* Older turns stay quiet — see ONLY THE NEWEST CARD BEAMS above. */
#aiChatMessages > .ai-chat-msg:has(~ .ai-chat-msg) :is(.ai-preview-card, .ai-task-card, .ai-form-card)::before,
#aiChatMessages > .ai-chat-msg:has(~ .ai-chat-msg) :is(.ai-preview-card, .ai-task-card, .ai-form-card)::after {
    content: none;
}

/* Reduced motion: the card still says it is waiting, it just says it without
   moving — a steady ring instead of a travelling one, and no flare on the answer. */
@media (prefers-reduced-motion: reduce) {
    :is(.ai-preview-card[data-live="1"],
        .ai-task-card:not(.ai-task-card-done),
        .ai-form-card:not(.ai-task-card-done)):not([data-stream-pending="1"]):not(:has(.ai-tc-actions button:disabled))::before,
    :is(.ai-preview-card[data-live="1"],
        .ai-task-card:not(.ai-task-card-done),
        .ai-form-card:not(.ai-task-card-done)):not([data-stream-pending="1"]):not(:has(.ai-tc-actions button:disabled))::after {
        background: var(--ai-beam-tail);
        animation: none;
    }
    .ai-preview-card[data-locked-for="confirmed"],
    .ai-task-card.ai-task-card-done,
    .ai-form-card.ai-task-card-done { animation: none; }
}
