/* Univers Next — UT house-style font, self-hosted (font-src 'self'; no external CDN call).
   Four real weight cuts (Light 300 / Regular 400 / Medium 500 / Bold 700), converted to
   woff2 from the licensed Linotype Univers Standard TTFs (Univers Next is the same family).
   Declaring true cuts means the browser renders each weight from its own outlines instead
   of synthesising faux-bold from a single thin Light file, so body, headings and labels
   all read crisply. font-display: swap avoids invisible text on first paint. */
@font-face {
    font-family: 'Univers Next W02';
    src: url('/static/fonts/univers-next-light.woff2') format('woff2');
    font-weight: 300;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Univers Next W02';
    src: url('/static/fonts/univers-next-regular.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Univers Next W02';
    src: url('/static/fonts/univers-next-medium.woff2') format('woff2');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Univers Next W02';
    src: url('/static/fonts/univers-next-bold.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

:root {
    --primary-bg: #090b10;
    --sidebar-sec-bg: #11141b;
    --sidebar-prim-bg: #050608;
    --text-main: #e2e8f0;
    --text-muted: #94a3b8;
    --border-color: #1e293b;
    --ut-accent: #10b981;
    /* accent at low opacity for tints/borders — recomputed per accent in theming.js applyAccent() */
    --ut-accent-05: rgba(16,185,129,0.05);
    --ut-accent-10: rgba(16,185,129,0.1);
    --ut-accent-20: rgba(16,185,129,0.2);
    --ut-red: #ff0055;
    --ut-purple: #bc13fe;
    --surface-inset: rgba(255,255,255,0.05);   /* subtle inset boxes (code lists, checklist, device rows) */
    --gradient-2: linear-gradient(135deg, var(--ut-accent), #0062ff);
    --chat-font-size: 1.1rem;
    --main-font: 'Univers Next W02', 'Aptos', 'Segoe UI', sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; font-family: var(--main-font, 'Univers Next W02', 'Aptos', 'Segoe UI', sans-serif),serif; }
/* Global type scale: drops the rem base below the browser default (16px) so all rem-based text shrinks uniformly.
   Bumped to 93.75% (15px) — the thin Univers Next Light cut needs the extra size to stay legible on the dark theme. */
html { font-size: 93.75%; }
body { display: flex; height: 100vh; background-color: var(--primary-bg); color: var(--text-main); overflow: hidden; transition: direction 0.3s ease; font-weight: 400; }

/* Boot splash (#bootSplash, index.html). Covers the gap between first paint and
   restoreSession choosing a branch, which is otherwise an empty page.
   z-index sits above .login-container (1000) so it stays on top of whichever screen is
   revealed underneath it, and is removed rather than uncovered — _hideBootSplash().
   It takes --primary-bg from :root, which theming.js sets on documentElement, so it is
   already the right ground for the active theme on the first frame. */
.boot-splash { position: fixed; inset: 0; z-index: 2000; display: flex; flex-direction: column; gap: 18px; align-items: center; justify-content: center; background-color: var(--primary-bg); color: var(--text-muted); font-size: 0.95rem; letter-spacing: 0.02em; }
/* The logo breathes rather than spinning: a spinner says "busy", and this gap is
   usually a few hundred milliseconds in which nothing is wrong. Same invert/blend
   trick as .login-logo, because the asset is a JPG with a white ground. The text
   below it stays: it paints with no network at all, so a slow image cannot put the
   empty interval back. */
.boot-splash-logo { height: 96px; max-width: 70vw; object-fit: contain; filter: invert(1) hue-rotate(180deg); mix-blend-mode: screen; animation: boot-pulse 1.6s ease-in-out infinite; }
@keyframes boot-pulse { 0%, 100% { opacity: 0.45; transform: scale(0.97); } 50% { opacity: 1; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .boot-splash-logo { animation: none; opacity: 1; } }

/* --- MARKDOWN TABLES --- */
.message-text table { width: 100%; border-collapse: collapse; margin: 15px 0; background: rgba(0,0,0,0.2); font-size: 0.95rem; }
.message-text th, .message-text td { border: 1px solid var(--border-color); padding: 12px; text-align: left; }
.message-text th { background: rgba(255,255,255,0.05); color: var(--ut-accent); font-weight: 700; }
.message-text tr:nth-child(even) { background: rgba(255,255,255,0.02); }

/* --- RTL (Right-to-Left) SUPPORT FOR ARABIC --- */
body[dir="rtl"] { direction: rtl; }
body[dir="rtl"] .sidebar-primary { border-right: none; border-left: 1px solid var(--border-color); }
body[dir="rtl"] .sidebar-secondary { border-right: none; border-left: 1px solid var(--border-color); }
body[dir="rtl"] .sidebar-secondary.collapsed { border-left: none; }
body[dir="rtl"] .history-item.active { border-left: none; border-right: 3px solid var(--ut-accent); }
body[dir="rtl"] .btn-action { display: flex; align-items: center; justify-content: center; }
body[dir="rtl"] .rtl-flip { transform: scaleX(-1); }

/* --- SIDEBARS --- */
.sidebar-primary { width: 85px; background-color: var(--sidebar-prim-bg); border-right: 1px solid var(--border-color); display: flex; flex-direction: column; align-items: center; padding: 20px 0; flex-shrink: 0; justify-content: space-between; z-index: 100; }
.nav-item { display: flex; flex-direction: column; align-items: center; gap: 6px; margin-bottom: 18px; cursor: pointer; color: var(--text-muted); transition: 0.3s; width: 100%; text-decoration: none; text-align: center; }
/* title-case labels to match the mockup (was 0.6rem uppercase, letter-spacing 1px).
   Medium (500) real cut + a touch more tracking reads clearly at this small size without
   the heaviness of the Bold face (a requested 600 would round up to the 700 cut). */
.nav-item span { font-size: 0.7rem; font-weight: 500; letter-spacing: 0.4px; line-height: 1.2; padding: 0 4px; }
.nav-icon { width: 24px; height: 24px; stroke: currentColor; stroke-width: 2; fill: none; }
.nav-item:hover, .nav-item.active, .nav-item[aria-expanded="true"] { color: var(--ut-accent); }
/* de-glowed + mockup active state: a flat accent pill behind the icon (was drop-shadow(0 0 8px accent)) */
.nav-item .nav-icon { padding: 6px 14px; border-radius: 11px; box-sizing: content-box; transition: background 0.2s; }
.nav-item.active .nav-icon { background: var(--ut-accent-10); }

/* Container that handles the actual scrolling */
.nav-scroll-container {
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    flex-grow: 1;

    /* Hide scrollbar for IE, Edge and Firefox */
    -ms-overflow-style: none;
    scrollbar-width: none;
}

/* Hide scrollbar for Chrome, Safari and Opera */
.nav-scroll-container::-webkit-scrollbar {
    display: none;
}

/* Style the arrow buttons */
.nav-scroll-btn {
    background: transparent;
    color: var(--text-muted);
    border: none;
    padding: 10px 0;
    cursor: pointer;
    font-size: 1rem;
    text-align: center;
    transition: color 0.2s;
    width: 100%;
}

.nav-scroll-btn:hover {
    color: var(--ut-accent);
}

/* nav theme quick-toggle (sun/moon) + Dark/Light/High Contrast popup — mirrors the mockup */
.account-wrap { position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; }
.account-menu { position: absolute; left: 64px; bottom: 0; min-width: 188px; background: var(--sidebar-sec-bg); border: 1px solid var(--border-color); border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.4); padding: 6px; display: flex; flex-direction: column; gap: 2px; z-index: 200; }
.account-menu[hidden] { display: none; }
.account-menu button { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; background: transparent; border: none; cursor: pointer; color: var(--text-main); font-family: inherit; font-size: 0.85rem; padding: 9px 11px; border-radius: 8px; transition: background 0.15s; }
.account-menu button:hover { background: var(--ut-accent-10); }
.account-menu button.active { color: var(--ut-accent); font-weight: 700; }
.account-menu .tq-ic, .lang-switcher-menu .tq-ic { width: 18px; flex-shrink: 0; text-align: center; }
.account-menu .tq-ic svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vertical-align: middle; }
.account-menu .tq-divider { height: 1px; margin: 4px 6px; background: var(--border-color); }

/* Floating language switcher — globe button pinned top-right, glass look, over all content.
   The dropdown mirrors .account-menu for a consistent popup style. */
.lang-switcher { position: fixed; top: 18px; right: 18px; z-index: 10000; }
.lang-switcher-toggle {
    width: 38px; height: 38px; display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--sidebar-sec-bg) 88%, transparent);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    border: 1px solid var(--border-color); border-radius: 10px; cursor: pointer;
    color: var(--text-main); box-shadow: 0 6px 18px rgba(0,0,0,0.28); transition: border-color 0.2s, color 0.2s;
}
.lang-switcher-toggle svg { width: 20px; height: 20px; }
.lang-switcher-toggle:hover,
.lang-switcher-toggle[aria-expanded="true"] { border-color: var(--ut-accent); color: var(--ut-accent); }
.lang-switcher-menu {
    position: absolute; top: 46px; right: 0; min-width: 210px;
    background: var(--sidebar-sec-bg); border: 1px solid var(--border-color); border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0,0,0,0.45); padding: 6px; display: flex; flex-direction: column; gap: 2px;
}
.lang-switcher-menu[hidden] { display: none; }
.lang-switcher-menu button {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    background: transparent; border: none; cursor: pointer; color: var(--text-main);
    font-family: inherit; font-size: 0.85rem; padding: 9px 11px; border-radius: 8px; transition: background 0.15s;
}
.lang-switcher-menu button:hover { background: var(--ut-accent-10); }
.lang-switcher-menu button.active { background: var(--ut-accent-10); color: var(--ut-accent); font-weight: 700; }
.lang-switcher-menu .ls-flag { width: 20px; height: 15px; flex-shrink: 0; object-fit: cover; border-radius: 2px; border: 1px solid rgba(255,255,255,0.12); box-shadow: 0 1px 2px rgba(0,0,0,0.3); }
.lang-switcher-menu .ls-name { flex: 1; }
.lang-switcher-menu .ls-code { color: var(--text-muted); font-size: 0.72rem; }
.lang-switcher-menu button.active .ls-code { color: var(--ut-accent); }
/* RTL (Arabic): body flips to dir=rtl; the whole layout mirrors, so move the globe to the
   top-left (clear of the now-left-aligned menu bar) and open its popup from the left edge. */
[dir="rtl"] .lang-switcher { right: auto; left: 18px; }
[dir="rtl"] .lang-switcher-menu { right: auto; left: 0; text-align: right; }
[dir="rtl"] .lang-switcher-menu button { text-align: right; }
/* Theme switcher: the globe's twin, one button further in (38px button + 8px gap).
   It shares .lang-switcher, so these offsets come after the globe's own. */
.theme-switcher { right: 64px; }
[dir="rtl"] .theme-switcher { right: auto; left: 64px; }

.sidebar-secondary { width: 260px; min-width: 260px; background-color: var(--sidebar-sec-bg); border-right: 1px solid var(--border-color); display: flex; flex-direction: column; transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1), min-width 0.3s cubic-bezier(0.4, 0, 0.2, 1); overflow: hidden; white-space: nowrap; }
.sidebar-secondary.collapsed { width: 0; min-width: 0; border-right: none; }
.sidebar-header { padding: 25px 20px; display: flex; align-items: center; gap: 12px; font-weight: 700; color: white; border-bottom: 1px solid var(--border-color); }
.sidebar-header img { filter: invert(1) hue-rotate(180deg); mix-blend-mode: screen; }

.history-item { display: flex; justify-content: space-between; align-items: center; padding: 12px 15px; font-size: 0.85rem; color: var(--text-muted); cursor: pointer; border-bottom: 1px solid rgba(255,255,255,0.02); transition: 0.2s; }
.history-item:hover { background: rgba(255,255,255,0.05); color: white; }
.history-item.active { color: var(--ut-accent); background: var(--ut-accent-05); border-left: 3px solid var(--ut-accent); }
/* Chat-history header: a labelled section title with the history icon, plus New Chat + collapse controls. */
.history-toolbar { display: flex; align-items: center; justify-content: space-between; padding: 14px 15px 8px; }
.history-toolbar-title { display: flex; align-items: center; gap: 8px; font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); white-space: nowrap; }
.history-toolbar-title svg { color: var(--ut-accent); flex-shrink: 0; }
.history-toolbar-actions { display: flex; align-items: center; gap: 4px; }

/* Panel-toggle icon: the chevron inside the panel only appears on hover. */
.panel-arrow { opacity: 0; transition: opacity 0.18s ease; }
#historyCollapseBtn:hover .panel-arrow,
.history-reopen:hover .panel-arrow { opacity: 1; }

/* Per-item chat-bubble icon, sitting before the title. */
.history-item .history-icon { display: flex; align-items: center; flex-shrink: 0; margin-right: 10px; color: var(--text-muted); opacity: 0.65; transition: 0.2s; }
.history-item:hover .history-icon { opacity: 1; }
.history-item.active .history-icon { color: var(--ut-accent); opacity: 1; }

/* Compact reopen button pinned near the top, shown only while the history is collapsed. */
.history-reopen-rail { display: none; flex-direction: column; gap: 6px; align-self: flex-start; flex-shrink: 0; margin: 14px 6px 0; }
.history-reopen { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; flex-shrink: 0; background: transparent; border: 1px solid var(--border-color); border-radius: 8px; color: var(--text-muted); cursor: pointer; padding: 0; transition: background 0.2s, color 0.2s, border-color 0.2s; }
.history-reopen:hover { color: var(--ut-accent); background: var(--ut-accent-05); border-color: var(--ut-accent); }
.sidebar-wrapper:has(#sidebar-secondary.collapsed) .history-reopen-rail { display: flex; }

.chat-actions { display: flex; align-items: center; gap: 8px; }
.pin-chat { color: #444; cursor: pointer; transition: 0.2s; }
.pin-chat:hover, .pin-chat.is-pinned { color: var(--ut-accent); }
.del-chat { color: #444; font-size: 1.2rem; padding: 0 5px; transition: 0.2s; }
.del-chat:hover { color: var(--ut-red); }

/* --- MAIN CONTENT & VIEWS --- */
/* min-width: 0 lets the main area shrink to the screen; tab bars and tables then scroll inside
   their own box instead of pushing the whole page off a tablet's right edge. */
.main-content { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; position: relative; background: var(--primary-bg); }
.view-container { display: none; flex-grow: 1; overflow-y: auto; width: 100%; }
.view-container.active { display: flex; flex-direction: column; }

/* One themed scrollbar for every scrolling surface: the page views, the chat history
   list and the eval panes. This used to be written out once per surface, so a fourth
   one would have been a fourth copy to keep in sync. Add new surfaces to these
   selector lists instead. Firefox reads the first rule, WebKit the rest. */
.view-container, #chatHistoryList, .eval-scroll { scrollbar-width: thin; scrollbar-color: var(--border-color) transparent; }
.view-container::-webkit-scrollbar, #chatHistoryList::-webkit-scrollbar, .eval-scroll::-webkit-scrollbar { width: 8px; }
.view-container::-webkit-scrollbar-track, #chatHistoryList::-webkit-scrollbar-track, .eval-scroll::-webkit-scrollbar-track { background: transparent; }
.view-container::-webkit-scrollbar-thumb, #chatHistoryList::-webkit-scrollbar-thumb, .eval-scroll::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 10px; transition: background 0.3s; }
.view-container::-webkit-scrollbar-thumb:hover, #chatHistoryList::-webkit-scrollbar-thumb:hover, .eval-scroll::-webkit-scrollbar-thumb:hover { background: var(--ut-accent); }
.welcome-title-img { height: 260px; margin-bottom: -22px; filter: invert(1) hue-rotate(180deg); mix-blend-mode: screen; object-fit: contain; }

.prompt-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; width: 100%; max-width: 850px; margin-top: 30px; }
.prompt-card { background: var(--sidebar-sec-bg); border: 1px solid var(--border-color); border-radius: 15px; padding: 18px; cursor: pointer; transition: 0.3s; text-align: left; }
.prompt-card:hover { border-color: var(--ut-accent); box-shadow: 0 8px 20px rgba(0,0,0,0.22); }
.prompt-card strong { color: var(--ut-accent); font-size: 0.95rem; }
.prompt-card:focus-visible, .history-item [role="button"]:focus-visible { outline: 2px solid var(--ut-accent); outline-offset: 2px; }
/* A dialog box takes focus itself (tabindex="-1") only when it holds no control yet; no ring. */
[role="dialog"]:focus { outline: none; }

/* --- CHAT INTERFACE --- */
#view-chat { padding-bottom: 200px; }
.message-row { width: 100%; padding: 40px 0; border-bottom: 1px solid rgba(255,255,255,0.03); }
.message-row.user { background: rgba(255, 255, 255, 0.02); }
.message-content { max-width: 850px; margin: 0 auto; padding: 0 40px; display: flex; flex-direction: column; gap: 12px; }
.user-tag, .ai-tag { font-weight: 800; font-size: 0.8rem; letter-spacing: 2px; text-transform: uppercase; }
.user-tag { color: var(--ut-accent); }
.ai-tag { color: var(--ut-purple); }

/* Rendered markdown outside the chat stream (e.g. the evaluations detail modal). */
.md-rendered > *:first-child { margin-top: 0; }
.md-rendered > *:last-child { margin-bottom: 0; }
.md-rendered p { margin: 0 0 0.75em; }
.md-rendered ul, .md-rendered ol { margin: 0 0 0.75em; padding-left: 1.5em; }
.md-rendered li { margin: 0.2em 0; }
.md-rendered code { background: rgba(127,127,127,0.18); padding: 0.1em 0.35em; border-radius: 4px; font-size: 0.9em; }
.md-rendered pre { background: rgba(127,127,127,0.18); padding: 12px; border-radius: 6px; overflow-x: auto; }
.md-rendered pre code { background: none; padding: 0; }
.md-rendered table { border-collapse: collapse; width: 100%; margin: 0 0 0.75em; }
.md-rendered th, .md-rendered td { border: 1px solid var(--border-color); padding: 6px 10px; text-align: left; }
.md-rendered a { color: var(--ut-accent); }
/* Citation superscripts built by cleanAIResponse (static/js/utils.js). Styled here
   rather than inline because the sanitiser strips `style` and `class` from rendered
   markdown (SEC L-05) — the markup is composed before sanitising. */
.md-rendered sup a, .message-text sup a { color: var(--ut-accent); text-decoration: none; cursor: pointer; }

#sendMessageBtn {
    width: 40px;
    height: 40px;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--ut-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease-in-out;
    margin-left: 5px;
    border-radius: 8px;
}
#sendMessageBtn:hover {
    background: var(--ut-accent-10);
}
/* Transforms only where hover is real: on touch the :hover state sticks after a tap. */
@media (hover: hover) {
    #sendMessageBtn:hover { transform: scale(1.1) rotate(5deg); }
    .color-swatch:hover { transform: scale(1.15); }
}
#sendMessageBtn svg {
    width: 24px;
    height: 24px;
    fill: currentColor;
    margin-left: 2px;
}

.message-text { line-height: 1.8; color: #d1d5db; transition: font-size 0.2s ease; font-size: var(--chat-font-size, 1.1rem); overflow-wrap: break-word; word-break: break-word; min-width: 0; max-width: 100%; }
.message-text h3 { color: var(--ut-accent); margin: 25px 0 10px 0; font-size: 1.4rem; font-weight: 700; border-bottom: 1px solid var(--ut-accent-20); padding-bottom: 5px; }
.message-text p { margin-bottom: 15px; }
.message-text ul, .message-text ol { margin-left: 25px; margin-bottom: 15px; padding-inline-start: 0; }
.message-text li { margin-bottom: 8px; }
.message-text strong { color: white; font-weight: 700; }
.message-text a { color: var(--ut-accent); text-decoration: underline; }
.message-text img { max-width: 100%; height: auto; }

/* --- SPEECH TO TEXT MIC --- */
#micButton.recording {
    color: var(--ut-red) !important;
    animation: pulse-mic 1.5s infinite;
}

@keyframes pulse-mic {
    0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255, 0, 85, 0.4); }
    70% { transform: scale(1.1); box-shadow: 0 0 0 10px rgba(255, 0, 85, 0); }
    100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255, 0, 85, 0); }
}

/* --- CITATIONS & FEEDBACK --- */

.feedback-bar { display: flex; gap: 10px; margin-top: 15px; padding-top: 10px; border-top: 1px dashed rgba(255,255,255,0.1); }
.btn-feedback { background: transparent; border: 1px solid var(--border-color); color: var(--text-muted); padding: 4px 8px; border-radius: 6px; cursor: pointer; font-size: 0.8rem; display: flex; align-items: center; gap: 5px; transition: 0.2s; }
.btn-feedback:hover:not(:disabled) { border-color: var(--ut-accent); color: var(--ut-accent); }
.btn-feedback.active-up { background: rgba(16, 185, 129, 0.2); border-color: #10b981; color: #10b981; }
.btn-feedback.active-down { background: rgba(239, 68, 68, 0.2); border-color: #ef4444; color: #ef4444; }
.btn-feedback:disabled { opacity: 0.4; cursor: not-allowed; }
.grounding-warning { margin-top: 8px; padding: 6px 10px; border-left: 3px solid #f59e0b; background: rgba(245, 158, 11, 0.08); color: var(--text-muted); font-size: 0.8rem; border-radius: 4px; }
body[dir="rtl"] .grounding-warning { border-left: none; border-right: 3px solid #f59e0b; }
.web-pages-note { margin: 0 0 6px; color: var(--text-muted); font-size: 0.8rem; overflow-wrap: anywhere; }
.azure-status-line { margin: 0 0 6px; padding: 6px 10px; border-left: 3px solid #f59e0b; background: rgba(245, 158, 11, 0.08); color: var(--text-muted); font-size: 0.8rem; border-radius: 4px; }
.azure-status-line a { color: var(--ut-accent); }
body[dir="rtl"] .azure-status-line { border-left: none; border-right: 3px solid #f59e0b; }

/* Info > Status. Each dot's state is also written out, so colour is never the only signal. */
.status-list { list-style: none; margin: 0; padding: 0; }
.status-row { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; border-top: 1px solid var(--border-color); }
.status-row:first-child { border-top: none; }
.status-body { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.status-body ul { margin: 4px 0 0; padding-inline-start: 18px; }
.status-detail, .status-meta, .status-note { color: var(--text-muted); font-size: 0.85rem; }
.status-meta { white-space: nowrap; }
.status-note { margin: 0 0 8px; }
.status-detail a { color: var(--ut-accent); }
.status-dot { flex-shrink: 0; width: 12px; height: 12px; margin-top: 4px; border-radius: 50%; background: var(--text-muted); }
.status-ok { background: #22c55e; }
.status-warn { background: #f59e0b; }
.status-down { background: #ef4444; }
.status-planned { background: transparent; border: 2px solid var(--ut-accent); }
/* A calendar item with a description opens in place. */
.status-item { flex: 1; min-width: 0; }
.status-item > summary { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; list-style: none; }
.status-item > summary::-webkit-details-marker { display: none; }
.status-item > summary:focus-visible { outline: 2px solid var(--ut-accent); outline-offset: 2px; border-radius: 4px; }
.status-chevron { color: var(--text-muted); font-size: 1.2rem; line-height: 1; transition: transform 0.2s; }
.status-item[open] .status-chevron { transform: rotate(90deg); }
body[dir="rtl"] .status-chevron { transform: scaleX(-1); }
body[dir="rtl"] .status-item[open] .status-chevron { transform: rotate(90deg); }
.status-desc { margin: 8px 0 0; padding-inline-start: 24px; overflow-wrap: anywhere; }
.status-desc p { margin: 0 0 6px; }
.status-desc a { color: var(--ut-accent); }
.btn-feedback.active-up:disabled, .btn-feedback.active-down:disabled { opacity: 1; }
.btn-feedback option { background: var(--sidebar-sec-bg); color: var(--text-main); }

/* --- TOAST NOTIFICATION --- */
#toastNotification { position: fixed; bottom: -60px; left: 50%; transform: translateX(-50%); background: var(--sidebar-sec-bg); border: 1px solid var(--ut-accent); color: white; padding: 12px 24px; border-radius: 30px; box-shadow: 0 10px 30px rgba(0,0,0,0.35); font-size: 0.95rem; font-weight: 600; z-index: 9999; transition: bottom 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); display: flex; align-items: center; gap: 10px; }
#toastNotification.show { bottom: 30px; }

/* --- MODAL --- */
.modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 1000; justify-content: center; align-items: center; backdrop-filter: blur(5px); }
.modal-content { background: var(--sidebar-sec-bg); border: 1px solid var(--border-color); border-radius: 15px; width: 80%; max-width: 1200px; height: 85%; display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 10px 40px rgba(0,0,0,0.5); }
.modal-header { padding: 15px 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border-color); background: var(--sidebar-prim-bg); }
.modal-body { flex-grow: 1; width: 100%; background: var(--sidebar-sec-bg); }
.modal-body.doc-viewer-body { background: #fff; }
/* The white default is for PDF/office document viewing in the iframe. When the
   surface is our own themed markdown/text panel — whether just reading a .md item
   or editing one — the body must match it, otherwise the surrounding strip (hint,
   Save/Cancel, Edit button) shows a jarring white bar. */
.modal-body.doc-viewer-body.editing,
.modal-body.doc-viewer-body.text-view { background: var(--sidebar-prim-bg); }
iframe.doc-frame { width: 100%; height: 100%; border: none; }

/* The .sidebar-wrapper sits at z-index 9999, above the z-index:1000 modal overlay,
   so a full-width overlay is painted over on its left edge and appears partly hidden
   behind the chat history. Offset such overlays so they sit *next to* the sidebars
   instead of behind them: 85px primary rail + 260px open history = 345px, narrowing to
   just the 85px rail when the history is collapsed. #dryrunBatchModal centres its
   content, so offsetting the overlay re-centres the report in the space beside the
   history. Desktop only — on mobile the sidebar is an off-canvas overlay and the
   overlays keep the full width. */
@media (min-width: 769px) {
    #docViewerModal, #dryrunBatchModal { left: 345px; width: calc(100% - 345px); }
    body:has(#sidebar-secondary.collapsed) #docViewerModal,
    body:has(#sidebar-secondary.collapsed) #dryrunBatchModal { left: 85px; width: calc(100% - 85px); }
}

/* --- DOCS, NOTES & SETTINGS --- */
.page-content { max-width: 1100px; margin: 0 auto; width: 100%; padding: 60px 40px; }
.card { width: 100%; background: var(--sidebar-sec-bg); border: 1px solid var(--border-color); border-radius: 20px; padding: 30px; margin-bottom: 25px; }
/* Admin > Playground: the card fills the view down to the bottom of the viewport instead
   of a fixed 800px. The view container is already a viewport-high flex column that
   scrolls, so the page content grows to fill it and the playground takes what is left
   under the title and tab bar; the message list scrolls inside the card and the input
   stays at its foot. The min-height keeps a usable card on a short phone screen (the
   page scrolls there instead). The class is set by switchAdminTab, playground tab only. */
#view-admin.playground-active .page-content { flex: 1 0 auto; display: flex; flex-direction: column; padding-bottom: 24px; }
#view-admin.playground-active #admin-playground { flex: 1 1 0; min-height: 420px; display: flex !important; flex-direction: column; }
#view-admin.playground-active .playground-card { flex: 1 1 0; min-height: 0; margin-bottom: 0; }
/* The Internal view's chat card fills the view the same way, always (it has no tabs).
   The 420px floor keeps it usable on a short phone screen, where the page scrolls. */
#view-internal .page-content { flex: 1 0 auto; display: flex; flex-direction: column; padding-bottom: 24px; }
/* Knowledge nests each sub-tab in its own .page-content; the outer one already carries the top
   padding, so a second one put ~85px between the tab row and the first card. Like every other
   page, the sub-tabs carry no title of their own: the tab button names them. */
.mod-tab-content > .page-content { padding-top: 0; }
#view-internal .internal-card { flex: 1 1 0; min-height: 420px; margin-bottom: 0; }
/* Statistics metric-card captions (e.g. "Water used"). Lifted off --text-muted onto
   --text-main and set in the Medium (500) cut so they read clearly; the big accent value
   below keeps the label visually secondary without needing the dimmed colour.
   --text-main is theme-driven (theming.js), so this stays correct on every theme. */
.stat-label { color: var(--text-main); font-weight: 500; font-size: 0.8rem; margin-bottom: 6px; }
/* Sample size next to a KPI figure — present, but never competing with it. */
.kpi-sample { color: var(--text-muted); font-size: 0.75rem; font-weight: 400; margin-left: 6px; }
/* gap -> manual -> approval -> eval run, on the gap row (D1). */
.gap-outcome { margin-top: 10px; padding: 10px; border: 1px solid var(--border-color); border-radius: 6px; font-size: 0.85rem; }
.gap-outcome-runs { margin: 6px 0 0; padding-left: 18px; }
.gap-card.resolved { opacity: 0.85; }

/* Needs attention: one queue over gaps, ratings and eval regressions (C1). */
.wl-row { padding: 12px 0; border-bottom: 1px solid var(--border-color); }
.wl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.wl-title { font-weight: 600; overflow-wrap: anywhere; }
.wl-detail, .wl-reason { font-size: 0.85rem; margin-top: 4px; overflow-wrap: anywhere; }
.wl-actions { margin-top: 10px; display: flex; gap: 8px; flex-wrap: wrap; }

/* A KPI tile you can open: the rows behind the number (B1). */
.kpi-tile { cursor: pointer; }
.kpi-tile:hover { border-color: var(--ut-accent); }
.kpi-tile:focus-visible { outline: 2px solid var(--ut-accent); outline-offset: 2px; }
.kpi-delta { font-size: 0.75rem; font-weight: 400; color: var(--text-muted); margin-top: 4px; }
.kpi-delta.up { color: #10b981; }
.kpi-delta.down { color: #ef4444; }
/* The left padding is the caret's lane. Both the header row and the summary rows carry
   it, which is what keeps the columns lined up with each other. */
.kpi-drill-row { display: grid; grid-template-columns: 110px 130px 1fr 70px 50px; gap: 10px; padding: 8px 0 8px 18px; border-bottom: 1px solid var(--border-color); font-size: 0.85rem; align-items: start; }
.kpi-drill-row.head { color: var(--text-muted); font-weight: 600; }
.kpi-drill-q { overflow-wrap: anywhere; }
/* A drill row opens to show the answer it was counted for. `summary` must carry the
   grid itself: display:grid on it also removes the default marker, so the caret is
   drawn by ::before instead of being lost. */
.kpi-drill-item > summary { position: relative; cursor: pointer; list-style: none; }
.kpi-drill-item > summary::-webkit-details-marker { display: none; }
/* ABSOLUTE, and that is the whole point: the summary is the grid, so a static
   ::before becomes a grid ITEM and takes the first cell. Every value then lands one
   column to the right of its own header, which is exactly how this shipped: the
   Question column showed the agent and Grounding showed the question. */
.kpi-drill-item > summary::before { content: '▸'; position: absolute; left: 4px; top: 8px; color: var(--text-muted); }
.kpi-drill-item[open] > summary::before { content: '▾'; }
.kpi-drill-item > summary:hover { background: var(--ut-accent-05); }
.kpi-drill-item > summary:focus-visible { outline: 2px solid var(--ut-accent); outline-offset: -2px; }
.kpi-drill-detail { padding: 6px 0 14px 18px; border-bottom: 1px solid var(--border-color); font-size: 0.85rem; }
.kpi-drill-detail h4 { margin: 10px 0 4px; font-size: 0.85rem; color: var(--text-muted); }
.kpi-drill-answer { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.kpi-drill-detail .md-rendered { font-size: 0.9rem; line-height: 1.6; max-width: 72ch; overflow-wrap: anywhere; }
@media (max-width: 700px) { .kpi-drill-row { grid-template-columns: 1fr; } }
.notebook-grid { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 20px; height: 60vh; }
.note-tab { padding: 12px; border-radius: 8px; cursor: pointer; margin-bottom: 8px; background: rgba(255,255,255,0.03); border: 1px solid transparent; }
.note-tab.active { border-color: var(--ut-accent); background: var(--ut-accent-10); }

/* Agent Evals panel */
.muted { color: var(--text-muted); }
.eval-badge-ok { background: var(--ut-accent-10); color: var(--ut-accent); border: 1px solid var(--ut-accent); border-radius: 4px; padding: 1px 6px; font-size: 0.75rem; font-weight: 600; }
.eval-badge-bad { background: rgba(239,68,68,0.12); color: var(--ut-red); border: 1px solid var(--ut-red); border-radius: 4px; padding: 1px 6px; font-size: 0.75rem; font-weight: 600; }
/* Runs and cases both grow without bound (the backend returns the latest 50 runs),
   so each list is a fixed-height scroll pane: the page length no longer tracks how
   many times evals have been run. Rows are single-line and separated by a rule
   instead of each being its own bordered card. */
.eval-scroll { max-height: 300px; overflow-y: auto; border: 1px solid var(--border-color); border-radius: 8px; padding: 4px 8px; }
.eval-scroll > p.muted { margin: 10px 4px; }
.eval-help > summary { cursor: pointer; margin-bottom: 10px; font-size: 0.85rem; }

.eval-run-row { display: flex; align-items: center; gap: 12px; padding: 8px 6px; border-bottom: 1px solid var(--border-color); transition: background 0.15s; }
.eval-run-row:last-child { border-bottom: none; }
.eval-run-row:hover { background: var(--ut-accent-05); }
.eval-run-row .eval-run-id { font-weight: 600; min-width: 3.5em; }
.eval-run-row .eval-run-when { color: var(--text-muted); font-size: 0.8rem; white-space: nowrap; }
.eval-run-row .eval-run-trigger { font-size: 0.82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eval-run-row .eval-run-pass { margin-left: auto; font-size: 0.82rem; white-space: nowrap; }
.eval-run-row .eval-run-score { font-weight: 600; min-width: 3em; text-align: right; }

.eval-case-row { display: flex; align-items: center; gap: 12px; padding: 10px 6px; border-bottom: 1px solid var(--border-color); }
.eval-case-row:last-child { border-bottom: none; }
.eval-case-row .eval-case-main { flex: 1; min-width: 0; }
/* One line each, ellipsised — the full text is in the row's title attribute. */
.eval-case-row .eval-case-q,
.eval-case-row .eval-case-crit { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eval-case-row .eval-case-crit { font-size: 0.8rem; }
.eval-case-row .eval-case-actions { display: flex; gap: 6px; flex-shrink: 0; }
.eval-case-row .eval-case-actions .btn-ghost { padding: 4px 10px; font-size: 0.78rem; }
.color-swatch { width: 32px; height: 32px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; transition: 0.2s; }
.color-swatch.active { border-color: white; box-shadow: 0 0 0 2px currentColor; }
.theme-btn { background: rgba(0,0,0,0.3); border: 1px solid var(--border-color); color: var(--text-muted); padding: 8px 16px; border-radius: 8px; cursor: pointer; transition: 0.2s; font-weight: 600; }
.theme-btn:hover { border-color: var(--ut-accent); color: white; }
.theme-btn.active { border-color: var(--ut-accent); background: rgba(255,255,255,0.05); color: white; }

select.lang-select, select.role-select { background: rgba(0,0,0,0.3); border: 1px solid var(--border-color); color: white; padding: 10px; border-radius: 8px; outline: none; cursor: pointer; font-size: 1rem; width: 200px; }
select.lang-select option, select.role-select option { background: var(--sidebar-sec-bg); color: var(--text-main); }

/* Every <select> (incl. inline-styled ones, e.g. User Management) gets a readable,
   theme-aware option list + native popup. Without this, non-.role-select dropdowns
   fell back to unreadable native colours in dark mode. */
select option { background: var(--sidebar-sec-bg); color: var(--text-main); }
select { color-scheme: dark; }

/* --- INPUTS & BUTTONS --- */
.btn-action { background: rgba(148,163,184,0.12); border: 1px solid var(--border-color); color: var(--text-main); padding: 9px 18px; border-radius: 8px; cursor: pointer; font-weight: 600; transition: 0.2s; }
.btn-action:hover { border-color: var(--ut-accent); color: var(--ut-accent); }
.btn-danger { background: transparent; border: 1px solid var(--ut-red); color: var(--ut-red); padding: 8px 16px; border-radius: 8px; cursor: pointer; font-weight: 600; }
.btn-ghost { background: transparent; border: 1px solid var(--border-color); color: var(--text-muted); padding: 8px 16px; border-radius: 8px; cursor: pointer; font-size: 0.75rem; transition: 0.3s; }
.btn-ghost:hover:not(:disabled) { border-color: var(--ut-accent); color: white; }
/* Switched off (Export logs until a search is applied): it must look it, or a click seems to do nothing. */
.btn-ghost:disabled { opacity: 0.45; cursor: not-allowed; }
a.btn-ghost { display: inline-block; text-decoration: none; }
#keepAnalysisBtn:disabled { opacity: 0.5; cursor: not-allowed; }
.analyst-report-tab { min-width: 40px; }
.analyst-report-tab[aria-selected="true"] { border-color: var(--ut-accent); color: var(--ut-accent); }
/* Native file inputs (Docs/Database): style the "Choose File" button like .btn-ghost */
input[type="file"] { color: var(--text-main); font-size: 0.85rem; }
input[type="file"]::file-selector-button { background: transparent; border: 1px solid var(--border-color); color: var(--text-muted); padding: 8px 16px; border-radius: 8px; cursor: pointer; font-size: 0.75rem; font-weight: 600; font-family: inherit; margin-right: 12px; transition: 0.3s; }
input[type="file"]::file-selector-button:hover { border-color: var(--ut-accent); color: var(--ut-accent); }
input[type="file"]::-webkit-file-upload-button { background: transparent; border: 1px solid var(--border-color); color: var(--text-muted); padding: 8px 16px; border-radius: 8px; cursor: pointer; font-size: 0.75rem; font-weight: 600; font-family: inherit; margin-right: 12px; transition: 0.3s; }
input[type="file"]::-webkit-file-upload-button:hover { border-color: var(--ut-accent); color: var(--ut-accent); }

/* App-feedback side tab: pinned to the right edge, vertical text, hidden on mobile */
.app-feedback-tab { position: fixed; right: 0; top: 50%; transform: translateY(-50%); writing-mode: vertical-rl; background: var(--ut-accent); color: #fff; border: none; padding: 16px 8px; border-radius: 10px 0 0 10px; cursor: pointer; font-weight: 700; font-size: 0.8rem; letter-spacing: 1.5px; box-shadow: 0 4px 14px rgba(0,0,0,0.25); z-index: 1500; transition: padding-right 0.2s ease, filter 0.2s ease; }
.app-feedback-tab:hover { padding-right: 12px; filter: brightness(1.08); }
.btn-icon { background: transparent; border: none; color: var(--text-muted); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: 0.2s; }
.btn-icon:hover { color: var(--ut-accent); }
.input-container-wrapper { position: absolute; bottom: 0; width: 100%; padding: 20px 40px 40px; background: linear-gradient(0deg, var(--primary-bg) 80%, transparent); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.input-box { width: 100%; max-width: 850px; background: var(--sidebar-sec-bg); border: 1px solid var(--border-color); border-radius: 20px; padding: 10px 25px; display: flex; align-items: center; box-shadow: 0 1px 2px rgba(0,0,0,0.25); }
.input-box input[type="text"] { background: transparent; border: none; color: white; flex: 1 1 auto; min-width: 0; width: 100%; outline: none; font-size: 1.1rem; padding: 10px; }
.input-box { transition: border-color 0.3s ease, box-shadow 0.3s ease !important; }
/* de-glowed: keep the crisp accent border on the input, drop the 0 0 15px halo */
.input-box { border-color: var(--ut-accent) !important; transition: border-color 0.3s ease, box-shadow 0.3s ease !important; }

/* --- THEME-AWARE INPUTS & EDITORS --- */
textarea.input-box,
input.input-box,
textarea,
input[type="text"],
input[type="password"] {
    background-color: rgba(0, 0, 0, 0.2);
    color: var(--text-main);
    border: 1px solid var(--border-color);
    padding: 12px;
    border-radius: 8px;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

textarea.input-box:focus,
input.input-box:focus,
textarea:focus,
input[type="text"]:focus,
input[type="password"]:focus {
    outline: none;
    border-color: var(--ut-accent);
    background-color: rgba(0, 0, 0, 0.4);
}

/* Ensure placeholder text is readable but muted */
::placeholder {
    color: var(--text-muted);
    opacity: 0.7;
}

/* --- LOGIN & ADMIN STYLES --- */
.login-container { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; width: 100%; position: absolute; top: 0; left: 0; background: var(--primary-bg); z-index: 1000; }
.login-box { background: var(--sidebar-sec-bg); border: 1px solid var(--border-color); border-radius: 20px; padding: 40px; width: 100%; max-width: 400px; text-align: center; box-shadow: 0 10px 40px rgba(0,0,0,0.5); }
.login-box h2 { color: var(--text-main); margin-bottom: 20px; }
/* Only the box that carries a subtitle tightens its heading gap; the six MFA/password
   boxes share .login-box and have no subtitle, so they keep the original 20px. */
.login-box h2:has(+ .login-sub) { margin-bottom: 8px; }
.login-sub { color: var(--text-muted); font-size: 0.85rem; line-height: 1.45; margin-bottom: 20px; }
.login-logo { height: 100px; margin-bottom: 20px; filter: invert(1) hue-rotate(180deg); mix-blend-mode: screen; object-fit: contain; }
/* Admin > System Settings > Branding (specs/branding.md). Both brands' logos are dark ink on a
   light or transparent ground, so they take the same invert trick as the sign-in logo. */
.brand-choices { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 15px; }
.brand-choice { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 12px 16px; border: 1px solid var(--border-color); border-radius: 10px; cursor: pointer; min-width: 150px; }
.brand-choice:has(input:checked) { border-color: var(--ut-accent); box-shadow: 0 0 0 1px var(--ut-accent); }
.brand-choice-logo { height: 72px; width: 72px; object-fit: contain; filter: invert(1) hue-rotate(180deg); mix-blend-mode: screen; }
.brand-hint { color: var(--text-muted); font-size: 0.8rem; margin-top: 6px; }
.login-input { width: 100%; background: rgba(0,0,0,0.3); border: 1px solid var(--border-color); color: white; padding: 12px; border-radius: 8px; outline: none; margin-bottom: 15px; font-size: 1rem; }
/* Number-field stepper arrows are browser-drawn native UI; color-scheme makes them
   match the theme (light arrows on the dark fields, dark arrows in light themes). */
input[type="number"] { color-scheme: dark; }
body.light-mode input[type="number"] { color-scheme: light; }
/* Reusable dark-themed date field: color-scheme themes the native calendar/spinner
   so date pickers blend in with the app instead of falling back to the light OS control. */
.date-input { background: rgba(0,0,0,0.3); border: 1px solid var(--border-color); color: white; padding: 8px 12px; border-radius: 8px; outline: none; color-scheme: dark; }
body.light-mode .date-input { color-scheme: light; }
.login-btn { width: 100%; background: var(--gradient-2); border: none; color: white; padding: 12px; border-radius: 8px; cursor: pointer; font-weight: 700; font-size: 1rem; transition: 0.3s; }
.login-error { color: var(--ut-red); font-size: 0.9rem; margin-top: 10px; display: none; }

#nav-admin, #nav-quality { display: none; }

.admin-table { width: 100%; border-collapse: collapse; margin-top: 20px; }
.admin-table th, .admin-table td { padding: 12px; text-align: left; border-bottom: 1px solid var(--border-color); }
.admin-table th { color: var(--text-muted); font-weight: 600; }
.admin-table td { color: white; }
/* A long summary table shows its first 15 rows until "Show all" is pressed. */
.admin-table tbody.rows-collapsed tr:nth-child(n+16) { display: none; }
/* Answer ratings: the pin reads as off until this viewer has pinned the row. */
.eval-pin { padding: 2px 6px; line-height: 1; opacity: 0.35; filter: grayscale(1); }
.eval-pin.pinned { opacity: 1; filter: none; }
.eval-pin:hover { opacity: 0.8; }
.eval-pin.pinned:hover { opacity: 1; }


/* ==========================================
    GLOBAL ANNOUNCEMENT BANNER
   ========================================== */

.announcement-banner {
    background: var(--ut-accent-05);
    border-bottom: 1px solid var(--ut-accent-20);
    backdrop-filter: blur(10px);
    color: var(--text-main);
    text-align: center;
    padding: 10px 20px;
    font-size: 0.9rem;
    font-weight: 600;
    letter-spacing: 1px;
    flex-shrink: 0;
    z-index: 90;
}
.announcement-banner strong { color: var(--ut-accent); }

body.light-mode .announcement-banner {
    background: var(--ut-accent-10);
    color: #242424;
}

/* Card toolbar standard (docs/superpowers/specs/2026-10-05-admin-toolbar-standard-design.md):
   a title row (title left; card actions, exports, then Refresh last on the right), a filter
   row (search takes the free width, Reset last) and a pager above and below every paged list.
   The same control sits in the same place on every moderator/admin list. */
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 15px; }
.card-head > h3 { margin: 0; }
.card-actions { display: flex; align-items: center; justify-content: flex-end; gap: 10px; flex-wrap: wrap; margin-inline-start: auto; }
/* Packed to the end, like the title row and the pager: a row that wraps keeps Filter and Reset
   at the right instead of leaving Reset alone at the start of a line. */
.filter-row { display: flex; align-items: flex-end; justify-content: flex-end; gap: 10px; flex-wrap: wrap; margin-bottom: 15px; }
.filter-row > .filter-search { flex: 1 1 220px; min-width: 0; }
/* One line on a phone too: the buttons keep their size and the label wraps between them. */
.list-pager { display: flex; justify-content: flex-end; align-items: center; gap: 12px; margin: 12px 0; }
.list-pager > .btn-ghost { flex: none; white-space: nowrap; }
.list-pager:empty { display: none; }
#trafficGroupScope:empty { display: none; }
.list-pager-label { color: var(--text-muted); font-size: 0.85rem; min-width: 0; text-align: center; }

/* Page tab bars (Quality / Knowledge / Admin / Info): the segmented look of the
   Admin > Logs sub-tabs (2026-10-08), a size up so a main bar still reads as the level
   above a sub-tab row on the same page. Wraps, so the last tabs (Admin > Logs, Quality >
   Data Analyst) are never off-screen on a tablet or phone. */
.main-tab-row { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px; margin: 10px 0 25px; max-width: 100%; border: 1px solid var(--border-color); border-radius: 10px; }
.admin-tab-btn { background: transparent; border: none; border-radius: 7px; padding: 8px 16px; font: inherit; font-size: 0.95rem; color: var(--text-muted); cursor: pointer; white-space: nowrap; }
.admin-tab-btn:hover { color: var(--text-main); }
.admin-tab-btn.active { background: var(--ut-accent-10); color: var(--ut-accent); }

/* Second-level tabs under an admin tab (Admin > Logs). Smaller and segmented, so they read
   as a level below .admin-tab-btn rather than a second copy of it (specs/navigation.md). */
.sub-tab-row { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px; margin-bottom: 20px; max-width: 100%; overflow-x: auto; border: 1px solid var(--border-color); border-radius: 8px; }
.sub-tab-btn { background: transparent; border: none; border-radius: 6px; padding: 6px 12px; font: inherit; font-size: 0.85rem; color: var(--text-muted); cursor: pointer; white-space: nowrap; }
.sub-tab-btn:hover { color: var(--text-main); }
.sub-tab-btn.active { background: var(--ut-accent-10); color: var(--ut-accent); }

/* The doc-viewer Edit button sits on the white document surface, where a plain
   .btn-ghost (muted grey on faint border) is near-invisible. Accent-tint it so it
   reads as a button; it flips to the dark editor chrome once clicked. */
#docEditBtn { background: var(--ut-accent-10); color: var(--ut-accent); border-color: var(--ut-accent); }

/* ==========================================
   LIGHT MODE OVERRIDES
   ========================================== */
body.light-mode .main-content { background: var(--primary-bg); }
body.light-mode { color: var(--text-main); --surface-inset: rgba(0,0,0,0.04); }
body.light-mode .message-text,
body.light-mode .message-text strong,
body.light-mode h1,
body.light-mode h2,
body.light-mode h3,
body.light-mode td { color: var(--text-main) !important; }

body.light-mode input[type="text"],
body.light-mode input[type="password"],
body.light-mode input[type="search"],
body.light-mode input[type="email"],
body.light-mode input[type="number"],
body.light-mode input[type="date"],
body.light-mode input[type="time"],
body.light-mode textarea,
body.light-mode select { background: #ffffff !important; color: #242424 !important; border: 1px solid var(--border-color) !important; color-scheme: light; }

body.light-mode .card,
body.light-mode .prompt-card { background: #ffffff; border-color: var(--border-color); box-shadow: 0 4px 10px rgba(0,0,0,0.03); }
/* Light theme: card outline uses the user's chosen accent (High Contrast Light keeps its black border) */
html[data-theme="Light"] .card,
html[data-theme="Light"] .prompt-card { border-color: var(--ut-accent); }

body.light-mode .history-item:hover { background: rgba(0,0,0,0.05); color: #000; }
body.light-mode .sidebar-header { color: #242424; }
body.light-mode .sidebar-header img { filter: none; mix-blend-mode: multiply; }
body.light-mode .welcome-title-img,
body.light-mode .boot-splash-logo,
body.light-mode .login-logo,
body.light-mode .brand-choice-logo { filter: none; mix-blend-mode: multiply; }

/* UT Assist: the square logo follows the theme. The logo itself is only the mask; the
   element's background paints it, the accent above the gap between bubble and name (row
   896 of 1500, so 59.7%) and the text colour below it. The image's own pixels are pushed
   out of the box with object-position, which keeps its size and leaves the background.
   Comes after the light-mode block so it also replaces the invert/multiply there. */
html[data-brand="utassist"] .welcome-title-img,
html[data-brand="utassist"] .boot-splash-logo,
html[data-brand="utassist"] .login-logo {
    filter: none; mix-blend-mode: normal;
    object-fit: none; object-position: -10000px 0;
    background: linear-gradient(var(--ut-accent) 59.7%, var(--text-main) 59.7%);
    -webkit-mask: url(/static/brand/utassist/logo-square.png) center / contain no-repeat;
    mask: url(/static/brand/utassist/logo-square.png) center / contain no-repeat;
}

body.light-mode th { background: #f3f2f1; color: #242424; }
body.light-mode .input-box { background: #ffffff; }
body.light-mode .btn-ghost { color: var(--text-main); }
body.light-mode #toastNotification { color: var(--text-main); }
body.light-mode .theme-btn { background: #ffffff; color: var(--text-main); }
body.light-mode .theme-btn:hover, body.light-mode .theme-btn.active { color: var(--ut-accent); background: var(--ut-accent-10); }

/* ==========================================
   ADMIN LIST ROWS
   ========================================== */
.user-list-row { transition: background 0.15s; }
.user-list-row:hover { background: rgba(255,255,255,0.04); }
body.light-mode .user-list-row:hover { background: rgba(0,0,0,0.04); }
/* A peer team manager is shown but not editable, so the row must not answer the hover
   the way a clickable one does — the cursor and the opacity say read-only and a
   highlight would contradict both. */
.user-list-row.readonly:hover, body.light-mode .user-list-row.readonly:hover { background: none; }

/* ==========================================
   MOBILE RESPONSIVENESS & VIEWPORT FIXES
   ========================================== */
.mobile-header { display: none; }
.mobile-toggle-btn { background: none; border: none; color: var(--text-main); font-size: 1.8rem; cursor: pointer; padding: 5px; }

@media (max-width: 768px) {
    /* --- NEW: Dynamic Viewport & Cutoff Fixes --- */
    body, html, #appInterface {
        height: 100dvh !important;
        overflow: hidden;
    }

    .main-content {
        width: 100%;
        margin-left: 0 !important;
        height: 100dvh !important;
        overflow-y: auto;
        overflow-x: hidden;
    }

    .view-container {
        padding-bottom: 90px !important;
    }

    #inputArea {
        padding-bottom: max(15px, env(safe-area-inset-bottom)) !important;
        margin-bottom: 0 !important;
    }
    /* -------------------------------------------- */

    /* --- EXISTING: Mobile UI Logic --- */
    .mobile-header { display: flex; align-items: center; padding: 15px 20px; background: var(--sidebar-sec-bg); border-bottom: 1px solid var(--border-color); }
    .mobile-header .mobile-toggle-btn { margin-right: 15px; display: block; }

    .prompt-grid {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        padding-bottom: 15px;
        -webkit-overflow-scrolling: touch;
        -ms-overflow-style: none;
        scrollbar-width: none;
    }

    .prompt-grid::-webkit-scrollbar {
        display: none;
    }

    .prompt-card {
        flex: 0 0 80%;
        scroll-snap-align: center;
    }

    .sidebar-wrapper {
        position: fixed;
        top: 0;
        left: 0;
        transform: translateX(-100%);
    }

    #view-welcome {
        padding-top: 24px !important;
        padding-bottom: 140px !important;
        padding-left: 16px !important;
        padding-right: 16px !important;
    }
    .welcome-title-img { height: 150px; margin-bottom: -10px; }

    .input-container-wrapper {
        z-index: 100;
        padding: 15px;
        position: fixed;
        bottom: 0;
    }

    .sidebar-wrapper.mobile-open {
        transform: translateX(0);
    }

    .page-content { padding: 15px; }

    .input-box { border-radius: 12px; }
    .btn-action.rtl-flip { width: 100% !important; margin-top: 5px; }

    /* Size to content, capped, and let the body scroll so the header and the
       buttons at the end of the body stay reachable (also with the keyboard open).
       max-height is a % of the overlay, which sits inside the safe-area padding below. */
    .modal-content { width: 95% !important; height: auto !important; max-height: 90%; }
    .modal-body { overflow-y: auto; min-height: 0; }
    /* The document viewer fills its dialog and scrolls internally. */
    #docViewerModal .modal-content { height: 90% !important; }
    .modal-overlay { padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }

    .card { overflow-x: auto; }
    table.admin-table { min-width: 600px; }

    .feedback-bar { flex-wrap: wrap; }
    .message-content { padding: 0 15px; }

    .sidebar-primary {
        overflow-y: auto;
        justify-content: flex-start;
        gap: 20px;
        height: 100%;
        padding-bottom: 30px;
        -ms-overflow-style: none;
        scrollbar-width: none;
    }

    .sidebar-primary::-webkit-scrollbar {
        display: none;
    }

    .sidebar-secondary {
        overflow-y: auto;
        height: 100%;
    }

    /* On mobile the whole rail scrolls (height:100%), so the inner nav container must
       NOT scroll independently — otherwise the pinned theme toggle stays fixed while the
       nav items scroll past it. Let everything flow and scroll together; hide the desktop
       up/down scroll arrows. */
    .nav-scroll-container { overflow-y: visible; flex-grow: 0; }
    .nav-scroll-btn { display: none !important; }
    .account-wrap { margin-top: 8px; }

    /* The rail scrolls (overflow-y:auto), which also clips horizontally and would hide
       the account popup. Pin it to the viewport (fixed escapes the clip) and put it on top. */
    .account-menu { position: fixed; left: 10px; bottom: 88px; z-index: 10000; max-height: calc(100vh - 100px); overflow-y: auto; }

    /* larger tap targets */
    .mobile-toggle-btn { min-width: 44px; min-height: 44px; }
    #sendMessageBtn { width: 44px; height: 44px; }

    /* Keep the globe clear of the mobile header's New Chat button (top-right). */
    .lang-switcher { top: 9px; right: 14px; }
    .theme-switcher { right: 60px; }
    #mobileNewChatBtn { margin-right: 98px !important; }

    /* RTL: the mobile header flex row reverses, so New Chat lands on the left —
       move the globe there too and clear it with a left margin instead. */
    [dir="rtl"] .lang-switcher { right: auto; left: 14px; }
    [dir="rtl"] .theme-switcher { right: auto; left: 60px; }
    [dir="rtl"] #mobileNewChatBtn { margin-right: 15px !important; margin-left: 98px !important; }
}

/* ── Knowledge Gaps: grouped view ─────────────────────────────── */
.gap-group { margin-bottom: 14px; }
.gap-group-head {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 8px 10px; border-radius: 8px; background: var(--ut-accent-05);
  user-select: none;
}
.gap-group-head:hover { background: var(--ut-accent-10); }
.gap-group-count { color: var(--text-muted); font-weight: 400; }
.gap-group.collapsed .gap-group-body { display: none; }

.gap-card { border: 1px solid var(--border-color); border-radius: 8px; margin: 8px 0; overflow: hidden; }
.gap-card.drafted { opacity: 0.75; }
.gap-row {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 10px 12px; user-select: none;
}
.gap-row:hover { background: var(--ut-accent-05); }
.gap-badge { font-size: 0.9rem; }
.gap-label { flex: 1; }
.gap-count { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.gap-rec { font-size: 0.75rem; padding: 1px 8px; border-radius: 10px; white-space: nowrap; }
.gap-rec.safe { background: rgba(16,185,129,0.15); color: #10b981; }
.gap-rec.review { background: rgba(245,158,11,0.15); color: #f59e0b; }
.gap-rec.dismiss { color: var(--text-muted); }
.gap-caret { color: var(--text-muted); }

.gap-detail { display: none; padding: 4px 12px 12px 12px; }
.gap-card.open .gap-detail { display: block; }
.gap-sig { display: flex; gap: 14px; color: var(--text-muted); font-size: 0.85rem; margin-bottom: 6px; }
.gap-samples { margin: 6px 0; padding-left: 18px; }
.gap-samples .lang { color: var(--ut-accent); font-size: 0.75rem; text-transform: uppercase; }
.gap-samples .freq { color: var(--text-muted); font-size: 0.8rem; }
.gap-cov { color: var(--text-muted); font-size: 0.85rem; margin: 6px 0; }
.gap-actions { display: flex; gap: 8px; margin-top: 8px; }

/* ── Traffic Dashboard: grouped-by-IP view (mirrors the Knowledge Gaps look) ── */
.ip-group { border: 1px solid var(--border-color); border-radius: 8px; margin-bottom: 10px; overflow: hidden; }
.ip-group-head {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 10px 12px; background: var(--ut-accent-05); user-select: none;
}
.ip-group-head:hover { background: var(--ut-accent-10); }
.ip-group-caret { color: var(--text-muted); }
.ip-group-ip { color: var(--ut-accent); font-family: monospace; font-weight: bold; }
.ip-group-meta { flex: 1; color: var(--text-muted); font-size: 0.85rem; }
.ip-group-count { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ip-group.collapsed .ip-group-body { display: none; }
/* Country flag before an address (utils.js::ipWithFlag, specs/admin.md). */
.ip-flagged { white-space: nowrap; }
.ip-flag { width: 16px; height: 12px; margin-right: 6px; vertical-align: -1px; border-radius: 2px;
  box-shadow: 0 0 0 1px var(--border-color); }
/* Mail server fields on the Escalation card: label beside field, stacked on a phone. */
.smtp-grid { display: grid; grid-template-columns: max-content minmax(0, 360px); gap: 8px 12px; align-items: center; }
.smtp-grid label { color: var(--text-muted); font-size: 0.78rem; }
.smtp-grid .login-input, .smtp-grid .role-select { width: 100%; margin: 0; }
@media (max-width: 600px) { .smtp-grid { grid-template-columns: 1fr; gap: 4px; } }
/* The "Needs attention" tile: a native <details>, so closed by default and keyboard-ready. */
.attention-tile > summary { list-style: none; font-weight: 600; }
.attention-tile > summary::-webkit-details-marker { display: none; }
.attention-tile > summary::before { content: '▸'; color: var(--text-muted); }
.attention-tile[open] > summary::before { content: '▾'; }
.attention-tile > summary:focus-visible { outline: 2px solid var(--ut-accent); outline-offset: -2px; }
.attention-tile.has-items > summary { color: var(--ut-accent); }
.attention-body { padding: 4px 14px 12px; overflow-x: auto; }
.attention-body .admin-table { margin-top: 8px; font-size: 0.85rem; }
.attention-body .att-sort { font: inherit; font-weight: 600; color: inherit; padding: 0; text-align: left; }
.attention-body td.att-actions { white-space: nowrap; }
.attention-body td.att-samples { max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: monospace; }
.ip-group-body { padding: 4px 0; }
.ip-req {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px; cursor: pointer;
  padding: 8px 14px; font-size: 0.85rem; border-top: 1px solid var(--border-color);
}
.ip-req:hover { background: var(--ut-accent-05); }
.ip-req-time { color: var(--text-muted); white-space: nowrap; }
.ip-req-method { background: rgba(127,127,127,0.15); padding: 2px 6px; border-radius: 4px; font-size: 0.8rem; }
/* min-width makes the row wrap (date below) before the name gets crushed on a phone. */
.ip-req-endpoint { flex: 1; min-width: 12ch; word-break: break-all; }
.ip-req-ua { color: var(--text-muted); white-space: nowrap; max-width: 220px; overflow: hidden; text-overflow: ellipsis; }
/* Scope caption above the list, plus the loading / error / "load more" lines inside
   an expanded group — the rows of one address are fetched on demand. */
.ip-group-note { color: var(--text-muted); font-size: 0.85rem; margin: 0 0 10px 0; padding: 0 2px; }
.ip-group-body .ip-group-note { padding: 10px 14px; margin: 0; }
.ip-group-more { display: block; width: calc(100% - 28px); margin: 8px 14px; font-size: 0.85rem; }
/* Dry-run report: the "why it regressed" block under an agent's summary row.
   Styled here, not inline — sanitizeHtml strips style/class off rendered markdown
   and the CSP forbids inline handlers, so report markup keeps its styling in the
   stylesheet like everything else the app builds. */
.dryrun-why-row td { background: var(--ut-accent-05); padding: 12px 14px; }
.dryrun-why-title { margin: 0 0 8px 0; font-weight: 700; font-size: 0.85rem; }
.dryrun-case {
  border-left: 3px solid var(--ut-red); padding: 6px 0 6px 10px; margin-bottom: 10px;
}
.dryrun-case:last-child { margin-bottom: 0; }
.dryrun-case-q { font-size: 0.9rem; }
.dryrun-case-score { color: var(--text-muted); font-size: 0.8rem; font-variant-numeric: tabular-nums; }
.dryrun-case-note { margin: 6px 0 2px 0; font-size: 0.8rem; color: var(--text-muted); }
.dryrun-unmet { margin: 0; padding-left: 20px; font-size: 0.85rem; }
.dryrun-answer { margin-top: 6px; font-size: 0.85rem; }
.dryrun-answer summary { cursor: pointer; color: var(--text-muted); }
.dryrun-answer pre {
  white-space: pre-wrap; word-break: break-word; margin: 6px 0 0 0; padding: 8px;
  background: rgba(127,127,127,0.12); border-radius: 4px; font-size: 0.8rem;
}
.dryrun-why-btn { font-size: 0.75rem; padding: 0 6px; }

/* Per-language freshness line under the Help Center edit controls. Styled here,
   not inline, so the marks stay legible against every theme's card background. */
.help-translate-status {
    display: block;
    margin-top: 6px;
    font-size: 0.75rem;
    color: var(--text-muted);
    letter-spacing: 0.02em;
}

/* Advisory findings on a staged knowledge-base file (indirect prompt injection). Styled
   as a note rather than an alert: it is a hint for the second reviewer, not a verdict,
   and a red box would train people to dismiss it. */
.scan-findings { border: 1px solid var(--ut-accent); border-radius: 8px; padding: 12px 14px; margin: 0 0 14px; background: var(--ut-accent-05); font-size: 0.85rem; }
.scan-findings p { margin: 4px 0 10px; }
/* Fix the article (specs/kb_checks.md): what prompted the edit, above the editor. */
.doc-edit-context { border: 1px solid var(--ut-accent); border-radius: 8px; padding: 10px 14px; margin: 0 0 10px; background: var(--ut-accent-05); font-size: 0.85rem; max-height: 30vh; overflow-y: auto; }
.doc-edit-context-label { color: var(--text-muted); font-weight: 600; margin-top: 6px; }
.doc-edit-context-text { white-space: pre-wrap; margin: 2px 0 6px; }
.article-pick { display: block; width: 100%; text-align: left; margin: 0 0 8px; }
/* Upload check findings under a file in the review queue. */
.lint-box { font-size: 0.8rem; margin-top: 4px; }
.lint-finding { color: var(--text-main); }
.lint-finding::before { content: "\26A0\FE0E  "; color: var(--ut-red); }
.scan-finding { padding: 6px 0; border-top: 1px solid var(--border-color); }
.scan-finding code { display: block; margin-top: 4px; padding: 6px 8px; background: rgba(0,0,0,0.25); border-radius: 4px; overflow-wrap: anywhere; }

/* Dashboard queue: a handled row keeps its place, struck through, rather than vanishing —
   an item that disappears cannot be un-done by the colleague who disagrees. */
.wl-row.wl-done .wl-title { text-decoration: line-through; }
.wl-row.wl-done { opacity: 0.62; }   /* only visible under "Show done" */

/* The four knowledge-base rankings, stacked and collapsing to one column on a phone. */
/* Knowledge base health: one ranking at a time, and every row the same three columns in
   the same places, so switching list does not move the page under the reader. */
.kb-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 10px; }
.kb-tab { background: transparent; border: 1px solid var(--border-color); color: var(--text-muted);
          padding: 5px 12px; border-radius: 999px; font-size: 0.8rem; cursor: pointer; }
.kb-tab:hover { color: inherit; }
.kb-tab.active { border-color: var(--ut-accent); color: var(--ut-accent); background: var(--ut-accent-10); }
.kb-ranked { margin-top: 4px; }
.kb-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 12px;
          align-items: baseline; padding: 7px 0; border-bottom: 1px solid var(--border-color); }
.kb-row:last-child { border-bottom: 0; }
.kb-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-store { font-size: 0.78rem; color: var(--text-muted); }
.kb-value { font-size: 0.8rem; color: var(--text-muted); font-variant-numeric: tabular-nums;
            min-width: 6.5em; text-align: right; }

/* The tile row spans exactly what the cards below it span. It was an inline four-column
   template carrying three tiles, which left a quarter of the row empty on the right and
   made every card underneath look indented. */
.kpi-tile-row { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr); gap: 15px;
                margin-bottom: 15px; }
/* .card carries its own 25px bottom margin, which inside a grid row lands under every
   tile and put the cards below out of step with the row's own spacing. */
.kpi-tile-row > .card { margin-bottom: 0; }
@media (max-width: 900px) { .kpi-tile-row { grid-template-columns: 1fr; } }

/* One tile, two numbers that answer the same question: did the answer serve the person,
   and was it supported by the knowledge base. Each half keeps its own drill-down. */
.kpi-tile-pair { text-align: left; }
.kpi-components { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; }
.kpi-component { font-size: 0.72rem; color: var(--text-muted); cursor: pointer; }
.kpi-component:hover { color: var(--ut-accent); }
.kpi-component b { color: inherit; font-variant-numeric: tabular-nums; }
.wl-dismiss { margin-left: auto; }

/* A-03. Deliberately not a toast: a lost accounting write is a standing condition, not an
   event, and it has to survive the reload that a toast does not. */
.kpi-accounting-warning { border: 1px solid #ef4444; background: rgba(239,68,68,0.08);
    color: inherit; border-radius: 8px; padding: 12px 14px; margin-bottom: 16px;
    font-size: 0.88rem; }

/* --- PHONES, TABLETS & TOUCH ---
   Everything below is scoped to a small screen, a tablet width or touch input, so the
   desktop layout is untouched. */

/* viewport-fit=cover (index.html) lets the page run under the notch and home indicator.
   The insets are 0 on every screen without them, so this is a no-op on desktop; in
   landscape it keeps the rail clear of the notch. */
body { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }

@media (max-width: 768px) {
    /* Fixed elements ignore the body padding, so they carry the insets themselves. */
    .main-content { padding-top: env(safe-area-inset-top); }
    .sidebar-wrapper { padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom) env(safe-area-inset-left); background: var(--sidebar-prim-bg); }
    .input-container-wrapper {
        padding-left: max(15px, env(safe-area-inset-left));
        padding-right: max(15px, env(safe-area-inset-right));
    }

    .stats-grid { grid-template-columns: 1fr !important; }
    .notebook-grid { grid-template-columns: 1fr; height: auto; }
    .notes-list { max-height: 30vh; overflow-y: auto; }
    #noteBody { min-height: 40vh; }
    /* The user list is a 7-column grid; scroll it sideways rather than squeeze it. */
    #userListBody { overflow-x: auto; }
    #userListBody > div { min-width: 640px; }
}

/* iOS zooms into any focused field under 16px. */
@media (max-width: 768px), (hover: none) and (pointer: coarse) {
    input, textarea, select { font-size: 16px !important; }
}

@media (pointer: coarse) {
    .btn-feedback { min-height: 40px; padding: 6px 12px; }
    #micButton { min-width: 40px; min-height: 40px; margin-right: 4px !important; }
    /* Negative margins grow the hit area into the row's padding without making the row taller. */
    .pin-chat { box-sizing: content-box; padding: 12px; margin: -12px -4px; }
    .del-chat { display: inline-flex; align-items: center; justify-content: center; min-width: 40px; min-height: 40px; margin: -12px 0; }
}

/* Tablets: the desktop layout with narrower history and side padding; wide admin
   tables scroll inside their card instead of running off screen. */
@media (min-width: 769px) and (max-width: 1024px) {
    .sidebar-secondary { width: 220px; min-width: 220px; }
    #docViewerModal, #dryrunBatchModal { left: 305px; width: calc(100% - 305px); }
    /* 64px on top so a right-aligned title-row button clears the theme and language buttons. */
    .page-content { padding: 64px 24px 40px; }
    /* The editor column next to the note list is too narrow beside the chat history. */
    .notebook-grid { grid-template-columns: 1fr; height: auto; }
    .notes-list { max-height: 30vh; overflow-y: auto; }
    .card { overflow-x: auto; }
    table.admin-table { min-width: 600px; }
}
