/*
 * This is free software — do whatever you want with it.
 * Developed by Franck LEFEVRE for K1 (https://k1info.com),
 * aided by his team of kind and fun robots.
 *
 * Please use the enormous power of this software to do good things
 * for things and people, always making sure it harms nothing and no one.
 */

/**
 * Inlux Web — Base layout and structural styles.
 * Color variables are defined in each theme's theme.css.
 *
 * 2026-04-02 — Refactored: extracted color variables to per-theme CSS files.
 *   Layout, spacing, and structural rules remain here.
 */

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

body {
    font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
                 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
    background: var(--bg);
    color: var(--text);
    height: 100vh;
    overflow: hidden;
}

/* --- Screens --- */
.screen { display: flex; flex-direction: column; height: 100vh; position: relative; }
.screen[hidden] { display: none; }

/* --- Login --- */
#login-screen { justify-content: center; align-items: center; }

.login-box {
    background: var(--surface);
    padding: 2rem;
    border-radius: var(--radius);
    width: 340px;
    text-align: center;
}
.login-box .login-logo {
    display: block; margin: 0 auto 1rem; height: 40px; width: auto;
    filter: var(--logo-filter);
}
.login-box h1 { margin-bottom: 0.25rem; color: var(--login-title-color); }
.login-box .subtitle { color: var(--login-subtitle-color); margin-bottom: 1.5rem; font-size: 0.9rem; }
.login-box input {
    display: block; width: 100%; padding: 0.6rem; margin-bottom: 0.75rem;
    border: 1px solid var(--border-color); border-radius: var(--radius);
    background: var(--input-bg); color: var(--text); font-size: 1rem;
}
.login-box button {
    width: 100%; padding: 0.6rem; border: none; border-radius: var(--radius);
    background: var(--accent); color: var(--btn-text); font-size: 1rem; cursor: pointer;
    transition: background 0.2s, opacity 0.2s;
}
.login-box button:hover { opacity: 0.9; }
.error { color: var(--accent); margin-top: 0.5rem; font-size: 0.85rem; }
/* 2026-04-16 — Discrete version footer on the login box (backend + frontend). */
.login-versions {
    margin-top: 1.25rem;
    color: var(--login-subtitle-color);
    font-size: 0.75rem;
    opacity: 0.7;
    letter-spacing: 0.02em;
}
.login-versions-sep { margin: 0 0.4rem; }

/* --- Chat header --- */
header {
    display: flex; align-items: center; gap: 1rem;
    padding: 0.75rem 1rem; background: var(--header-bg);
    border-bottom: 1px solid var(--border-color);
}
header .header-logo { height: 28px; width: auto; filter: var(--logo-filter); }
.header-user { font-size: 0.75rem; color: var(--text-muted); margin-left: 0.4rem; }
header h1 { font-size: 1.1rem; flex: 1; }
header #user-name { color: var(--text-muted); font-size: 0.85rem; }
header button {
    padding: 0.3rem 0.8rem; border: 1px solid var(--border-color); border-radius: var(--radius);
    background: transparent; color: var(--text-muted); cursor: pointer; font-size: 0.8rem;
    transition: background 0.2s, color 0.2s;
}

/* 2026-04-07 — Chat layout: sidebar + main area */
#chat-screen { flex-direction: row; }
#fab-sidebar {
    width: 220px; min-width: 220px; background: var(--surface);
    border-right: 1px solid var(--border-color);
    display: flex; flex-direction: column; overflow: hidden;
    transition: width 0.2s, min-width 0.2s;
}
#fab-sidebar.collapsed { width: 0; min-width: 0; border-right: none; }
#sidebar-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--border-color);
}
#sidebar-header .header-logo { height: 24px; }
.sidebar-toggle-btn {
    background: none; border: none; color: var(--text-muted); cursor: pointer;
    padding: 0.2rem; border-radius: var(--radius);
}
.sidebar-toggle-btn:hover { color: var(--text); }
#fab-list { flex: 1; overflow-y: auto; padding: 0.3rem 0; }
.fab-list-item {
    padding: 0.5rem 0.8rem; cursor: pointer; font-size: 0.88rem;
    border-left: 3px solid transparent; transition: all 0.15s;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fab-list-item:hover { background: var(--bg); }
.fab-list-item.active {
    background: var(--bg); border-left-color: var(--accent); font-weight: 600;
}

#chat-main { flex: 1; display: flex; flex-direction: column; min-width: 0; position: relative; }
#chat-main > header { flex-shrink: 0; }

.current-fab-name { font-weight: 600; font-size: 0.95rem; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Burger menu button */
.burger-btn {
    background: none; border: 1px solid var(--border-color); border-radius: var(--radius);
    color: var(--text-muted); cursor: pointer; padding: 0.3rem 0.5rem;
    transition: background 0.2s;
}
.burger-btn:hover { background: var(--accent); color: var(--btn-text); }

/* Burger dropdown menu */
.burger-menu {
    position: absolute; top: 44px; right: 0.5rem; z-index: 200;
    background: var(--surface); border: 1px solid var(--border-color);
    border-radius: var(--radius); box-shadow: 0 4px 16px rgba(0,0,0,0.3);
    min-width: 200px; padding: 0.3rem 0;
}
.burger-menu[hidden] { display: none; }
.burger-section { padding: 0.4rem 0.8rem; }
.burger-user { font-size: 0.85rem; color: var(--text-muted); }
.burger-divider { height: 1px; background: var(--border-color); margin: 0.2rem 0; }
.burger-item {
    display: flex; align-items: center; gap: 0.5rem; width: 100%;
    padding: 0.45rem 0.8rem; border: none; background: none;
    color: var(--text); cursor: pointer; font-size: 0.88rem;
    text-align: left; transition: background 0.15s;
}
.burger-item:hover { background: var(--accent); color: var(--btn-text); }
.burger-item[hidden] { display: none; }
.burger-item svg { flex-shrink: 0; }
.burger-item-danger { color: #dc3545; }
.burger-item-danger:hover { background: #dc3545; color: #fff; }

/* Responsive: collapse sidebar on small screens */
@media (max-width: 768px) {
    #fab-sidebar { position: absolute; z-index: 50; height: 100%; }
    #fab-sidebar.collapsed { width: 0; min-width: 0; }
}

/* --- Chat content wrapper — centered responsive column --- */
/* 2026-04-02 — Messages and input centered with max-width for readability
   on wide screens; fills available width on narrow viewports. */
#messages {
    flex: 1; overflow-y: auto; padding: 1rem;
    display: flex; flex-direction: column; align-items: center;
}

#messages-inner {
    width: 100%; max-width: 800px;
}

.message { margin-bottom: 1rem; max-width: 80%; line-height: 1.5; }

.message.user {
    margin-left: auto; background: var(--primary);
    padding: 0.6rem 1rem; border-radius: var(--radius) var(--radius) 4px var(--radius);
    white-space: pre-wrap; color: var(--btn-text);
}

.message.assistant {
    background: var(--surface); padding: 0.6rem 1rem;
    border-radius: var(--radius) var(--radius) var(--radius) 4px;
}

/* 2026-04-14 — Timestamp on every message */
.message-time {
    display: block; font-size: 0.65rem; color: var(--text-muted);
    opacity: 0.6; margin-bottom: 0.15rem;
}
.message.tool .message-time { display: inline; margin-right: 0.4rem; margin-bottom: 0; }
.message-body { display: block; }

.message.tool {
    font-size: 0.8rem; color: var(--text-muted); background: transparent;
    border-left: 2px solid var(--accent); padding-left: 0.5rem; max-width: 90%;
}

/* --- Markdown content in assistant messages --- */
.message.assistant p { margin: 0.4em 0; }
.message.assistant ul, .message.assistant ol { margin: 0.4em 0 0.4em 1.5em; }
.message.assistant li { margin: 0.2em 0; }
.message.assistant h1, .message.assistant h2, .message.assistant h3 {
    margin: 0.8em 0 0.3em; font-weight: 600;
}
.message.assistant h1 { font-size: 1.3em; }
.message.assistant h2 { font-size: 1.15em; }
.message.assistant h3 { font-size: 1.05em; }

.message.assistant strong { font-weight: 600; }
.message.assistant em { font-style: italic; }

.message.assistant code {
    background: var(--code-bg); padding: 0.15em 0.35em; border-radius: 4px;
    font-family: 'Fira Code', 'Consolas', monospace; font-size: 0.9em;
}
.message.assistant pre {
    background: var(--code-bg); padding: 0.8em; border-radius: var(--radius);
    overflow-x: auto; margin: 0.5em 0;
}
.message.assistant pre code {
    background: none; padding: 0; font-size: 0.85em; line-height: 1.4;
}

.message.assistant table {
    border-collapse: collapse; margin: 0.5em 0; font-size: 0.9em; width: 100%;
}
.message.assistant th, .message.assistant td {
    border: 1px solid var(--border-color); padding: 0.4em 0.6em; text-align: left;
}
.message.assistant th { background: var(--primary); font-weight: 600; color: var(--btn-text); }

.message.assistant blockquote {
    border-left: 3px solid var(--accent); padding-left: 0.8em;
    color: var(--text-muted); margin: 0.5em 0;
}

.message.assistant a { color: var(--link-color); text-decoration: none; }
.message.assistant a:hover { text-decoration: underline; }

/* --- File download cards --- */
.file-card {
    display: inline-flex; align-items: center; gap: 0.5rem;
    background: var(--surface); border: 1px solid var(--border-color); border-radius: var(--radius);
    padding: 0.5rem 0.8rem; margin: 0.3rem 0; cursor: pointer;
    text-decoration: none; color: var(--text); font-size: 0.85rem;
    transition: background 0.2s;
}
.file-card:hover { background: var(--file-card-hover); }
.file-card svg { flex-shrink: 0; }
.file-card .file-name { font-weight: 500; }
.file-card .file-type { color: var(--text-muted); font-size: 0.75rem; }

/* --- File upload preview --- */
#file-preview {
    display: flex; flex-wrap: wrap; gap: 0.4rem; padding: 0.4rem;
    border-bottom: 1px solid var(--border-color);
}
#file-preview .file-chip {
    display: flex; align-items: center; gap: 0.3rem;
    background: var(--surface); border: 1px solid var(--border-color);
    border-radius: 12px; padding: 0.2rem 0.6rem; font-size: 0.8rem;
}
#file-preview .file-chip button {
    background: none; border: none; color: var(--text-muted); cursor: pointer;
    font-size: 1rem; line-height: 1; padding: 0 0.2rem;
}

/* --- Input area — centered to match message column --- */
#input-area {
    display: flex; justify-content: center;
    padding: 0.75rem 1rem; background: var(--header-bg); border-top: 1px solid var(--border-color);
}

#input-area-inner {
    display: flex; align-items: flex-end; gap: 0.5rem;
    width: 100%; max-width: 800px;
}

#attach-btn {
    display: flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; cursor: pointer; color: var(--text-muted);
    border-radius: var(--radius); transition: color 0.2s;
}
#attach-btn:hover { color: var(--text); }

#input-wrapper { flex: 1; display: flex; flex-direction: column; }

#message-input {
    width: 100%; padding: 0.6rem; border: 1px solid var(--border-color); border-radius: var(--radius);
    background: var(--input-bg); color: var(--text); font-size: 1rem;
    resize: none; font-family: inherit;
    transition: border-color 0.2s;
}

#send-btn {
    padding: 0.6rem 1.2rem; border: none; border-radius: var(--radius);
    background: var(--accent); color: var(--btn-text); cursor: pointer; font-size: 1rem;
    height: 36px; transition: background 0.2s, opacity 0.2s;
}
#send-btn:hover { opacity: 0.9; }
#send-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* --- Message footer (model + token usage) --- */
/* 2026-04-03 — Shown under assistant messages after completion */
.message-footer {
    font-size: 0.7rem; color: var(--text-muted); margin-top: 0.5rem;
    padding-top: 0.4rem; border-top: 1px solid var(--border-color);
    opacity: 0.7; font-style: italic;
}

/* --- Model indicator/selector in header --- */
.model-indicator {
    font-size: 0.75rem; color: var(--text-muted);
    background: var(--surface); padding: 0.15rem 0.5rem;
    border-radius: 10px; border: 1px solid var(--border-color);
}
.model-selector {
    font-size: 0.75rem; color: var(--text);
    background: var(--surface); padding: 0.2rem 0.4rem;
    border-radius: 10px; border: 1px solid var(--border-color);
    cursor: pointer; max-width: 260px;
}
.model-selector[hidden] { display: none; }

/* --- Show tools toggle --- */
/* 2026-04-14 — Checkbox to show/hide tool call messages in chat */
.show-tools-label {
    display: inline-flex; align-items: center; gap: 0.3rem;
    font-size: 0.75rem; color: var(--text-muted); cursor: pointer;
    margin-right: 0.3rem;
}
/* 2026-04-21 (v1.2.6) — Make the [hidden] attribute actually hide the
   label. The `.show-tools-label` rule above sets `display:inline-flex`,
   which wins over the UA stylesheet's `[hidden] { display:none }` at
   equal specificity (author beats UA). Without this explicit override,
   setting `hidden=true` from JS had no visual effect — the toggle
   stayed visible for user-only roles despite v1.2.5. */
.show-tools-label[hidden] { display: none; }
.show-tools-label input[type="checkbox"] {
    display: inline-block; width: auto; margin: 0; cursor: pointer;
}
.hide-tools .message.tool { display: none; }

/* --- Clear button --- */
.clear-btn {
    font-size: 0.8rem; padding: 0.25rem 0.6rem;
    background: transparent; border: 1px solid var(--border-color);
    color: var(--text-muted); cursor: pointer; border-radius: var(--radius);
}
.clear-btn:hover { background: var(--accent); color: var(--btn-text); border-color: var(--accent); }

/* --- Scroll to bottom button --- */
.scroll-bottom-btn {
    position: absolute; bottom: 80px; right: 2rem; z-index: 10;
    width: 36px; height: 36px; border-radius: 50%;
    background: var(--accent); color: var(--btn-text);
    border: none; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 2px 8px rgba(0,0,0,0.3);
    opacity: 0.85; transition: opacity 0.2s;
}
.scroll-bottom-btn:hover { opacity: 1; }
.scroll-bottom-btn[hidden] { display: none; }

/* 2026-04-17 — History navigation: search panel + date banner + load-more */
.history-date-input { display: none; }
.history-date-banner {
    flex-shrink: 0; display: flex; align-items: center; gap: 0.75rem;
    padding: 0.4rem 1rem; background: var(--hover-bg, #f1f3f5);
    border-bottom: 1px solid var(--border-color);
    font-size: 0.85rem; color: var(--text-muted);
}
.history-date-banner[hidden] { display: none; }
.return-present-btn {
    font-size: 0.78rem; padding: 0.2rem 0.55rem;
    background: var(--accent); color: var(--btn-text);
    border: none; border-radius: var(--radius); cursor: pointer;
}
.return-present-btn:hover { filter: brightness(1.1); }

.load-more-btn {
    display: block; margin: 0 auto 1rem;
    padding: 0.35rem 1rem; font-size: 0.8rem;
    background: transparent; color: var(--text-muted);
    border: 1px dashed var(--border-color); border-radius: var(--radius);
    cursor: pointer;
}
.load-more-btn:hover { background: var(--hover-bg, #f1f3f5); color: var(--text-color); }
.load-more-btn[disabled] { opacity: 0.6; cursor: wait; }

.history-search-panel {
    /* 2026-04-17 (v2.8.9) — Sit below the chat header instead of over it.
       The header is ~53px (0.75rem × 2 padding + ~28px logo + 1px border);
       3.5rem gives a safe margin and matches what the user sees visually. */
    position: absolute; top: 3.5rem; right: 0; bottom: 0;
    width: 340px; max-width: 85vw;
    background: var(--bg-color); border-left: 1px solid var(--border-color);
    display: flex; flex-direction: column;
    box-shadow: -4px 0 10px rgba(0,0,0,0.08); z-index: 20;
}
.history-search-panel[hidden] { display: none; }
.history-search-header {
    flex-shrink: 0; display: flex; gap: 0.5rem; align-items: center;
    padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--border-color);
}
#history-search-input {
    flex: 1; padding: 0.4rem 0.6rem; font-size: 0.9rem;
    border: 1px solid var(--border-color); border-radius: var(--radius);
    background: var(--bg-color); color: var(--text-color);
}
.history-search-close {
    background: transparent; border: none; font-size: 1.4rem; line-height: 1;
    cursor: pointer; color: var(--text-muted); padding: 0 0.3rem;
}
.history-search-close:hover { color: var(--text-color); }
.history-search-status {
    flex-shrink: 0; padding: 0.4rem 0.8rem;
    font-size: 0.78rem; color: var(--text-muted);
    border-bottom: 1px solid var(--border-color);
}
.history-search-status:empty { display: none; }
.history-search-results { flex: 1; overflow-y: auto; }
.history-search-result {
    padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--border-color);
    cursor: pointer; font-size: 0.83rem;
}
.history-search-result:hover { background: var(--hover-bg, #f1f3f5); }
.history-search-result .hs-meta {
    font-size: 0.72rem; color: var(--text-muted); margin-bottom: 0.2rem;
    display: flex; justify-content: space-between;
}
.history-search-result .hs-snippet {
    color: var(--text-color); line-height: 1.35;
    overflow: hidden; text-overflow: ellipsis;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
}
.history-search-result .hs-snippet mark {
    background: var(--accent); color: var(--btn-text);
    padding: 0 2px; border-radius: 2px;
}
.history-search-highlight { animation: hsFlash 2s ease-out; }
@keyframes hsFlash {
    0% { background: rgba(255, 200, 0, 0.5); }
    100% { background: transparent; }
}

/* --- File notification card (in chat) --- */
.file-notification-card {
    display: inline-flex; align-items: center; gap: 0.6rem;
    background: var(--surface); border: 1px solid var(--accent);
    border-radius: var(--radius); padding: 0.6rem 1rem;
    margin: 0.5rem 0; cursor: pointer; transition: background 0.2s;
    max-width: 80%;
}
.file-notification-card:hover { background: var(--primary); }
.file-notification-card:hover .file-notification-meta { color: var(--btn-text); opacity: 0.8; }
.file-notification-icon { font-size: 1.4rem; }
.file-notification-name { font-weight: 600; font-size: 0.9rem; }
.file-notification-meta { font-size: 0.75rem; color: var(--text-muted); }

/* --- Typing indicator (deprecated — replaced by activity-indicator) --- */
.typing-indicator { color: var(--text-muted); font-style: italic; font-size: 0.85rem; }

/* ==========================================================================
   2026-04-03 — Init phase messages and activity indicator
   ========================================================================== */

/* --- Init messages in chat --- */
.message.init {
    font-size: 0.85rem; color: var(--text-muted);
    padding: 0.4rem 0.8rem; max-width: 90%;
    background: transparent; border-left: 2px solid var(--accent);
}

.init-indicator {
    display: inline-block; width: 8px; height: 8px; border-radius: 50%;
    background: var(--accent); margin-right: 0.3rem; vertical-align: middle;
    animation: init-pulse 1s ease-in-out infinite;
}

.init-done {
    display: inline-block; width: 8px; height: 8px; border-radius: 50%;
    background: #28a745; margin-right: 0.3rem; vertical-align: middle;
}

@keyframes init-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
}

/* --- Activity indicator (pulsing dot next to send button) --- */
.activity-indicator {
    display: inline-block; width: 10px; height: 10px; border-radius: 50%;
    background: var(--accent); margin-left: 0.3rem; flex-shrink: 0;
    animation: activity-pulse 1.2s ease-in-out infinite;
    align-self: center;
}

.activity-indicator.stale {
    animation: activity-pulse 2.5s ease-in-out infinite;
    opacity: 0.4;
}

.activity-indicator[hidden] { display: none; }

@keyframes activity-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.3; transform: scale(0.7); }
}

/* --- Disabled input state --- */
#message-input:disabled {
    opacity: 0.5; cursor: not-allowed;
}

/* ==========================================================================
   2026-04-03 — Profile, Admin, and Form styles for user CRUD screens
   ========================================================================== */

/* --- Form container (centered column) --- */
.form-container {
    flex: 1; overflow-y: auto; padding: 1.5rem;
    display: flex; flex-direction: column; align-items: center;
}

.form-card {
    background: var(--surface); border-radius: var(--radius);
    padding: 1.5rem 2rem; width: 100%; max-width: 600px;
}

.form-card.admin-card { max-width: 800px; }

/* 2026-04-17 (v2.8.23) — Interlocutor edit card at 50% width. The fields
   are short (email, display_name, roles, LLM grants) — full-width is
   wasteful, 50% stays comfortable to read on any screen. */
.form-card.interlocutor-card {
    width: 50%;
    min-width: 520px;
    max-width: 1100px;
}

/* 2026-04-17 (v2.8.9) — FAB edit card: wide layout like Browse Files.
   80% of viewport, centered, capped on huge screens so the labels stay
   within a comfortable reading distance of the inputs on the right.
   2026-04-17 (v2.8.11) — Extra padding + vertical rhythm so labels breathe
     from the edges and h3 sections don't feel stacked on top of each other. */
.form-card.fab-card {
    width: 80%;
    max-width: 1600px;
    padding: 2rem 2.5rem 2.25rem;
}
.form-card.fab-card h3 {
    margin: 2rem 0 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
}
.form-card.fab-card h3:first-of-type {
    border-top: none;
    padding-top: 0;
    margin-top: 1.5rem;
}
.form-card.fab-card label {
    margin-top: 0.85rem;
    margin-bottom: 0.3rem;
}
.form-card.fab-card > form > label:first-of-type { margin-top: 0; }
.form-card.fab-card input,
.form-card.fab-card textarea,
.form-card.fab-card select {
    margin-bottom: 0.25rem;  /* label margin-top provides the main gap */
}
.form-card.fab-card .form-hint { margin-bottom: 0.5rem; }
.form-card.fab-card .form-actions { margin-top: 1.75rem; }

.form-card h2 { margin-bottom: 1rem; font-size: 1.2rem; }
.form-card h3 { margin: 1.2rem 0 0.5rem; font-size: 1rem; color: var(--text-muted); }

.form-card label {
    display: block; margin-bottom: 0.25rem; font-size: 0.85rem;
    color: var(--text-muted); font-weight: 500;
}

.form-card input,
.form-card textarea,
.form-card select {
    display: block; width: 100%; padding: 0.5rem; margin-bottom: 0.75rem;
    border: 1px solid var(--border-color); border-radius: var(--radius);
    background: var(--input-bg); color: var(--text); font-size: 0.9rem;
    font-family: inherit;
}

.form-card input:disabled {
    opacity: 0.6; cursor: not-allowed;
}

.form-card textarea { resize: vertical; }

.form-actions {
    display: flex; gap: 0.75rem; margin-top: 1rem;
    justify-content: flex-start;
}

.btn-primary {
    padding: 0.5rem 1.2rem; border: none; border-radius: var(--radius);
    background: var(--accent); color: var(--btn-text); cursor: pointer;
    font-size: 0.9rem; transition: opacity 0.2s;
}
.btn-primary:hover { opacity: 0.9; }

/* 2026-04-07 — Secondary button (outline style, used for Cancel/Back/Export) */
.btn-secondary {
    padding: 0.5rem 1.2rem; border: 1px solid var(--border-color); border-radius: var(--radius);
    background: transparent; color: var(--text); cursor: pointer;
    font-size: 0.9rem; transition: all 0.2s;
}
.btn-secondary:hover { background: var(--accent); color: var(--btn-text); border-color: var(--accent); }

.btn-danger {
    padding: 0.5rem 1.2rem; border: none; border-radius: var(--radius);
    background: #dc3545; color: #fff; cursor: pointer;
    font-size: 0.9rem; transition: opacity 0.2s;
}
.btn-danger:hover { opacity: 0.9; }

.form-message {
    margin-top: 0.75rem; font-size: 0.85rem; padding: 0.4rem 0.8rem;
    border-radius: var(--radius);
}
.form-message.success { color: #28a745; }
.form-message.error { color: var(--accent); }

.profile-usage {
    display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.75rem;
}
.profile-usage-stat {
    background: var(--surface); border: 1px solid var(--border-color);
    border-radius: var(--radius); padding: 0.5rem 0.8rem; text-align: center;
}
.profile-usage-stat .stat-value { font-size: 1.2rem; font-weight: 700; }
.profile-usage-stat .stat-label { font-size: 0.7rem; color: var(--text-muted); }

/* --- Admin toolbar --- */
.admin-toolbar {
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 1rem;
}
.admin-toolbar h2 { margin-bottom: 0; }

/* --- Shared proposals --- */
.proposal-card {
    background: var(--surface); border: 1px solid var(--accent);
    border-radius: var(--radius); padding: 0.75rem; margin-bottom: 0.5rem;
}
.proposal-header {
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 0.4rem;
}
.proposal-author { font-weight: 600; font-size: 0.85rem; }
.proposal-date { font-size: 0.75rem; color: var(--text-muted); }
.proposal-content {
    font-size: 0.83rem; white-space: pre-wrap; max-height: 120px;
    overflow-y: auto; margin-bottom: 0.5rem; line-height: 1.4;
}
.proposal-actions { display: flex; gap: 0.4rem; }

/* --- FAB edit permissions grid --- */
/* 2026-04-07 — Permissions/roles grid: label left, checkbox right, aligned */
.ae-perms-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 0.15rem 1rem; margin-bottom: 0.75rem;
}
.ae-perm-item {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 0.85rem; padding: 0.25rem 0.4rem;
    border-bottom: 1px solid var(--border-color);
}
.ae-perm-item:last-child { border-bottom: none; }
.ae-perm-item label { cursor: pointer; flex: 1; order: -1; }
.ae-perm-item input { cursor: pointer; width: auto; height: auto; margin: 0; flex-shrink: 0; }

/* 2026-04-06 — Profile fields and data permissions rows */
.profile-field-row {
    display: flex; align-items: center; gap: 0.4rem;
    padding: 0.25rem 0; font-size: 0.88rem;
}
.profile-field-key {
    min-width: 120px; font-weight: 600; color: var(--text-muted);
}
.profile-field-value { flex: 1; }
.profile-add-field {
    display: flex; gap: 0.3rem; margin-top: 0.3rem;
}
.profile-add-field input { flex: 1; }
.btn-small {
    padding: 0.15rem 0.5rem; font-size: 0.8rem; min-width: auto;
}
.form-hint {
    font-size: 0.82rem; color: var(--text-muted); margin: 0.2rem 0 0.5rem;
}

/* 2026-04-10 — Data sharing: FAB selector tabs + permission table */
.sharing-fab-tabs {
    display: flex; flex-wrap: wrap; gap: 0.3rem; margin-bottom: 0.5rem;
}
.sharing-fab-tab {
    padding: 0.3rem 0.7rem; border: 1px solid var(--border-color);
    border-radius: var(--radius); background: var(--surface);
    color: var(--text-muted); font-size: 0.82rem; cursor: pointer;
    transition: all 0.15s;
}
.sharing-fab-tab:hover { border-color: var(--accent); color: var(--text); }
.sharing-fab-tab.active {
    background: var(--accent); color: #fff; border-color: var(--accent);
}
.sharing-badge {
    display: inline-block; min-width: 1.1em; padding: 0 0.3em;
    border-radius: 999px; background: rgba(255,255,255,0.3);
    font-size: 0.7rem; text-align: center; margin-left: 0.2em;
}
.sharing-table {
    width: 100%; border-collapse: collapse;
    font-size: 0.85rem; margin-bottom: 0.5rem;
}
.sharing-table th, .sharing-table td {
    padding: 0.3rem 0.4rem; text-align: left;
    border-bottom: 1px solid var(--border-color);
}
.sharing-table th { font-weight: 600; color: var(--text-muted); font-size: 0.8rem; }
.sharing-field-name { font-weight: 600; }
.sharing-sel { font-size: 0.82rem; padding: 0.15rem 0.2rem; }

/* 2026-04-07 — LLM catalog cards */
.llm-card {
    padding: 0.6rem 0; border-bottom: 1px solid var(--border-color);
}
.llm-card:last-child { border-bottom: none; }
.llm-card-header { display: flex; justify-content: space-between; align-items: baseline; }
.llm-card-name { font-weight: 600; font-size: 0.95rem; }
.llm-card-meta { font-size: 0.8rem; color: var(--text-muted); }
.llm-card-desc { font-size: 0.85rem; margin: 0.2rem 0; }
.llm-card-comment { font-size: 0.82rem; color: var(--text-muted); font-style: italic; margin: 0.1rem 0; }
.llm-card-footer { display: flex; align-items: center; gap: 0.8rem; margin-top: 0.3rem; font-size: 0.82rem; }
.llm-card-score { font-weight: 600; }
.llm-card-reports { color: var(--text-muted); }
.llm-ref-link { font-size: 0.78rem; margin-left: 0.3rem; }
.llm-reports { font-size: 0.82rem; margin-bottom: 0.3rem; }
.llm-report-row { padding: 0.15rem 0; color: var(--text-muted); }
.llm-report-link:hover { color: var(--accent); }
.test-detail { font-size: 0.78rem; color: var(--text-muted); margin-left: 1.5rem; margin-top: 0.1rem; white-space: pre-wrap; }

/* 2026-04-07 — Integrated test results in LLM edit */
.llm-test-score { font-size: 0.9rem; margin: 0.5rem 0; }
.llm-test-row { font-size: 0.84rem; padding: 0.15rem 0; }
.test-pass { color: #16a34a; font-weight: 600; font-size: 0.78rem; }
.test-fail { color: #dc3545; font-weight: 600; font-size: 0.78rem; }
.test-error { font-size: 0.78rem; color: #dc3545; margin-left: 1.5rem; }

/* 2026-04-07 — Documentation popup */
.docs-popup {
    z-index: 100;
    background: var(--surface); border: 1px solid var(--border-color);
    border-radius: var(--radius); box-shadow: 0 4px 16px rgba(0,0,0,0.3);
    min-width: 280px; max-height: 400px; overflow-y: auto;
    padding: 0.5rem 0;
}
.docs-popup-title {
    font-weight: 600; font-size: 0.85rem; padding: 0.3rem 0.8rem;
    color: var(--text-muted); border-bottom: 1px solid var(--border-color);
    margin-bottom: 0.2rem;
}
.docs-popup-item {
    padding: 0.4rem 0.8rem; cursor: pointer; font-size: 0.88rem;
    transition: background 0.15s;
}
.docs-popup-item:hover { background: var(--accent); color: var(--btn-text); }
.docs-popup-loading { padding: 0.5rem 0.8rem; font-size: 0.85rem; color: var(--text-muted); }

/* 2026-04-07 — Grant rows in FAB sharing section.
   2026-04-18 (v2.8.28) — rows now mix user + FAB grants; the FAB badge
   distinguishes the two. Revoke button is discreet red on hover. */
.ae-user-row {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 0.83rem; padding: 0.2rem 0;
}
.ae-grant-type-fab {
    display: inline-block;
    padding: 0 0.35rem;
    border-radius: 3px;
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--btn-text);
    background: var(--accent);
    margin-left: 0.3rem;
    vertical-align: 1px;
}
.ae-grant-revoke-btn {
    background: transparent;
    color: var(--text-muted);
    border: 1px solid var(--border-color);
    padding: 0 0.4rem;
    border-radius: 3px;
    font-size: 0.8rem;
    cursor: pointer;
    margin-left: 0.3rem;
}
.ae-grant-revoke-btn:hover {
    color: #fff;
    background: var(--danger, #dc2626);
    border-color: var(--danger, #dc2626);
}

/* --- Admin tabs --- */
.admin-tab { /* reuses .sys-tab styles */ }

/* --- FAB list cards --- */
.fab-card {
    display: flex; justify-content: space-between; align-items: center;
    padding: 0.6rem 0; border-bottom: 1px solid var(--border-color);
}
.fab-card:last-child { border-bottom: none; }
.fab-card-info { flex: 1; }
.fab-card-name { font-weight: 600; }
.fab-card-meta { font-size: 0.75rem; color: var(--text-muted); }

/* --- Admin user table --- */
#admin-user-table {
    width: 100%; border-collapse: collapse; font-size: 0.9rem;
}
#admin-user-table th,
#admin-user-table td {
    text-align: left; padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--border-color);
}
#admin-user-table th {
    font-weight: 600; color: var(--text-muted); font-size: 0.8rem;
    text-transform: uppercase; letter-spacing: 0.03em;
}
#admin-user-table td .action-btn {
    background: none; border: 1px solid var(--border-color); border-radius: var(--radius);
    padding: 0.25rem 0.6rem; cursor: pointer; color: var(--text);
    font-size: 0.8rem; margin-right: 0.3rem; transition: background 0.2s;
}
#admin-user-table td .action-btn:hover { background: var(--primary); color: var(--btn-text); }

/* --- Storage list --- */
.storage-list {
    border: 1px solid var(--border-color); border-radius: var(--radius);
    max-height: 200px; overflow-y: auto; font-size: 0.85rem;
}
.storage-list .storage-empty {
    padding: 0.75rem; color: var(--text-muted); text-align: center;
}
.storage-item {
    display: flex; justify-content: space-between; align-items: center;
    padding: 0.4rem 0.75rem; border-bottom: 1px solid var(--border-color);
}
.storage-item:last-child { border-bottom: none; }

/* --- 2026-04-17 (v2.8.23) — Scheduled actions read-only table on
   FAB edit + Interlocutor edit screens. Compact, fixed header, prompt
   column ellipsizes (full text in title tooltip). */
.schedules-list { font-size: 0.82rem; }
.schedules-table {
    width: 100%;
    border-collapse: collapse;
}
.schedules-table thead th {
    text-align: left;
    padding: 0.4rem 0.5rem;
    border-bottom: 2px solid var(--border-color);
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.schedules-table tbody td {
    padding: 0.45rem 0.5rem;
    border-bottom: 1px solid var(--border-color);
    vertical-align: top;
}
.schedules-table tbody td:first-child {
    max-width: 320px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.schedules-table tbody tr:last-child td { border-bottom: none; }
.schedules-table code {
    background: var(--input-bg);
    padding: 1px 4px;
    border-radius: 3px;
    font-size: 0.78rem;
}
.storage-item .file-name { flex: 1; word-break: break-all; }
.storage-item .file-size { color: var(--text-muted); margin-left: 1rem; white-space: nowrap; }
.storage-item .file-download {
    margin-left: 0.5rem; color: var(--link-color); cursor: pointer;
    text-decoration: none; font-size: 0.8rem;
}
.storage-item .file-download:hover { text-decoration: underline; }

/* --- 2026-04-18 (v2.8.30 / inlux-web v1.0.5) — Recent exchanges table
   on FAB edit screen. Reuses .schedules-table styling; only the message
   column needs its own ellipsis + click-to-drilldown link styling.
   2026-04-18 (v1.0.6) — Scroll-bounded container (no tall pages), narrow
   metadata columns so the Message column claims the remaining width. */
.exchanges-scroll {
    max-height: 18rem;
    overflow-y: auto;
    border: 1px solid var(--border-color);
    border-radius: 4px;
}
/* Column-sizing trick: width:1% + white-space:nowrap shrinks each
   metadata column to its content. The Message column has no such
   constraint, so it expands to fill the rest of the table. */
.exchanges-table .ex-date,
.exchanges-table .ex-from,
.exchanges-table .ex-to,
.exchanges-table .ex-dir,
.exchanges-table .ex-channel {
    width: 1%;
    white-space: nowrap;
}
.exchanges-table .ex-content {
    width: auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* max-width keeps the ellipsis kicking in even on wide screens. */
    max-width: 0;
}
.exchanges-table .ex-session-link {
    background: none;
    border: none;
    padding: 0;
    color: var(--link-color);
    cursor: pointer;
    font: inherit;
    text-decoration: underline dotted;
}
.exchanges-table .ex-session-link:hover { text-decoration: underline; }

/* Drilldown modal — native <dialog> with a sober panel. The scroll lives
   inside .drilldown-thread, not on the dialog itself, so the header stays
   pinned when the thread is long. */
.drilldown-dialog {
    max-width: 720px;
    width: 90vw;
    max-height: 80vh;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 0;
    background: var(--card-bg, #fff);
    color: var(--text-color, inherit);
}
.drilldown-dialog::backdrop { background: rgba(0, 0, 0, 0.45); }
.drilldown-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border-color);
}
.drilldown-header h3 { margin: 0; font-size: 1rem; }
.drilldown-header h3 span {
    font-family: monospace;
    color: var(--text-muted);
    font-size: 0.85rem;
}
.drilldown-close {
    background: none; border: none; font-size: 1.4rem;
    cursor: pointer; line-height: 1; padding: 0 0.3rem;
    color: var(--text-muted);
}
.drilldown-close:hover { color: var(--text-color, inherit); }
.drilldown-thread {
    padding: 0.75rem 1rem;
    overflow-y: auto;
    max-height: calc(80vh - 3rem);
}
.drilldown-msg {
    margin-bottom: 0.75rem;
    padding: 0.5rem 0.75rem;
    border-radius: 6px;
    border: 1px solid var(--border-color);
    background: var(--input-bg, #f7f7f7);
}
/* v1.2.2 — Soft alternating tints for drilldown readability.
   Cool blue for what the FAB (this side of the admin card) said,
   warm amber for what the interlocutor (user or peer FAB) said.
   Low alpha so they overlay cleanly on top of any theme background
   without fighting the theme's own colour scheme. Themes can
   override --drilldown-fab-bg / --drilldown-peer-bg if they want
   stronger tones — here we default to "très doux" as Franck asked. */
.drilldown-msg.role-user {
    background: var(--drilldown-peer-bg, rgba(217, 119, 6, 0.08));
}
.drilldown-msg.role-assistant {
    background: var(--drilldown-fab-bg, rgba(59, 130, 246, 0.08));
}
/* v1.1.2 (Inlux v2.10.7) — thinking-step rows are the LLM's internal
   reasoning before a tool call. Not what the interlocutor received.
   Grey out + italic tag so the admin reads them as "thought", distinct
   from the actual reply. Override the role-assistant background. */
.drilldown-msg.drilldown-msg-thinking,
.drilldown-msg.role-assistant.drilldown-msg-thinking {
    background: var(--bg-muted, #eceff1);
    opacity: 0.85;
    border-style: dashed;
}
.drilldown-msg-thinking-tag {
    font-style: italic;
    color: var(--text-muted);
    font-weight: normal;
}
.drilldown-msg-meta {
    font-size: 0.72rem;
    color: var(--text-muted);
    margin-bottom: 0.3rem;
}
.drilldown-msg-content { white-space: pre-wrap; word-break: break-word; }

/* v1.1.2 — Same treatment in the Recent Exchanges list table. */
.exchanges-table tr.ex-thinking-step {
    background: var(--bg-muted, #eceff1);
    opacity: 0.8;
    font-style: italic;
}

/* --- Header navigation buttons alignment --- */
header button { margin-left: 0.3rem; }
header #profile-btn,
header #admin-btn,
header #dev-btn {
    display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; padding: 0;
}
/* 2026-04-03 — Ensure hidden attribute overrides display:flex on nav buttons */
header #admin-btn[hidden],
header #dev-btn[hidden] { display: none; }

/* --- Files screen --- */
header #files-btn {
    display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; padding: 0;
}

.files-breadcrumb {
    font-size: 0.8rem; color: var(--text-muted); flex: 1;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.files-grid {
    display: grid; gap: 0.5rem;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

.files-item {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.6rem 0.8rem; border: 1px solid var(--border-color);
    border-radius: var(--radius); cursor: pointer;
    transition: background 0.2s; text-decoration: none; color: var(--text);
}
.files-item:hover { background: var(--primary); color: var(--btn-text); }

.files-item-icon { flex-shrink: 0; opacity: 0.7; }
.files-item-info { flex: 1; min-width: 0; }
.files-item-name {
    font-weight: 500; font-size: 0.9rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.files-item-meta { font-size: 0.75rem; color: var(--text-muted); }
.files-item:hover .files-item-meta { color: inherit; opacity: 0.8; }

.files-dir-icon { color: var(--accent); }

.files-empty {
    text-align: center; color: var(--text-muted); padding: 2rem; font-size: 0.9rem;
}

.files-back-link {
    display: inline-flex; align-items: center; gap: 0.3rem;
    color: var(--link-color); cursor: pointer; font-size: 0.85rem;
    margin-bottom: 0.75rem; text-decoration: none;
}
.files-back-link:hover { text-decoration: underline; }

/* --- Dashboard --- */
header #dashboard-btn {
    display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; padding: 0;
}
header #dashboard-btn[hidden] { display: none; }

header #model-test-btn {
    display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; padding: 0;
}
header #model-test-btn[hidden] { display: none; }

header #sysadmin-btn {
    display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; padding: 0;
}
header #sysadmin-btn[hidden] { display: none; }

/* Sysadmin tabs */
.sys-tabs {
    display: flex; gap: 0.2rem; background: var(--surface);
    border-radius: var(--radius); padding: 0.2rem; margin: 0 0.5rem;
}
.sys-tab {
    padding: 0.3rem 0.6rem; border: none; border-radius: var(--radius);
    background: transparent; color: var(--text-muted); cursor: pointer;
    font-size: 0.8rem; transition: all 0.15s;
}
.sys-tab.active { background: var(--accent); color: var(--btn-text); }
.sys-tab:hover:not(.active) { color: var(--text); }

/* Progress bar */
.sys-progress { height: 8px; background: var(--border-color); border-radius: 4px; overflow: hidden; }
.sys-progress-fill { height: 100%; border-radius: 4px; transition: width 0.3s; }
.sys-progress-fill.green { background: #16a34a; }
.sys-progress-fill.orange { background: #f59e0b; }
.sys-progress-fill.red { background: #dc2626; }

/* Traffic chart (pure CSS bar chart) */
.traffic-chart {
    display: flex; align-items: flex-end; gap: 2px; height: 150px;
    background: var(--code-bg); border-radius: var(--radius);
    padding: 0.5rem 0.5rem 1.5rem; position: relative;
    border: 1px solid var(--border-color);
}
.traffic-bar {
    flex: 1; min-width: 4px; background: var(--accent); border-radius: 2px 2px 0 0;
    position: relative; transition: height 0.3s;
}
.traffic-bar:hover { opacity: 0.8; }
.traffic-bar:hover::after {
    content: attr(data-tooltip);
    position: absolute; bottom: calc(100% + 4px); left: 50%;
    transform: translateX(-50%); background: var(--surface);
    border: 1px solid var(--border-color); border-radius: 4px;
    padding: 2px 6px; font-size: 0.7rem; white-space: nowrap;
    color: var(--text); z-index: 5;
}
.traffic-labels {
    display: flex; justify-content: space-between;
    position: absolute; bottom: 2px; left: 0.5rem; right: 0.5rem;
    font-size: 0.6rem; color: var(--text-muted);
}

/* Sysadmin process/container cards */
.sys-process {
    display: flex; justify-content: space-between; align-items: center;
    padding: 0.4rem 0; border-bottom: 1px solid var(--border-color);
    font-size: 0.85rem;
}
.sys-process:last-child { border-bottom: none; }
.sys-status { font-weight: 600; font-size: 0.75rem; padding: 0.1rem 0.4rem; border-radius: 8px; }
.sys-status.online, .sys-status.active, .sys-status.running { background: #16a34a; color: #fff; }
.sys-status.stopped, .sys-status.inactive { background: #dc2626; color: #fff; }
.sys-status.unknown { background: #6b7280; color: #fff; }
.sys-action-btn {
    padding: 0.15rem 0.4rem; border: 1px solid var(--border-color);
    border-radius: var(--radius); background: none; color: var(--text-muted);
    cursor: pointer; font-size: 0.7rem;
}
.sys-action-btn:hover { background: var(--accent); color: var(--btn-text); }

.mt-test-row {
    display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem 0;
    border-bottom: 1px solid var(--border-color); font-size: 0.85rem;
}
.mt-test-row:last-child { border-bottom: none; }
.mt-badge {
    display: inline-block; padding: 0.15rem 0.5rem; border-radius: 10px;
    font-size: 0.75rem; font-weight: 600; min-width: 40px; text-align: center;
}
.mt-badge.pass { background: #16a34a; color: #fff; }
.mt-badge.fail { background: #dc2626; color: #fff; }
.mt-test-name { font-weight: 600; min-width: 140px; }
.mt-test-time { color: var(--text-muted); min-width: 60px; }
.mt-test-detail { color: var(--text-muted); font-size: 0.8rem; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.mt-score {
    font-size: 1.4rem; font-weight: 700; margin-bottom: 0.5rem;
}

.mt-report-item {
    display: flex; justify-content: space-between; align-items: center;
    padding: 0.4rem 0; border-bottom: 1px solid var(--border-color);
    font-size: 0.85rem; cursor: pointer;
}
.mt-report-item:hover { color: var(--accent); }
.mt-report-item:last-child { border-bottom: none; }

.dashboard-grid {
    display: grid; gap: 1rem;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    width: 100%; max-width: 900px;
}

.dash-card {
    background: var(--surface); border: 1px solid var(--border-color);
    border-radius: var(--radius); padding: 1rem;
}
.dash-card-label {
    font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase;
    letter-spacing: 0.04em; margin-bottom: 0.3rem;
}
.dash-card-value {
    font-size: 1.6rem; font-weight: 700; color: var(--text);
}
.dash-card-sub {
    font-size: 0.75rem; color: var(--text-muted); margin-top: 0.2rem;
}

.dash-section {
    grid-column: 1 / -1; /* Full width */
}
.dash-section h3 {
    font-size: 0.9rem; color: var(--text-muted); margin-bottom: 0.5rem;
}

/* 2026-04-08 — Unified dashboard/system table style (themed, like sched-table) */
.dash-table {
    width: 100%; border-collapse: collapse; font-size: 0.84rem;
    background: var(--surface); border: 1px solid var(--border-color);
    border-radius: var(--radius); overflow: hidden;
}
.dash-table th {
    font-weight: 600; color: var(--btn-text); font-size: 0.75rem;
    text-transform: uppercase; letter-spacing: 0.03em;
    background: var(--accent); padding: 0.5rem 0.6rem;
    text-align: left;
}
.dash-table td {
    text-align: left; padding: 0.45rem 0.6rem;
    border-bottom: 1px solid var(--border-color);
}
.dash-table tr:last-child td { border-bottom: none; }
.dash-table tr:hover td { background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }

/* 2026-04-08 — Schedules table: wider, responsive, themed */
.sched-table {
    width: 100%; border-collapse: collapse; font-size: 0.84rem;
    background: var(--surface); border: 1px solid var(--border-color);
    border-radius: var(--radius); overflow: hidden;
}
.sched-table th {
    font-weight: 600; color: var(--btn-text); font-size: 0.75rem;
    text-transform: uppercase; letter-spacing: 0.03em;
    background: var(--accent); padding: 0.5rem 0.6rem;
    text-align: left;
}
.sched-table td {
    padding: 0.45rem 0.6rem; border-bottom: 1px solid var(--border-color);
    vertical-align: top;
}
.sched-table tr:last-child td { border-bottom: none; }
.sched-table tr:hover td { background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
.sched-prompt { max-width: 250px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sched-cron { font-family: 'Fira Code', monospace; font-size: 0.78rem; color: var(--accent); }
.sched-status-active { color: #16a34a; font-weight: 600; }
.sched-status-done { color: var(--text-muted); }
.sched-status-error { color: #dc3545; font-weight: 600; }
.sched-next { font-weight: 600; }
.sched-result { font-size: 0.78rem; color: var(--text-muted); max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sched-agent { color: var(--accent); font-weight: 600; }
@media (max-width: 900px) {
    .sched-table { font-size: 0.78rem; }
    .sched-table th, .sched-table td { padding: 0.3rem 0.4rem; }
    .sched-prompt { max-width: 150px; }
}

/* --- History viewer --- */
header #history-btn {
    display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; padding: 0;
}

.hist-row {
    display: flex; align-items: flex-start; gap: 0.5rem; padding: 0.5rem 0;
    border-bottom: 1px solid var(--border-color); font-size: 0.83rem;
}
.hist-row:last-child { border-bottom: none; }
.hist-role {
    display: inline-block; min-width: 65px; padding: 0.1rem 0.4rem;
    border-radius: 8px; font-size: 0.7rem; font-weight: 600; text-align: center;
    flex-shrink: 0;
}
.hist-role.user { background: var(--primary); color: var(--btn-text); }
.hist-role.assistant { background: var(--surface); border: 1px solid var(--border-color); }
.hist-role.tool { background: transparent; color: var(--text-muted); border: 1px solid var(--border-color); }
.hist-role.forget { background: #6b7280; color: #fff; text-decoration: line-through; opacity: 0.5; }
.hist-content {
    flex: 1; color: var(--text); word-break: break-word;
    max-height: 150px; overflow-y: auto; white-space: pre-wrap;
    font-size: 0.82rem; line-height: 1.4;
    scrollbar-width: thin;
    scrollbar-color: var(--text-muted) transparent;
}
/* Webkit scrollbar for history cells */
.hist-content::-webkit-scrollbar { width: 6px; }
.hist-content::-webkit-scrollbar-thumb { background: var(--text-muted); border-radius: 3px; }
.hist-content.forgotten { opacity: 0.4; text-decoration: line-through; }
.hist-time { color: var(--text-muted); font-size: 0.7rem; white-space: nowrap; flex-shrink: 0; }
.hist-btn {
    padding: 0.15rem 0.4rem; border: 1px solid var(--border-color); border-radius: var(--radius);
    background: none; color: var(--text-muted); cursor: pointer; font-size: 0.7rem;
    flex-shrink: 0; transition: all 0.2s;
}
.hist-btn:hover { background: var(--accent); color: var(--btn-text); border-color: var(--accent); }
.hist-tool-result { font-size: 0.78rem; color: var(--text-muted); font-style: italic; }
.hist-btn.restore { border-color: #16a34a; color: #16a34a; }
.hist-btn.restore:hover { background: #16a34a; color: #fff; }

/* 2026-04-09 — Agent mode toggle removed (mode system deleted) */

/* ==========================================================================
   2026-04-03 — Developer logs screen
   ========================================================================== */

.dev-controls {
    display: flex; gap: 0.4rem; align-items: center; flex: 1;
    justify-content: flex-end; flex-wrap: wrap;
}
.dev-controls select,
.dev-controls input[type="text"] {
    padding: 0.25rem 0.4rem; border: 1px solid var(--border-color);
    border-radius: var(--radius); background: var(--input-bg);
    color: var(--text); font-size: 0.8rem;
}
.dev-search-input { width: 140px; }
.dev-auto-label {
    font-size: 0.8rem; color: var(--text-muted);
    display: flex; align-items: center; gap: 0.2rem;
}
.dev-controls .btn-primary { font-size: 0.8rem; padding: 0.25rem 0.6rem; }

/* --- Split pane layout --- */
.dev-split {
    flex: 1; display: flex; flex-direction: column; overflow: hidden;
}

.log-container {
    flex: 1; overflow: auto; background: var(--code-bg);
    margin: 0; padding: 0; min-height: 60px;
}

.dev-divider {
    height: 5px; background: var(--border-color); cursor: row-resize;
    flex-shrink: 0; transition: background 0.15s;
}
.dev-divider:hover, .dev-divider.active {
    background: var(--accent);
}

.dev-prompt-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 0.3rem 0.75rem; background: var(--surface);
    border-bottom: 1px solid var(--border-color);
    font-size: 0.8rem; font-weight: 600; color: var(--text-muted);
}

.prompt-output {
    font-size: 0.75rem; line-height: 1.4; color: var(--text);
}

.log-output {
    padding: 0.75rem; margin: 0; font-size: 0.78rem; line-height: 1.5;
    font-family: 'Fira Code', 'Consolas', monospace;
    white-space: pre-wrap; word-break: break-all;
    color: var(--text);
}

/* Log line coloring by tag */
.log-line { display: block; }
.log-line:hover { background: rgba(255,255,255,0.03); }
.log-tag { font-weight: 600; }
.log-ts { color: var(--text-muted); }
.log-tag-ERROR { color: #ef4444; }
.log-tag-WARNING { color: #f59e0b; }
.log-tag-API { color: #60a5fa; }
.log-tag-AUTH { color: #a78bfa; }
.log-tag-MCP { color: #34d399; }
.log-tag-SESSION { color: #38bdf8; }
.log-tag-ENGINE { color: #fb923c; }
.log-tag-DB { color: #e879f9; }
.log-tag-CONFIG { color: #94a3b8; }
.log-tag-MQTT { color: #2dd4bf; }
.log-tag-LLM { color: #fbbf24; }
.log-tag-FILE { color: #4ade80; }
.log-tag-TOOL { color: #f472b6; }
.log-id { color: var(--text-muted); }

/* 2026-04-08 — FIP Clone wizard (FAB Identity Pack) */
.clone-steps {
    display: flex; align-items: center; gap: 0.4rem;
    margin-bottom: 1.5rem; font-size: 0.85rem;
    border-bottom: 1px solid var(--border-color); padding-bottom: 0.8rem;
}
.clone-step {
    padding: 0.3rem 0.7rem; border-radius: var(--radius);
    color: var(--text-muted); font-weight: 500;
}
.clone-step.active {
    background: var(--primary); color: var(--btn-text); font-weight: 600;
}
.clone-step.done {
    color: #16a34a; font-weight: 600;
}
.clone-step-sep { color: var(--text-muted); font-size: 0.75rem; }

/* Drop zone for file upload */
.clone-dropzone {
    border: 2px dashed var(--border-color); border-radius: var(--radius);
    padding: 2rem; text-align: center; cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
    color: var(--text-muted); margin: 0.5rem 0;
}
.clone-dropzone:hover,
.clone-dropzone.dragover {
    border-color: var(--primary); background: rgba(var(--primary-rgb, 100,100,255), 0.05);
}
.clone-dropzone-icon { font-size: 2rem; margin-bottom: 0.5rem; }
.clone-dropzone-text { font-size: 0.9rem; }
.clone-dropzone-hint { font-size: 0.78rem; color: var(--text-muted); margin-top: 0.3rem; }

/* Analysis review cards */
.fip-section {
    margin: 1rem 0; padding: 0.8rem;
    border: 1px solid var(--border-color); border-radius: var(--radius);
    background: var(--bg);
}
.fip-section-title {
    font-weight: 600; font-size: 0.9rem; margin-bottom: 0.5rem;
    display: flex; align-items: center; gap: 0.4rem;
}
.fip-badge {
    display: inline-block; padding: 0.1rem 0.4rem; border-radius: 3px;
    font-size: 0.72rem; font-weight: 600; text-transform: uppercase;
}
.fip-badge-ready { background: #16a34a; color: #fff; }
.fip-badge-warning { background: #f59e0b; color: #000; }
.fip-badge-error { background: #dc3545; color: #fff; }
.fip-badge-unmapped { background: #6b7280; color: #fff; }
.fip-badge-skip { background: var(--surface); color: var(--text-muted); border: 1px solid var(--border-color); }

/* File/tool inventory table */
/* 2026-04-10 — Responsive: overflow-x for wide tables, word-break for long paths */
.fip-table {
    width: 100%; border-collapse: collapse; font-size: 0.82rem;
    table-layout: auto;
}
.fip-table th, .fip-table td {
    padding: 0.3rem 0.5rem; text-align: left;
    border-bottom: 1px solid var(--border-color);
    word-break: break-word; max-width: 400px;
}
.fip-section { overflow-x: auto; }
.fip-table th {
    font-weight: 600; color: var(--text-muted); font-size: 0.78rem;
    text-transform: uppercase;
}
.fip-table tr:last-child td { border-bottom: none; }

/* Warning/info banners */
.fip-warnings {
    padding: 0.5rem 0.7rem; border-radius: var(--radius);
    background: rgba(245, 158, 11, 0.1); border-left: 3px solid #f59e0b;
    font-size: 0.82rem; margin: 0.5rem 0;
}
.fip-warnings li { margin: 0.2rem 0; }

/* Prompt preview (collapsible) */
.fip-prompt-preview {
    font-size: 0.8rem; white-space: pre-wrap;
    background: var(--bg); padding: 0.5rem;
    border-radius: var(--radius); max-height: 120px;
    overflow: auto; color: var(--text-muted);
}

/* Reconstruction notes */
.fip-notes {
    font-size: 0.82rem; font-style: italic; color: var(--text-muted);
    padding: 0.5rem; border-left: 3px solid var(--primary);
    margin: 0.5rem 0;
}

/* Success result card */
.fip-success {
    text-align: center; padding: 1.5rem;
}
.fip-success-icon { font-size: 3rem; margin-bottom: 0.5rem; }
.fip-success-title { font-size: 1.2rem; font-weight: 600; margin-bottom: 0.3rem; }
.fip-success-details { font-size: 0.85rem; color: var(--text-muted); }

/* --- 2026-04-17 — FAB file browser (full-width screen, like MQTT test) ---
   2026-04-17 (v2.8.7) — Panel is now a direct child of the screen (no
     .form-container wrapper). flex:1 takes the remaining vertical space
     after the header; width fills the viewport; inner columns get explicit
     flex-basis so the viewer always keeps most of the page width. */
.ae-browse-panel {
    display: flex;
    gap: 1.5rem;
    flex: 1;
    min-height: 0;      /* needed so children can overflow without pushing */
    width: 80%;         /* 2026-04-17 — breathing room on wide screens */
    max-width: 1600px;
    margin: 0 auto;     /* centered */
    padding: 1rem 0 1.5rem;
    box-sizing: border-box;
}
.ae-browse-tree {
    /* 2026-04-17 (v2.8.12) — Widened from 320 → 480 px so filenames are
       rarely truncated (icon + name + date + size + trash icon adds ~170 px
       of non-name chrome per row, which left too little for the name). */
    flex: 0 0 480px;
    min-width: 320px;
    overflow-y: auto;
    font-size: 0.82rem;
    border-right: 1px solid var(--border-color);
    padding-right: 1rem;
}
.ae-browse-viewer {
    flex: 1 1 auto;
    min-width: 0;       /* allow shrink so <pre> with long lines doesn't push */
    overflow: auto;
    font-size: 0.9rem;
    padding-left: 0.5rem;
}
.ae-browse-viewer-empty {
    color: var(--text-muted);
    padding: 2rem;
    text-align: center;
}
.ae-browse-viewer pre {
    background: var(--input-bg);
    padding: 0.75rem;
    border-radius: var(--radius);
    overflow-x: auto;
    font-size: 0.8rem;
    line-height: 1.5;
}
.ae-browse-viewer .md-rendered {
    line-height: 1.6;
}
/* Tree items */
.browse-section {
    font-weight: 600;
    margin: 0.75rem 0 0.25rem;
    color: var(--accent);
    font-size: 0.85rem;
}
.browse-section:first-child { margin-top: 0; }
.browse-dir {
    cursor: pointer;
    padding: 0.15rem 0;
    user-select: none;
}
.browse-dir::before {
    content: "▸ ";
    display: inline-block;
    width: 1em;
    transition: transform 0.15s;
}
.browse-dir.open::before { content: "▾ "; }
.browse-dir-children { margin-left: 1rem; }
.browse-dir-children.collapsed { display: none; }
/* 2026-04-17 (v2.8.11) — Files become a flex row with name + modified
   timestamp + size + trash icon. Name takes flex:1 with ellipsis so long
   names don't wreck the layout. Trash icon appears on row hover. */
.browse-file {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.2rem 0.3rem 0.2rem 1em;
    cursor: pointer;
    border-radius: 3px;
    min-width: 0;
}
.browse-file:hover { background: var(--input-bg); }
.browse-file.active { background: var(--accent); color: var(--btn-text); }
.browse-file-icon { flex: 0 0 auto; }
.browse-file-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.browse-file-mod {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 0.7rem;
    font-family: ui-monospace, monospace;
}
.browse-file-size {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 0.72rem;
}
.browse-file.active .browse-file-mod,
.browse-file.active .browse-file-size { color: var(--btn-text); opacity: 0.8; }
.browse-file-del {
    flex: 0 0 auto;
    background: transparent;
    border: none;
    padding: 2px 4px;
    border-radius: 3px;
    color: var(--text-muted);
    cursor: pointer;
    opacity: 0;          /* hidden until row is hovered */
    transition: opacity 0.1s, color 0.1s, background 0.1s;
    display: flex;
    align-items: center;
}
.browse-file:hover .browse-file-del { opacity: 1; }
.browse-file-del:hover { color: var(--danger, #dc2626); background: rgba(220, 38, 38, 0.1); }
.browse-file-del:disabled { opacity: 0.5; cursor: wait; }
.browse-download-link {
    display: inline-block;
    margin-top: 0.5rem;
    color: var(--accent);
    cursor: pointer;
    text-decoration: underline;
}
