/* ═══════════════════════════════════════════════════════════
   AI-Horizon-Core (theme folder "AI2") — AI Platform Theme
   (Aurora palette, top navigation)
   Visual-upgrade fork of AI-Horizon: same chrome model (menu in
   the top bar, no sidebar) and the same --sv-* token contract,
   but a richer surface system — a warm-grey canvas under white
   cards, aurora-gradient primary buttons, a three-step border
   scale and fuller state feedback (table headers, zebra rows,
   hover/selected tints, status badges).
   Primary Teal #0D9488 · Canvas #F5F3EE · Cards #FFFFFF
   Brand gradient (accent-only): teal → cyan → sky
   Keeps the --sv-* token architecture and sv- class conventions so
   the framework menu and AI module pages work unchanged. Sidebar
   tokens are still emitted (mapped onto the teal palette) because
   module CSS (settings.css nav pills etc.) reads them.
   ═══════════════════════════════════════════════════════════ */

:root {
    /* ── Primary palette — aurora teal (aligned with AI1) ──
       --sv-primary-rgb is THE single source every alpha tint in this
       sheet derives from (rgba(var(--sv-primary-rgb), a)); the header
       accent customizer (js/accent.js) rewrites it plus the solid
       stops, and all ~30 tints follow with zero extra wiring. */
    --sv-primary: #0D9488;
    --sv-primary-rgb: 13, 148, 136;
    --sv-primary-light: #14B8A6;
    --sv-primary-dark: #0F766E;
    --sv-primary-active: #115E59;
    --sv-primary-bg: rgba(var(--sv-primary-rgb), 0.08);
    --sv-primary-bg-hover: rgba(var(--sv-primary-rgb), 0.13);
    --sv-accent: #06B6D4;               /* aurora cyan — glows & highlights */
    --sv-accent-light: #22D3EE;
    --sv-accent-violet: #A78BFA;        /* third aurora stop, login panel only */
    /* Brand gradient — used on accent moments (logo tile, avatar disc,
       preloader, login banner tile) AND — since the v2 visual upgrade —
       on primary buttons + progress bars, where the teal→cyan sweep
       carries the brand without ever touching content surfaces. */
    --sv-gradient-brand: linear-gradient(135deg, #0D9488 0%, #06B6D4 60%, #22D3EE 100%);

    /* ── Status colors ── */
    --sv-danger: #E11D48;
    --sv-success: #059669;
    --sv-warning: #D97706;
    --sv-info: #0284C7;

    /* ── Surfaces — warm neutrals in THREE distinct steps so every
         region reads at a glance: the scrolling canvas is a warm
         grey sheet, cards float on it white, and inset regions
         (table headers, tiles, code) sink one step below the card.
         v2 upgrade: canvas moved off pure white so cards gain real
         elevation instead of white-on-white hairlines. ── */
    --sv-bg-body: #ECE9E1;
    --sv-bg-white: #FFFFFF;
    --sv-bg-card: #FFFFFF;
    --sv-bg-canvas: #F5F3EE;
    --sv-bg-hover: #EFEBE3;
    --sv-bg-input: #FAF9F6;
    --sv-bg-inset: #F0EDE6;
    /* Top bar — one shade heavier than the canvas so the top
       navigation reads as its own band above the content. */
    --sv-bg-topbar: #F1EEE7;

    /* ── Sidebar tokens — AI2 has NO sidebar, but module CSS reads
         these (settings.css nav pills fall back to them), so they are
         re-emitted with the warm teal values AI1 uses. Treat as
         compatibility aliases; do not delete without checking module
         consumers. ── */
    --sv-bg-sidebar: #FDFCFA;
    --sv-bg-sidebar-hover: #F1EFEA;
    --sv-bg-sidebar-sub: transparent;
    --sv-sidebar-text: #57534E;
    --sv-sidebar-text-hover: #292524;
    --sv-sidebar-icon: #A8A29E;
    --sv-sidebar-label: #A8A29E;
    --sv-sidebar-active-bg: rgba(var(--sv-primary-rgb), 0.10);
    --sv-sidebar-active-text: #0F766E;
    --sv-sidebar-active-icon: #0D9488;
    --sv-sidebar-active-bar: #0D9488;
    --sv-sidebar-border: #E2DDD2;
    --sv-sidebar-scrollbar: #D6D3D1;
    --sv-sidebar-guide: #EFEDE9;

    /* ── Login page (aligned with AI1's flat treatment) ── */
    --sv-login-banner: #0F766E;         /* card top banner & brand strip */
    --sv-login-bg: #F1F0EA;             /* calm flat backdrop */

    /* ── Text — warm stone scale ── */
    --sv-text: #292524;
    --sv-text-secondary: #57534E;
    --sv-text-muted: #A8A29E;
    --sv-text-light: #D6D3D1;
    --sv-text-link: #0F766E;

    /* ── Borders — warm hairlines in three strengths: light for
         inner dividers (table rows, card header seams), default for
         card/input strokes, strong for structural separators and
         hover emphasis. v2: each step nudged a touch deeper so lines
         stay visible without reading hard. ── */
    --sv-border: #E3DED3;
    --sv-border-light: #ECE8DF;
    --sv-border-strong: #CFC8BA;

    /* ── Shadows — warm-tinted ── */
    --sv-shadow-sm: 0 1px 2px rgba(41, 37, 36, 0.05);
    --sv-shadow: 0 2px 8px rgba(41, 37, 36, 0.07);
    --sv-shadow-lg: 0 8px 24px rgba(41, 37, 36, 0.10);
    --sv-shadow-xl: 0 16px 48px rgba(41, 37, 36, 0.16);

    /* ── v2 additive tokens — NEW variables only; nothing above is
         renamed, so every existing var(--sv-*) consumer keeps
         working. Status tints/borders give badges, chips and rows a
         consistent soft-colour language across module pages. ── */
    --sv-border-input: #DDD6C9;                       /* resting field stroke, one step above card borders */
    --sv-shadow-brand: 0 2px 8px rgba(var(--sv-primary-rgb), 0.28);
    --sv-shadow-brand-lg: 0 6px 18px rgba(var(--sv-primary-rgb), 0.32);
    --sv-success-bg: rgba(5, 150, 105, 0.10);
    --sv-success-border: rgba(5, 150, 105, 0.28);
    --sv-danger-bg: rgba(225, 29, 72, 0.08);
    --sv-danger-border: rgba(225, 29, 72, 0.26);
    --sv-warning-bg: rgba(217, 119, 6, 0.10);
    --sv-warning-border: rgba(217, 119, 6, 0.28);
    --sv-info-bg: rgba(2, 132, 199, 0.09);
    --sv-info-border: rgba(2, 132, 199, 0.26);
    --sv-bg-code: #F2EEE6;                            /* inline code / pre block surface */
    --sv-topbar-accent: linear-gradient(90deg, #0D9488 0%, #06B6D4 45%, #22D3EE 75%, rgba(34, 211, 238, 0) 100%);

    /* ── Radii — soft, one step rounder (AI-Aurora) ── */
    --sv-radius-sm: 8px;
    --sv-radius: 10px;
    --sv-radius-lg: 14px;
    --sv-radius-xl: 20px;

    /* ── Layout ── */
    --sv-header-height: 56px;
    --sv-transition: all 0.16s ease-out;
    --sv-transition-panel: all 0.22s cubic-bezier(0.22, 1, 0.36, 1);
    --sv-content-indent: 20px;

    /* ── Typography ── */
    --sv-font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans SC", "Noto Sans HK", "Microsoft JhengHei", sans-serif;
    --sv-font-mono: "JetBrains Mono", ui-monospace, Consolas, "Andale Mono", monospace;

    /* Override Default theme's Bootstrap brand variables */
    --bs-primary: #0D9488;
    --bs-primary-rgb: 13, 148, 136;
    --bs-link-color: #0F766E;
    --bs-link-hover-color: #115E59;
}

/* ===== BASE ===== */
.sv-theme {
    font-family: var(--sv-font-family);
    font-size: 14px;
    line-height: 1.6;
    /* Body is the frame behind the scrolling canvas: a whisper of a
       vertical gradient adds depth on preloader/edge moments without
       fighting the flat canvas. */
    background-color: var(--sv-bg-body);
    background-image: linear-gradient(180deg, #ECE9E1 0%, #F2F0EA 100%);
    background-attachment: fixed;
    color: var(--sv-text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ═══════════════════════════════════════════════════════════
   ROCKER NEUTRALIZATION — hide Rocker's layout, use our own
   ═══════════════════════════════════════════════════════════ */
.sv-theme .topbar { display: none; }
.sv-theme .page-footer { display: none; }

/* Full-height flex chain, mirroring the Default theme's
   .container-wrapper > .page-wrapper > .page-container cascade.
   Framework components size themselves with height:100% (pdf.js
   #outerContainer, jstree, GridStack); without a definite height on every
   ancestor they resolve to 0 and the page renders blank. */
.sv-theme .page-wrapper {
    margin: 0;
    background: transparent;
    height: auto;              /* height comes from the flex parent */
    min-height: 0;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.sv-theme .page-content { padding: 0; }

/* The <form> wrapper is a pass-through flex link in the chain */
.sv-theme form.page-content,
.sv-theme .nexTore-page-form {
    padding: 0;
    margin: 0;
    min-height: 0;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* ═══════════════════════════════════════════════════════════
   TOPBAR — warm-tinted header carrying brand + top nav + user
   tools. One shade heavier than the white canvas (--sv-bg-topbar)
   so the nav band reads apart from the content below; hairline at
   rest, hairline + soft shadow once content scrolls beneath it
   (JS hook .sv-topbar--scrolled, same as AI1).
   ═══════════════════════════════════════════════════════════ */
.sv-topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: var(--sv-header-height);
    background: var(--sv-bg-topbar);
    border-bottom: 1px solid var(--sv-border);
    z-index: 100;
    padding: 0 16px;
    transition: box-shadow 0.22s ease;
}

/* Aurora hairline — a 2px teal→cyan sweep along the header's bottom
   edge (::before is otherwise unused on .sv-topbar). The active nav
   item's 2px teal ::after bar paints over it and stays clearly
   readable; on scroll the soft shadow joins underneath. */
.sv-topbar::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 2px;
    background: var(--sv-topbar-accent);
    opacity: 0.65;
    pointer-events: none;
}

.sv-topbar.sv-topbar--scrolled {
    /* Lift feedback once content scrolls beneath: darken the hairline
       a step (--sv-border-strong) on top of the soft shadow, so the
       warm band keeps a crisp edge against white cards below. */
    border-bottom-color: var(--sv-border-strong);
    box-shadow: var(--sv-shadow);
}

.sv-topbar .navbar {
    height: var(--sv-header-height);
    gap: 12px;
}

.sv-header-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    flex-shrink: 0;
}

/* Brand tile — the ONLY gradient in the header chrome. White glyph on
   the teal→cyan ramp; ties to the avatar disc and the login banner
   so the brand reads consistently across the theme. */
.sv-header-logo {
    width: 32px;
    height: 32px;
    border-radius: var(--sv-radius-sm);
    background: var(--sv-gradient-brand);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    box-shadow: 0 2px 6px rgba(var(--sv-primary-rgb), 0.35);
    flex-shrink: 0;
}

/* Site logo images — uploaded Resources files or the theme's designed
   SVG fallbacks (see _Layout.cshtml). Wide logo rides ≥768px, the mark
   rides mobile; both size to the header band, never distort. */
.sv-header-logo-img {
    height: 32px;
    width: auto;
    max-width: 220px;
    object-fit: contain;
    flex-shrink: 0;
}

.sv-header-logo-img--mark {
    height: 30px;
}

.sv-header-title {
    font-size: 16px;
    font-weight: 650;
    color: var(--sv-text);
    white-space: nowrap;
    letter-spacing: -0.01em;
}

/* Mobile hamburger — hidden on ≥992px where the nav is inline */
.sv-menu-toggle {
    width: 36px;
    height: 36px;
    border-radius: var(--sv-radius-sm);
    border: 1px solid transparent;
    background: transparent;
    color: var(--sv-text-secondary);
    font-size: 16px;
    display: none;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
    transition: var(--sv-transition);
}

.sv-menu-toggle:hover {
    border-color: var(--sv-border);
    color: var(--sv-primary);
    background: var(--sv-primary-bg);
}

/* ═══════════════════════════════════════════════════════════
   TOP NAVIGATION — the whole site menu, horizontal.
   Desktop: inline row, active = 2px teal underline riding the
   header's bottom edge (Linear language). Groups own a floating
   panel; hover OR click opens it (parity for keyboard/touch).
   Mobile (<992px): this same element becomes the slide-down panel
   — see the RESPONSIVE section. Markup contract lives in
   Core/Web/Views/MainSiteMenu.cshtml; behaviour in js/template.js.
   ═══════════════════════════════════════════════════════════ */
.sv-topbar-nav {
    display: flex;
    align-items: stretch;
    align-self: stretch;
    height: 100%;
    margin-left: 16px;
    min-width: 0;
    /* MUST stay overflow-visible: group dropdown panels hang below the
       56px header, and any clip/scroll on this container hides them
       (the "dropdown won't open" bug was overflow-y:hidden here).
       When the row runs out of room on narrow desktop windows, labels
       ellipsize instead — see .sv-nav-label. */
    overflow: visible;
}

.sv-nav {
    display: flex;
    align-items: stretch;
    gap: 2px;
    height: 100%;
    margin: 0;
    padding: 0;
    list-style: none;
    flex-wrap: nowrap;
}

.sv-nav-item {
    position: relative;
    display: flex;
    align-items: stretch;
    min-width: 0;
}

/* Flat links and group triggers share one shape. The trigger is a
   <button>, so reset native button chrome explicitly. */
.sv-nav-link {
    display: flex;
    align-items: center;
    gap: 7px;
    height: 100%;
    padding: 0 12px;
    border: none;
    background: transparent;
    color: var(--sv-text-secondary);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    position: relative;
    min-width: 0;
    transition: color 0.16s ease-out, background-color 0.16s ease-out;
}

/* Last-resort compression on narrow desktop windows: the row never
   scrolls or wraps (both would clip the dropdowns), labels truncate. */
.sv-nav-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    /* The link's line-height:1 would make this box exactly 1em tall,
       and overflow:hidden then clips descenders (g, y, p) at the box
       edge. Give the label a full line box; the flex parent keeps it
       centred either way. */
    line-height: 1.5;
}

.sv-nav-link:hover {
    color: var(--sv-text);
    background: var(--sv-bg-hover);
}

.sv-nav-link > i:first-child {
    font-size: 14px;
    color: var(--sv-text-muted);
    transition: color 0.16s ease-out;
}

.sv-nav-link:hover > i:first-child {
    color: var(--sv-primary);
}

.sv-nav-caret {
    font-size: 9px;
    color: var(--sv-text-muted);
    transition: transform 0.18s ease-out;
}

.sv-nav-group.open .sv-nav-caret {
    transform: rotate(180deg);
}

/* Active — teal ink + soft tinted pill + 2px teal bar riding the
   header's bottom edge, so the current page reads at a glance.
   JS sets .active on the exact link and .mm-active on its <li>; both
   selectors land on the same paint. The pill is a ::before at
   z-index:-1 (the link itself must stay full-height so the ::after
   bar rides the header edge); desktop-only — the mobile panel tints
   the element background instead (see RESPONSIVE). */
.sv-nav-item.mm-active > .sv-nav-link,
.sv-nav-link.active {
    color: var(--sv-primary-dark);
    font-weight: 600;
}

@media (min-width: 992px) {
    .sv-nav-item.mm-active > .sv-nav-link::before,
    .sv-nav-link.active::before,
    .sv-nav-group--active > .sv-nav-trigger::before {
        content: "";
        position: absolute;
        top: 9px;
        bottom: 9px;
        left: 3px;
        right: 3px;
        border-radius: var(--sv-radius-sm);
        background: var(--sv-primary-bg);
        z-index: -1;
    }

    /* Hover on an active item deepens its own pill instead of taking
       the neutral grey wash (which would paint over the tint). */
    .sv-nav-item.mm-active > .sv-nav-link:hover,
    .sv-nav-link.active:hover,
    .sv-nav-group--active > .sv-nav-trigger:hover {
        background: transparent;
    }

    .sv-nav-item.mm-active > .sv-nav-link:hover::before,
    .sv-nav-link.active:hover::before,
    .sv-nav-group--active > .sv-nav-trigger:hover::before {
        background: var(--sv-primary-bg-hover);
    }
}

.sv-nav-item.mm-active > .sv-nav-link::after,
.sv-nav-link.active::after {
    content: "";
    position: absolute;
    left: 10px;
    right: 10px;
    bottom: 0;
    height: 2px;
    border-radius: 2px 2px 0 0;
    background: var(--sv-primary);
}

.sv-nav-item.mm-active > .sv-nav-link > i:first-child,
.sv-nav-link.active > i:first-child {
    color: var(--sv-primary);
}

/* A group whose panel holds the current page lights its trigger the
   same way (class set by template.js). */
.sv-nav-group--active > .sv-nav-trigger {
    color: var(--sv-primary-dark);
    font-weight: 600;
}

.sv-nav-group--active > .sv-nav-trigger::after {
    content: "";
    position: absolute;
    left: 10px;
    right: 10px;
    bottom: 0;
    height: 2px;
    border-radius: 2px 2px 0 0;
    background: var(--sv-primary);
}

.sv-nav-group--active > .sv-nav-trigger > i:first-child {
    color: var(--sv-primary);
}

/* ── Group dropdown panel (desktop) ── */
.sv-nav-dropdown {
    display: none;
    position: absolute;
    top: calc(100% - 1px);
    left: 0;
    min-width: 230px;
    background: var(--sv-bg-white);
    border: 1px solid var(--sv-border);
    border-radius: var(--sv-radius);
    box-shadow: var(--sv-shadow-lg);
    padding: 6px;
    z-index: 110;
}

.sv-nav-group.open .sv-nav-dropdown {
    display: block;
    animation: sv-dropdown-in 0.16s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Hover-open is desktop-only; on touch/mobile it would fight the
   accordion behaviour, so it lives behind the min-width query below. */
@media (min-width: 992px) {
    .sv-nav-group:hover .sv-nav-dropdown {
        display: block;
        animation: sv-dropdown-in 0.16s cubic-bezier(0.22, 1, 0.36, 1);
    }
}

.sv-nav-dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-radius: var(--sv-radius-sm);
    color: var(--sv-text-secondary);
    font-size: 13px;
    text-decoration: none;
    transition: var(--sv-transition);
}

.sv-nav-dropdown-item i {
    width: 16px;
    text-align: center;
    font-size: 13px;
    color: var(--sv-text-muted);
    transition: color 0.16s ease-out;
}

.sv-nav-dropdown-item:hover {
    background: var(--sv-bg-hover);
    color: var(--sv-text);
}

.sv-nav-dropdown-item:hover i {
    color: var(--sv-primary);
}

.sv-nav-dropdown-item.active {
    background: var(--sv-primary-bg);
    color: var(--sv-primary-dark);
    font-weight: 600;
}

.sv-nav-dropdown-item.active i {
    color: var(--sv-primary);
}

/* Third-level parents render as quiet section labels inside the panel */
.sv-nav-dropdown-label {
    padding: 8px 12px 4px;
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--sv-text-muted);
}

@keyframes sv-dropdown-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ═══════════════════════════════════════════════════════════
   USER DROPDOWN
   ═══════════════════════════════════════════════════════════ */
.sv-theme .navbar-nav .nav-item.dropdown {
    padding: 0 2px;
}

.sv-user-dropdown {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 10px;
    border-radius: 999px;
    transition: var(--sv-transition);
}

.sv-user-dropdown:hover {
    background: var(--sv-bg-hover);
}

/* Avatar disc uses the brand gradient — echoes the header logo tile */
.user-avatar {
    width: 32px;
    height: 32px;
    min-width: 32px;
    min-height: 32px;
    border-radius: 50%;
    background: var(--sv-gradient-brand);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 600;
}

.user-name {
    font-weight: 500;
    color: var(--sv-text);
    font-size: 13px;
}

/* ═══════════════════════════════════════════════════════════
   DROPDOWN MENU — floating panel: border + soft elevation
   ═══════════════════════════════════════════════════════════ */
.sv-dropdown {
    background: var(--sv-bg-white);
    border: 1px solid var(--sv-border);
    border-radius: var(--sv-radius);
    box-shadow: var(--sv-shadow-lg);
    padding: 6px;
    min-width: 190px;
    animation: sv-dropdown-in 0.16s cubic-bezier(0.22, 1, 0.36, 1);
}

.sv-dropdown .dropdown-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border-radius: var(--sv-radius-sm);
    color: var(--sv-text-secondary);
    font-size: 13px;
    transition: var(--sv-transition);
}

.sv-dropdown .dropdown-item:hover {
    background: var(--sv-bg-hover);
    color: var(--sv-text);
}

.sv-dropdown .dropdown-item svg {
    width: 16px;
    height: 16px;
}

.sv-dropdown .dropdown-divider {
    margin: 4px 0;
    border-color: var(--sv-border-light);
}

/* ═══════════════════════════════════════════════════════════
   MAIN CONTENT AREA — full width under the topbar (no sidebar).
   The scrolling container spans the whole viewport (20px gutters);
   the point of killing the sidebar was to give pages the reclaimed
   width, so no reading-width cap is applied here. Individual module
   panels keep their own inner max-widths where they need them.
   ═══════════════════════════════════════════════════════════ */
.sv-main-content {
    margin-left: 0;
    margin-top: var(--sv-header-height);
    height: calc(100vh - var(--sv-header-height));
    overflow: hidden;          /* the content area scrolls, never the body */
    display: flex;
    flex-direction: column;
}

.sv-page-content {
    flex: 1 1 auto;
    min-height: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Inner content wrapper (matches Default theme's .page-container: the one
   element in the chain that actually scrolls) */
.sv-theme .page-content.container-fluid {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    padding: 20px;
    background: var(--sv-bg-canvas);
    width: 100%;
    /* Column flex so the footer can be pushed to the bottom on short pages
       (Default gets the same effect from .page-content{min-height:calc(100% - 52px)}). */
    display: flex;
    flex-direction: column;
}

/* Flex would otherwise shrink page content that declares its own height
   (chat/prompt-api use calc(100vh - X)); pin every child at its natural size
   so the container behaves like the block box it was before. */
.sv-theme .page-content.container-fluid > * {
    flex-shrink: 0;
}

/* ═══ MODULE PAGE FALLBACKS (style unification) ═══
   Pages whose module CSS predates the current chrome model get scoped
   corrections HERE so the module files stay untouched and other themes
   (Default/AI/AI1) are unaffected. Chrome heights match AI1 (56px
   topbar, no breadcrumb bar), so the calibrations carry over. */

/* AISettingsPage: .settings-layout's min-height was computed for older
   chrome; re-anchor it to this theme's real chrome (topbar 56 + gutter
   + page header + card chrome + footer + slack). */
.sv-theme .settings-layout {
    min-height: calc(100vh - 250px);
}

/* AppDistribution keeps its own inner gutter (.page-content) inside the
   standard card now; pin it to the same 16px (.card-body reference) so
   the whitespace rhythm matches every other page. */
.sv-theme .app-distribution-page .page-content {
    padding: 16px;
}

/* AIChatBotInfo: the view wraps .app-info-page in the standard .card
   shell like every other page. Cancel the page-level min-height (it was
   computed for bare-in-container layout and would stretch the card past
   the viewport) and the page background (the card already provides the
   white surface). */
.sv-theme .card-body > .app-info-page {
    min-height: 0;
    background: transparent;
}

/* AIChatBotPageEdit: layout unification, same pattern as AIChatBotPage's
   chat-card-shell. The edit shell sits in the standard .card > .card-body
   structure (20px gutter, visible footer). Height comes from the theme's
   definite flex chain instead of the module's calc(100vh - 130px)
   arithmetic, so the page is exactly one viewport by construction.
   Module CSS stays untouched.
   Beats `.container-fluid > * { flex-shrink: 0 }` by specificity. */
.sv-theme .page-content.container-fluid > .chat-edit-shell {
    flex: 1 1 0;                 /* fill the leftover height; footer sinks to the bottom */
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;            /* clip the panels into the card's rounded corners */
}

/* card-body keeps no padding: the edit shell has its own panel border
   system — a full-bleed fit avoids double gutters. */
.sv-theme .chat-edit-shell > .chat-edit-body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 0;
}

/* Override the module's calc(100vh - 130px) base height and cancel the
   nested container-fluid's horizontal padding inside the shell. flex:1
   fills the body regardless of percentage-height resolution. */
.sv-theme .chat-edit-body .container-fluid.chat-root {
    flex: 1 1 auto;
    min-height: 0;
    height: 100%;
    max-height: none;
    padding: 0;
    background: transparent;
}

/* ═══════════════════════════════════════════════════════════
   SYSTEM FOOTER — "© {sitetitle} Powered By Nexify | N ms | Version…"
   Sits at the end of the scrolling content area. Negative margins cancel
   the container's padding so the rule bleeds edge to edge, matching the
   Default theme where the footer sits outside the padded content box.
   ═══════════════════════════════════════════════════════════ */
.sv-theme .sv-footer {
    margin: 16px -20px -20px;   /* cancel .page-content.container-fluid padding */
    margin-top: auto;           /* short pages: pin to the bottom */
    padding: 10px 20px;
    background: transparent;
    border-top: 1px solid var(--sv-border-light);
    color: var(--sv-text-muted);
    font-size: 12px;
    line-height: 1.5;
    gap: 4px;
}

.sv-theme .sv-footer,
.sv-theme .sv-footer .text-muted {
    color: var(--sv-text-muted) !important;   /* beats Bootstrap's .text-muted */
}

.sv-theme .sv-footer a {
    color: var(--sv-text-secondary);
    text-decoration: none;
}

.sv-theme .sv-footer a:hover {
    color: var(--sv-primary);
    text-decoration: underline;
}

/* The footer is chrome, not content — hide it while a child is fullscreen */
.sv-theme .page-content.container-fluid:fullscreen .sv-footer,
.sv-theme .page-content.container-fluid:-webkit-full-screen .sv-footer,
.sv-theme .page-content.container-fluid.fullscreen-fallback .sv-footer {
    display: none !important;
}

/* Fullscreen: remove padding when container goes fullscreen */
.sv-theme .page-content.container-fluid:fullscreen,
.sv-theme .page-content.container-fluid:-webkit-full-screen,
.sv-theme .page-content.container-fluid.fullscreen-fallback {
    padding: 0;
    max-width: none;            /* fullscreen means fullscreen */
    background: var(--sv-bg-body);
}

/* ═══════════════════════════════════════════════════════════
   PAGE HEADER — full-width compact title bar (kept for a future
   restore; the bar itself is commented out in _Layout.cshtml).
   ═══════════════════════════════════════════════════════════ */
.sv-page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--sv-bg-white);
    padding: 11px 20px 11px var(--sv-content-indent);
    border-bottom: 1px solid var(--sv-border-light);
    min-height: 48px;
    margin: 0;
    z-index: 10;
    position: relative;
    flex: 0 0 auto;            /* stays put while the content below scrolls */
}

.sv-page-title {
    font-size: 16px;
    font-weight: 650;
    color: var(--sv-text);
    margin: 0;
    line-height: 1;
    white-space: nowrap;
    letter-spacing: -0.01em;
}

.sv-page-header .breadcrumb {
    padding: 0;
    margin: 0;
    background: transparent;
    font-size: 12px;
    display: flex;
    align-items: center;
}

.sv-page-header .breadcrumb-item {
    font-size: 12px;
    line-height: 1;
}

.sv-page-header .breadcrumb-item a {
    color: var(--sv-text-muted);
    text-decoration: none;
    transition: color 0.16s ease-out;
}

.sv-page-header .breadcrumb-item a:hover {
    color: var(--sv-primary);
}

.sv-page-header .breadcrumb-item.active {
    color: var(--sv-primary);
    font-weight: 500;
}

.sv-page-header .breadcrumb-item + .breadcrumb-item::before {
    color: var(--sv-text-light);
    font-size: 10px;
}

/* ═══════════════════════════════════════════════════════════
   PRELOADER — ring in theme teal.
   The structural rules below are re-cast from the framework's
   compiled template bundle (Default styles/themes/Default/layout/
   style.min.css): .preloader must be a FIXED full-screen overlay
   and .loader/.loader__figure must be absolutely centred. Since
   the anonymous layout does not load that bundle, without these
   the preloader collapsed into a normal-flow block at the page
   top — the site name flashed there for a moment on every
   login-page refresh before jQuery's fadeOut removed it.
   ═══════════════════════════════════════════════════════════ */
.sv-theme .preloader {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 99999;
    background-color: var(--sv-bg-body);
    background-image: linear-gradient(180deg, #ECE9E1 0%, #F2F0EA 100%);
}

.sv-theme .loader,
.sv-theme .loader__figure {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.sv-theme .loader {
    overflow: visible;
    padding-top: 2em;
    height: 0;
    width: 2em;
}

.sv-theme .loader__figure {
    height: 0;
    width: 0;
    box-sizing: border-box;
    border: 0 solid var(--sv-primary);
    border-top-color: transparent;
    border-radius: 50%;
    animation: loader-figure 1.15s infinite cubic-bezier(0.215, 0.61, 0.355, 1);
}

.sv-theme .loader__label {
    float: left;
    margin: 0.5em 0 0 50%;
    transform: translateX(-50%);
    font-size: 0.875em;
    letter-spacing: 0.1em;
    line-height: 1.5em;
    color: var(--sv-primary);
    white-space: nowrap;
    animation: loader-label 1.15s infinite cubic-bezier(0.215, 0.61, 0.355, 1);
}

@keyframes loader-figure {
    0%   { height: 0; width: 0; background-color: var(--sv-primary); }
    29%  { background-color: var(--sv-primary); }
    30%  { height: 2em; width: 2em; background-color: transparent; border-width: 1em; opacity: 1; }
    100% { height: 2em; width: 2em; border-width: 0; opacity: 0; background-color: transparent; }
}

@keyframes loader-label {
    0%   { opacity: 0.25; }
    30%  { opacity: 1; }
    100% { opacity: 0.25; }
}

/* ═══════════════════════════════════════════════════════════
   ANONYMOUS PAGES — flat centred card (reference-matched)
   _AnonymousLayout is a transparent shell: these pages (Login,
   Installation, RequestNexToreLicense, Error) bring their own
   full-page markup, and `.login-register` is `position:fixed`
   with auto offsets — a wrapper in the layout would displace it.
   So the whole look is done here, on the framework's own classes.
   The banner, in-field icons and password reveal are injected by
   the _AnonymousLayout enhancement script (login form only), so
   Error / Installation keep working untouched. Colours match AI1.
   ═══════════════════════════════════════════════════════════ */
.sv-anonymous-page {
    background-color: var(--sv-login-bg);
    min-height: 100vh;
}

.sv-theme .login-register {
    display: flex;
    flex-direction: column;
    align-items: center;
    /* `safe` keeps tall pages (Installation) top-aligned instead of
       clipping above the viewport; plain `center` is the fallback. */
    justify-content: center;
    justify-content: safe center;
    padding: 24px 16px;
    overflow: auto;
    /* The inline photo background the page ships needs !important to be
       overridden; longhand only (the `background:` shorthand would also
       reset background-repeat). Flat reference: solid, no gradients. */
    background-image: none !important;
    background-color: var(--sv-login-bg);
}

/* The framework logo above the card is redundant — the card banner
   carries the brand now. Login.cshtml also ships two <br> siblings
   after it for spacing; neutralise them or they leave a phantom gap
   above the card. */
.sv-theme .login-register .logo {
    display: none;
}

.sv-theme .login-register > br {
    display: none;
}

/* ── Neutralise the framework's grid/utility dependencies ─────────
   The Rocker template stylesheet the anonymous layout references does
   not exist in this build — it 404s — so the Bootstrap grid & spacing
   utilities Login.cshtml relies on are missing entirely:
   - InputAttributesView wraps every credential field in a `.row` with
     a hidden col-md-3 label column and a col-md-12 input column.
     Without grid CSS the columns size to their content.
   - The profile <select> loses Bootstrap's `display:block` and
     collapses to a 64px inline-block control.
   Provide the minimum ourselves rather than copying the (absent)
   template CSS into the theme. */
.sv-theme .login-box .row {
    display: block;
}

.sv-theme .login-box .row > [class*="col-"] {
    display: block;
    width: 100%;
    max-width: 100%;
}

.sv-theme .login-box select.form-control,
.sv-theme .login-box .sv-field-input {
    width: 100%;
    /* Without the Rocker sheet (Bootstrap reboot) form controls fall
       back to content-box: `width:100%` would overflow the card by
       exactly the padding amount. border-box keeps 100% = the visible
       edge, padding included. */
    box-sizing: border-box;
}

.sv-theme .login-box select.form-control {
    display: block;
    /* The enhancement script gives credential inputs the .sv-field-input
       build (42px tall, tinted rest); the profile <select> is not
       enhanced, so match it to the same presence explicitly. */
    height: 42px;
    padding: 0 13px;
    background-color: var(--sv-bg-input);
    border: 1px solid var(--sv-border);
    border-radius: 8px;
    color: var(--sv-text);
    font-size: 13.5px;
    transition: border-color 0.16s ease-out, box-shadow 0.16s ease-out, background-color 0.16s ease-out;
}

.sv-theme .login-box select.form-control:hover {
    border-color: var(--sv-border-strong);
}

.sv-theme .login-box select.form-control:focus {
    border-color: var(--sv-primary);
    box-shadow: 0 0 0 3px rgba(var(--sv-primary-rgb), 0.12);
    background-color: var(--sv-bg-white);
    outline: none;
}

/* The login card — reference proportions: 380px, tight radius, one soft
   deep shadow, hairline border. overflow:hidden clips the banner into
   the rounded top corners. The doubled class raises specificity above
   the generic `.sv-theme .card` rule further down this file, which
   would otherwise clamp the radius to --sv-radius (10px). */
.sv-theme .login-box.login-box {
    width: 100%;
    max-width: 380px;
    background-color: var(--sv-bg-white);
    border: 1px solid var(--sv-border);
    border-radius: 14px;
    box-shadow: 0 6px 24px rgba(41, 37, 36, 0.08);
    overflow: hidden;
    animation: sv-card-in 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.sv-theme .login-box > .card-body {
    padding: 24px 32px 28px;
}

@keyframes sv-card-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ── Brand banner — injected as the first child of `.login-box`, so it
      bleeds edge-to-edge and the card-body content follows below. ── */
/* ── Login banner — aurora sweep instead of a flat teal strip, so the
      card's brand moment matches the logo tile + primary buttons. ── */
.sv-login-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 20px 24px;
    background: var(--sv-login-banner);
    background-image: linear-gradient(120deg, #0F766E 0%, #0D9488 45%, #0891B2 100%);
    color: #fff;
}

.sv-login-banner-icon {
    width: 34px;
    height: 34px;
    min-width: 34px;
    border-radius: 9px;
    background: rgba(255, 255, 255, 0.14);
    border: 1px solid rgba(255, 255, 255, 0.22);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
}

/* Uploaded / theme mark on the gradient banner: a white hairline ring
   separates the tile from the banner's own gradient. */
.sv-login-banner-logo {
    height: 34px;
    width: auto;
    max-width: 160px;
    object-fit: contain;
    border-radius: 9px;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.35);
    flex-shrink: 0;
}

.sv-login-banner-name {
    font-size: 16px;
    font-weight: 650;
    letter-spacing: 0.01em;
}

/* Title — centred; h3 owns the gap to the first field via margin-bottom */
.sv-theme .login-box h3 {
    font-size: 20px;
    font-weight: 800;
    color: var(--sv-text);
    letter-spacing: -0.01em;
    text-align: center;
    margin: 4px 0 18px;
}

/* Labels — quiet, above the field */
.sv-theme .login-box label,
.sv-theme .login-box .form-label {
    font-size: 12px;
    color: var(--sv-text-secondary);
    margin-bottom: 4px;
}

/* ── In-field icons & password reveal — the enhancement script wraps
      each credential input in its OWN .sv-field span. It must never
      annotate the framework's form-group/row wrappers: those are
      Bootstrap grid rows (hidden col-md-3 label + col-md-12 input),
      and touching their display/position misaligns the fields. The
      span holds only the input, so the icon's top:50% always lands on
      the input's centre line. ── */
.sv-field {
    position: relative;
    display: block;
    /* The field rows ship `mb-2` spacing utilities that 404 with the
       Rocker sheet, so the vertical rhythm lives here instead. */
    margin-bottom: 16px;
}

.sv-field-input {
    height: 42px;
    padding-left: 38px;
    border-radius: 8px;
    /* Framework inputs arrive WITHOUT a type attribute, so width is
       locked separately on select + .sv-field-input (see neutralise
       block above). */
}

/* The profile <select> ships with an inline `margin-bottom: 3em` — a
   leftover from the Default era that leaves a hole in the card. Needs
   !important (inline style), and an empty list should vanish entirely. */
.sv-theme .login-box select.form-control {
    margin-bottom: 16px !important;
}

.sv-theme .login-box select.form-control:empty {
    display: none;
}

/* Framework language links row (ENG | 繁 | 简) — keep it (only language
   switcher on anonymous pages) but quiet, centred under the subtitle. */
.sv-theme .login-box .title {
    font-size: 12px;
    margin: 0 0 20px;
}

.sv-theme .login-box .title a {
    color: var(--sv-text-muted);
    text-decoration: none;
}

.sv-theme .login-box .title a:hover {
    color: var(--sv-text-link);
    text-decoration: underline;
}

.sv-field-input--reveal {
    padding-right: 42px;
}

.sv-field-icon {
    position: absolute;
    left: 13px;
    top: 50%;
    transform: translateY(-50%);
    color: rgba(120, 113, 108, 0.65);
    font-size: 13px;
    pointer-events: none;
}

.sv-field-reveal {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    width: 30px;
    height: 30px;
    border: none;
    background: transparent;
    border-radius: 7px;
    color: var(--sv-text-muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    transition: var(--sv-transition);
}

.sv-field-reveal:hover {
    color: var(--sv-primary-dark);
    background: var(--sv-bg-hover);
}

/* ── Submit — the page's single primary action. `.btn-rounded` is the
      base build's class; the bare `button[type=submit]` selector is a
      safety net in case the framework drops the utility class. ── */
.sv-theme .login-box .btn-rounded,
.sv-theme .login-box form button[type="submit"] {
    display: block;
    width: 100%;
    padding: 11px 24px;
    font-size: 15px;
    font-weight: 600;
    border-radius: 8px;
    background: var(--sv-gradient-brand);
    border-color: var(--sv-primary);
    color: #fff;
    box-shadow: var(--sv-shadow-brand);
    transition: var(--sv-transition);
}

.sv-theme .login-box .btn-rounded:hover,
.sv-theme .login-box .btn-rounded:focus,
.sv-theme .login-box form button[type="submit"]:hover,
.sv-theme .login-box form button[type="submit"]:focus {
    background: var(--sv-gradient-brand);
    border-color: var(--sv-primary-dark);
    color: #fff;
    opacity: 1;
    filter: brightness(0.95);
    box-shadow: var(--sv-shadow-brand-lg);
}

/* Remember-me row, if the framework renders one */
.sv-theme .login-box .form-check {
    font-size: 13px;
    color: var(--sv-text-secondary);
}

.sv-theme .login-register > footer {
    /* Version string, fixed to the viewport bottom by the framework.
       The reference login has no page footer — hide it; the version is
       visible on every authenticated page's footer anyway. */
    display: none;
}

/* ═══════════════════════════════════════════════════════════
   AIChatBotPage — layout unification. The chat shell sits in the
   standard .card > .card-body structure like every other page
   (20px gutter, visible footer). The view wraps .chat-app in
   .card.chat-card-shell > .card-body.chat-card-body; the module's
   chatbot.css ships the shell neutralized, this theme opts in.
   Height comes from the theme's definite flex chain instead of the
   module's calc(100vh - X) arithmetic, so the page is exactly one
   viewport by construction — no load-time scrollbar.
   Beats `.container-fluid > * { flex-shrink: 0 }` by specificity.
   ═══════════════════════════════════════════════════════════ */
.sv-theme .page-content.container-fluid > .chat-card-shell {
    flex: 1 1 0;                 /* fill the leftover height; footer sinks to the bottom */
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;            /* clip .chat-app into the card's rounded corners */
    background: var(--sv-bg-card);
    border: 1px solid var(--sv-border);
    border-radius: var(--sv-radius);
    box-shadow: var(--sv-shadow-sm);
}

/* card-body keeps no padding: the chat shell has its own navbar/sidebar
   border system — a full-bleed fit avoids double gutters. */
.sv-theme .chat-card-shell > .chat-card-body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 0;
}

/* Override the module's calc(100vh - offset) base height: inside the
   card the shell just fills whatever the flex chain hands down. */
.sv-theme .chat-card-body > .chat-app {
    height: auto;
    flex: 1 1 auto;
    min-height: 0;
}

/* Custom app view / module embed containers (UseCustomView apps) take the
   same flex slot as .chat-app when the default chat UI is hidden. */
.sv-theme .chat-card-body > #custom-app-view-container,
.sv-theme .chat-card-body > #module-embed-container {
    height: auto;
    flex: 1 1 auto;
    min-height: 0;
}

/* Re-cast the chat module's hardcoded indigo moments in aurora
   teal (aligned with AI1). The module's design-tokens.css already
   bridges every --color-* token to this theme's --sv-* values, so
   only the literals need re-declaring. `--chat-max` is nudged up:
   with the page header gone there is room for a wider reading
   column. */
.sv-theme .page-content:has(.chat-app) {
    --user-msg-bg: rgba(var(--sv-primary-rgb), 0.07);
    --think-text: #0F766E;
    --greeting-bg: rgba(var(--sv-primary-rgb), 0.05);
    --greeting-border: #99E0D8;
    --chat-max: 880px;
    --input-max: 880px;
}

/* ═══════════════════════════════════════════════════════════
   RESPONSIVE — under 992px the inline nav becomes a slide-down
   panel: .sv-topbar-nav itself is re-positioned below the header
   and revealed via body.sv-nav-open (template.js). Groups turn into
   accordions there — hover-open is already desktop-only above.
   ═══════════════════════════════════════════════════════════ */
@media (max-width: 991.98px) {
    .sv-menu-toggle {
        display: flex;
    }

    /* Keep the logo, drop the wordmark — the hamburger + lang + user
       chips already claim most of a narrow header. */
    .sv-header-title { display: none; }

    .sv-topbar-nav {
        position: fixed;
        top: var(--sv-header-height);
        left: 0;
        right: 0;
        height: auto;
        max-height: calc(100vh - var(--sv-header-height));
        overflow-y: auto;
        overflow-x: hidden;
        display: none;
        margin: 0;
        padding: 8px 12px 16px;
        background: var(--sv-bg-topbar);
        border-bottom: 1px solid var(--sv-border);
        box-shadow: var(--sv-shadow-lg);
        z-index: 1045;
    }

    body.sv-nav-open .sv-topbar-nav {
        display: block;
        animation: sv-nav-in 0.2s cubic-bezier(0.22, 1, 0.36, 1);
    }

    .sv-nav {
        flex-direction: column;
        height: auto;
        gap: 2px;
        flex-wrap: nowrap;
    }

    .sv-nav-item {
        display: block;
    }

    .sv-nav-link {
        height: auto;
        width: 100%;
        padding: 10px 12px;
        border-radius: var(--sv-radius-sm);
        justify-content: flex-start;
    }

    /* Underline indicator makes no sense inside a vertical list —
       swap it for a tinted background. */
    .sv-nav-item.mm-active > .sv-nav-link::after,
    .sv-nav-link.active::after,
    .sv-nav-group--active > .sv-nav-trigger::after {
        display: none;
    }

    .sv-nav-item.mm-active > .sv-nav-link,
    .sv-nav-link.active,
    .sv-nav-group--active > .sv-nav-trigger {
        background: var(--sv-primary-bg);
        color: var(--sv-primary-dark);
    }

    /* Group panel = accordion row under its trigger */
    .sv-nav-dropdown {
        position: static;
        min-width: 0;
        border: none;
        border-left: 1px solid var(--sv-border);
        border-radius: 0;
        box-shadow: none;
        background: transparent;
        padding: 2px 0 4px 10px;
        margin: 2px 0 4px 16px;
    }
}

@keyframes sv-nav-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Dimmed backdrop under the mobile nav panel (appended by template.js).
   z-index MUST stay below the topbar's stacking context (100): the
   slide-down panel is a CHILD of .sv-topbar, so its own z-index only
   ranks inside that context — an overlay above 100 paints over the
   panel and swallows its clicks (the "menu opens but is unclickable"
   bug). 90 keeps it above the unpositioned page content instead. */
.sv-nav-overlay {
    position: fixed;
    inset: 0;
    top: var(--sv-header-height);
    background: rgba(41, 37, 36, 0.35);
    z-index: 90;
    animation: sv-overlay-in 0.16s ease-out;
}

@keyframes sv-overlay-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@media (max-width: 768px) {
    .sv-theme .page-content.container-fluid {
        padding: 12px;
    }

    /* Re-cancel the (now smaller) container padding */
    .sv-theme .sv-footer {
        margin: 12px -12px -12px;
        margin-top: auto;
        padding: 10px 12px;
        text-align: center;
    }
}

/* ═══════════════════════════════════════════════════════════
   SCROLLBAR — thin & warm
   ═══════════════════════════════════════════════════════════ */
.sv-theme ::-webkit-scrollbar {
    width: 5px;
    height: 5px;
}

.sv-theme ::-webkit-scrollbar-track {
    background: transparent;
}

.sv-theme ::-webkit-scrollbar-thumb {
    background: var(--sv-border-strong);
    border-radius: 3px;
}

.sv-theme ::-webkit-scrollbar-thumb:hover {
    background: var(--sv-text-muted);
}

/* ═══════════════════════════════════════════════════════════
   FLAG ICONS (no longer used — replaced by text labels)
   ═══════════════════════════════════════════════════════════ */
.sv-theme .flag-icon {
    display: none;
}

/* ═══════════════════════════════════════════════════════════
   MICRO-INTERACTIONS & POLISH
   ═══════════════════════════════════════════════════════════ */

/* Page content entrance — fade + small rise, once */
.sv-page-content {
    animation: sv-page-in 0.26s ease-out;
}

@keyframes sv-page-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Language switcher — ghost pill button */
.sv-lang-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: 999px;
    border: 1px solid var(--sv-border);
    background: var(--sv-bg-white);
    transition: var(--sv-transition);
    text-decoration: none;
}

.sv-lang-toggle:hover {
    border-color: var(--sv-primary);
    background: var(--sv-primary-bg);
}

.sv-lang-toggle::after {
    display: none;
}

.sv-lang-icon {
    font-size: 14px;
    color: var(--sv-primary);
}

.sv-lang-label {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--sv-text);
    line-height: 1;
}

.sv-lang-arrow {
    font-size: 9px;
    color: var(--sv-text-muted);
    transition: transform 0.16s ease-out;
}

.sv-lang-toggle[aria-expanded="true"] .sv-lang-arrow {
    transform: rotate(180deg);
}

/* Language dropdown items */
.sv-dropdown .dropdown-item.active {
    background: var(--sv-primary-bg);
    color: var(--sv-primary-dark);
}

.sv-lang-item-label {
    flex: 1;
}

.sv-lang-check {
    font-size: 11px;
    color: var(--sv-primary);
}

/* ═══════════════════════════════════════════════════════════
   ACCENT CUSTOMIZER — header palette button + dropdown panel.
   The button sits in the right tool cluster (language ↔ user);
   the dot on its rim always shows the live accent. The panel
   offers curated presets (all AA-safe under white text), the
   native colour input for a custom hue, and a reset. Persistence
   is localStorage (client-only preference — see js/accent.js).
   ═══════════════════════════════════════════════════════════ */
.sv-accent-toggle {
    width: 34px;
    height: 34px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    border: 1px solid var(--sv-border);
    background: var(--sv-bg-white);
    color: var(--sv-text-secondary);
    font-size: 14px;
    cursor: pointer;
    position: relative;
    transition: var(--sv-transition);
}

.sv-accent-toggle:hover,
.sv-accent-toggle[aria-expanded="true"] {
    border-color: var(--sv-primary);
    color: var(--sv-primary);
    background: var(--sv-primary-bg);
}

/* Live accent dot riding the button rim */
.sv-accent-dot {
    position: absolute;
    top: -3px;
    right: -3px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--sv-primary);
    border: 2px solid var(--sv-bg-topbar);
    pointer-events: none;
}

.sv-accent-panel {
    min-width: 244px;
    padding: 12px;
}

.sv-accent-title {
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--sv-text-muted);
    margin-bottom: 10px;
}

.sv-accent-swatches {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 8px;
    justify-items: center;
    margin-bottom: 12px;
}

.sv-accent-swatch {
    width: 20px;
    height: 20px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--sw);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.10);
    cursor: pointer;
    transition: transform 0.12s ease-out, box-shadow 0.12s ease-out;
}

.sv-accent-swatch:hover {
    transform: scale(1.18);
}

/* Selected preset: white gap + own-colour ring */
.sv-accent-swatch.active {
    box-shadow: 0 0 0 2px var(--sv-bg-white), 0 0 0 4px var(--sw);
}

.sv-accent-custom {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 2px 2px;
    border-top: 1px solid var(--sv-border-light);
    font-size: 12.5px;
    color: var(--sv-text-secondary);
    cursor: pointer;
}

.sv-accent-custom input[type="color"] {
    width: 36px;
    height: 26px;
    padding: 2px;
    border: 1px solid var(--sv-border-input);
    border-radius: 6px;
    background: var(--sv-bg-input);
    cursor: pointer;
}

.sv-accent-reset {
    margin-top: 10px;
    width: 100%;
}

/* Focus-visible accessibility ring */
.sv-theme a:focus-visible,
.sv-theme button:focus-visible {
    outline: 2px solid var(--sv-primary);
    outline-offset: 2px;
    border-radius: var(--sv-radius-sm);
}

/* The base theme's Bootstrap build ships an orange focus ring —
   rgba(251,150,120,.25) — on every focusable control. A mouse click fires
   :focus but NOT :focus-visible, so the rule above never catches it and the
   orange shows through. Restate the ring in the theme's own accent. */
.sv-theme .btn-close:focus,
.sv-theme .btn:focus,
.sv-theme .page-link:focus,
.sv-theme .accordion-button:focus,
.sv-theme .btn-check:focus + .btn {
    box-shadow: 0 0 0 0.2rem rgba(var(--sv-primary-rgb), 0.18);
}

.sv-theme .form-range:focus::-webkit-slider-thumb {
    box-shadow: 0 0 0 0.2rem rgba(var(--sv-primary-rgb), 0.18);
}

.sv-theme .form-range:focus::-moz-range-thumb {
    box-shadow: 0 0 0 0.2rem rgba(var(--sv-primary-rgb), 0.18);
}

/* Selection color */
.sv-theme ::selection {
    background: rgba(var(--sv-primary-rgb), 0.14);
    color: var(--sv-text);
}

/* ═══════════════════════════════════════════════════════════
   BUTTONS — full semantic matrix, five states each.
   Focus ring: 3px soft teal halo. Disabled: opacity 0.45.
   ═══════════════════════════════════════════════════════════ */
.sv-theme .btn {
    border-radius: var(--sv-radius-sm);
    transition: var(--sv-transition);
    box-shadow: none;
    font-weight: 500;
    letter-spacing: 0.01em;
}

.sv-theme .btn:disabled,
.sv-theme .btn.disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.sv-theme .btn:focus-visible {
    box-shadow: 0 0 0 3px rgba(var(--sv-primary-rgb), 0.18);
}

/* Small buttons — table row actions, toolbar controls */
.sv-theme .btn-sm {
    border-radius: 6px;
    padding: 5px 14px;
    font-size: 13px;
    line-height: 1.5;
}

/* ── Primary — aurora gradient + brand shadow; hover deepens via a
      brightness step + lift so all five states stay distinct. ── */
.sv-theme .btn-primary {
    background: var(--sv-gradient-brand);
    border-color: var(--sv-primary);
    color: #fff;
    box-shadow: var(--sv-shadow-brand);
}

.sv-theme .btn-primary:hover,
.sv-theme .btn-primary:focus {
    background: var(--sv-gradient-brand);
    border-color: var(--sv-primary-dark);
    color: #fff;
    filter: brightness(0.95) saturate(1.05);
    box-shadow: var(--sv-shadow-brand-lg);
    transform: translateY(-1px);
}

.sv-theme .btn-primary:active,
.sv-theme .btn-primary.active {
    background: var(--sv-primary-active) !important;
    border-color: var(--sv-primary-active) !important;
    filter: none;
    transform: none;
    box-shadow: none !important;
}

.sv-theme .btn-primary:disabled,
.sv-theme .btn-primary.disabled {
    background: var(--sv-primary);
    border-color: var(--sv-primary);
    filter: none;
    transform: none;
    box-shadow: none;
}

/* ── Secondary (white + border) ── */
.sv-theme .btn-secondary {
    background: var(--sv-bg-white);
    border-color: var(--sv-border-strong);
    color: var(--sv-text);
    box-shadow: var(--sv-shadow-sm);
}

.sv-theme .btn-secondary:hover,
.sv-theme .btn-secondary:focus {
    background: var(--sv-primary-bg);
    border-color: var(--sv-primary);
    color: var(--sv-primary-dark);
    box-shadow: none;
}

.sv-theme .btn-secondary:active,
.sv-theme .btn-secondary.active {
    background: var(--sv-bg-inset) !important;
    border-color: var(--sv-primary) !important;
    color: var(--sv-primary-dark) !important;
}

/* ── Semantic solid ── */
.sv-theme .btn-success {
    background: var(--sv-success);
    border-color: var(--sv-success);
    color: #fff;
    box-shadow: 0 2px 6px rgba(5, 150, 105, 0.25);
}

.sv-theme .btn-success:hover,
.sv-theme .btn-success:focus {
    background: #047857;
    border-color: #047857;
    color: #fff;
    box-shadow: 0 4px 12px rgba(5, 150, 105, 0.30);
}

.sv-theme .btn-danger {
    background: var(--sv-danger);
    border-color: var(--sv-danger);
    color: #fff;
    box-shadow: 0 2px 6px rgba(225, 29, 72, 0.25);
}

.sv-theme .btn-danger:hover,
.sv-theme .btn-danger:focus {
    background: #BE123C;
    border-color: #BE123C;
    color: #fff;
    box-shadow: 0 4px 12px rgba(225, 29, 72, 0.30);
}

.sv-theme .btn-warning {
    background: var(--sv-warning);
    border-color: var(--sv-warning);
    color: #fff;
    box-shadow: 0 2px 6px rgba(217, 119, 6, 0.22);
}

.sv-theme .btn-warning:hover,
.sv-theme .btn-warning:focus {
    background: #B45309;
    border-color: #B45309;
    color: #fff;
    box-shadow: 0 4px 12px rgba(217, 119, 6, 0.28);
}

.sv-theme .btn-info {
    background: var(--sv-info);
    border-color: var(--sv-info);
    color: #fff;
    box-shadow: 0 2px 6px rgba(2, 132, 199, 0.22);
}

.sv-theme .btn-info:hover,
.sv-theme .btn-info:focus {
    background: #0369A1;
    border-color: #0369A1;
    color: #fff;
    box-shadow: 0 4px 12px rgba(2, 132, 199, 0.28);
}

/* ── Outline variants ── */
.sv-theme .btn-outline-primary {
    color: var(--sv-primary-dark);
    border-color: var(--sv-primary);
    background: transparent;
}

.sv-theme .btn-outline-primary:hover,
.sv-theme .btn-outline-primary:focus {
    background: var(--sv-gradient-brand);
    border-color: var(--sv-primary);
    color: #fff;
    box-shadow: var(--sv-shadow-brand);
}

.sv-theme .btn-outline-secondary {
    color: var(--sv-text-secondary);
    border-color: var(--sv-border-strong);
    background: transparent;
}

.sv-theme .btn-outline-secondary:hover,
.sv-theme .btn-outline-secondary:focus {
    background: var(--sv-bg-hover);
    border-color: var(--sv-text-secondary);
    color: var(--sv-text);
}

/* Outline semantic variants keep their own soft tint on hover
   (the solid fill belongs to the solid buttons — the two families
   must read apart). */
.sv-theme .btn-outline-success {
    color: var(--sv-success);
    border-color: var(--sv-success);
    background: transparent;
}

.sv-theme .btn-outline-success:hover,
.sv-theme .btn-outline-success:focus {
    background: var(--sv-success-bg);
    border-color: var(--sv-success);
    color: #047857;
}

.sv-theme .btn-outline-danger {
    color: var(--sv-danger);
    border-color: var(--sv-danger);
    background: transparent;
}

.sv-theme .btn-outline-danger:hover,
.sv-theme .btn-outline-danger:focus {
    background: var(--sv-danger-bg);
    border-color: var(--sv-danger);
    color: #BE123C;
}

.sv-theme .btn-outline-warning {
    color: var(--sv-warning);
    border-color: var(--sv-warning);
    background: transparent;
}

.sv-theme .btn-outline-warning:hover,
.sv-theme .btn-outline-warning:focus {
    background: var(--sv-warning-bg);
    border-color: var(--sv-warning);
    color: #B45309;
}

.sv-theme .btn-outline-info {
    color: var(--sv-info);
    border-color: var(--sv-info);
    background: transparent;
}

.sv-theme .btn-outline-info:hover,
.sv-theme .btn-outline-info:focus {
    background: var(--sv-info-bg);
    border-color: var(--sv-info);
    color: #0369A1;
}

/* ── Ghost / text & link buttons ── */
.sv-theme .btn-link {
    color: var(--sv-text-link);
    text-decoration: none;
}

.sv-theme .btn-link:hover,
.sv-theme .btn-link:focus {
    color: var(--sv-primary-active);
    text-decoration: underline;
}

/* Icon buttons — toolbars (.btn-icon from layout, .icon-btn from
   module pages) */
.sv-theme .icon-btn,
.sv-theme .btn.btn-icon {
    background: transparent;
    border: none;
    color: var(--sv-text-secondary);
    border-radius: var(--sv-radius-sm);
}

.sv-theme .icon-btn:hover,
.sv-theme .btn.btn-icon:hover {
    background: var(--sv-bg-hover);
    color: var(--sv-primary-dark);
}

/* ═══════════════════════════════════════════════════════════
   GLOBAL OVERRIDES — form controls, tables, cards, alerts
   Applied across all pages sharing this theme shell.
   ═══════════════════════════════════════════════════════════ */

/* ── Form controls — quiet resting field, white + teal on focus ──
   background-color, never the `background` shorthand: the shorthand also
   resets background-repeat to `repeat`, and Bootstrap's .form-select chevron
   and .is-invalid warning glyph rely on the base rule's `no-repeat`. With it
   reset, those SVGs tile across the whole field. */
.sv-theme .form-control,
.sv-theme .form-select {
    background-color: var(--sv-bg-input);
    border: 1px solid var(--sv-border-input);
    border-radius: var(--sv-radius-sm);
    color: var(--sv-text);
    font-size: 13.5px;
    box-shadow: none;
    transition: border-color 0.16s ease-out, box-shadow 0.16s ease-out, background-color 0.16s ease-out;
}

.sv-theme .form-control:hover,
.sv-theme .form-select:hover {
    border-color: var(--sv-border-strong);
}

.sv-theme .form-control:focus,
.sv-theme .form-select:focus {
    border-color: var(--sv-primary);
    box-shadow: 0 0 0 3px rgba(var(--sv-primary-rgb), 0.12);
    background-color: var(--sv-bg-white);   /* longhand — see note above */
}

.sv-theme .form-control::placeholder {
    color: var(--sv-text-muted);
}

.sv-theme .form-control.is-invalid,
.sv-theme .form-select.is-invalid {
    border-color: var(--sv-danger);
    box-shadow: none;
}

.sv-theme .form-control.is-invalid:focus,
.sv-theme .form-select.is-invalid:focus {
    box-shadow: 0 0 0 3px rgba(225, 29, 72, 0.12);
}

.sv-theme .form-check-input {
    border-color: var(--sv-border-strong);
    box-shadow: none;
}

.sv-theme .form-check-input:checked {
    background-color: var(--sv-primary);
    border-color: var(--sv-primary);
}

.sv-theme .form-check-input:focus {
    box-shadow: 0 0 0 3px rgba(var(--sv-primary-rgb), 0.12);
    border-color: var(--sv-primary);
}

/* Switch thumb: the Default base theme hardcodes an ORANGE dot for
   .form-switch .form-check-input:focus (fill='%23fdcbbc'), which flashes
   through on every click under this theme. Re-pin it to neutral grey, and
   white when checked. data-URIs cannot reference CSS variables, so these are
   literal colours by necessity — the same exception Default itself makes.
   Order matters: :checked must come AFTER :focus (equal specificity) so a
   checked switch that still holds focus keeps the white thumb. */
.sv-theme .form-switch .form-check-input:focus {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");
}

.sv-theme .form-switch .form-check-input:checked {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='white'/%3e%3c/svg%3e");
}

/* ═══════════════════════════════════════════════════════════
   DROPDOWNS — Bootstrap's default blue selection, everywhere
   Three separate blue sources, all repainted with the aurora accent:
     · Bootstrap .dropdown-item :active/.active  → solid #0d6efd
     · select2 (bootstrap-5 skin) chips + rows   → solid #0d6efd
     · native <option> checked                   → UA blue
   These live in the theme rather than in module CSS because every AI
   module page is full of selects; a page-level fix would have to be
   repeated in a dozen stylesheets.
   ═══════════════════════════════════════════════════════════ */

/* ── Bootstrap dropdown menus ── */
.sv-theme .dropdown-menu {
    background: var(--sv-bg-white);
    border: 1px solid var(--sv-border);
    border-radius: var(--sv-radius);
    box-shadow: var(--sv-shadow-lg);
    padding: 6px;
}

.sv-theme .dropdown-item {
    border-radius: var(--sv-radius-sm);
    color: var(--sv-text);
}

.sv-theme .dropdown-item:hover,
.sv-theme .dropdown-item:focus {
    background-color: var(--sv-bg-hover);
    color: var(--sv-text);
}

.sv-theme .dropdown-item.active,
.sv-theme .dropdown-item:active {
    background-color: rgba(var(--sv-primary-rgb), 0.10);
    color: var(--sv-primary);
    font-weight: 500;
}

/* ── Native <select> options (Firefox/Chromium honour these) ── */
.sv-theme select.form-select option:checked,
.sv-theme select.form-control option:checked {
    background-color: rgba(var(--sv-primary-rgb), 0.14);
    color: var(--sv-primary);
}

/* ── select2 (bootstrap-5 skin) ──
   The skin is loaded from Themes/Default/plugins/select2 for every page, so
   its selectors are matched shape-for-shape here; equal specificity, and
   this file loads afterwards. The dropdown panel is appended to <body>, so
   it sits outside .sv-theme — those rules stay unscoped on purpose. */
.sv-theme .select2-container--bootstrap-5 .select2-selection {
    border-color: var(--sv-border-input);
    border-radius: var(--sv-radius-sm);
    background-color: var(--sv-bg-input);
    /* skin 默认 1rem，比本主题表单控件的 13.5px 大一档，
       会让 select2 包裹的下拉（如 LLM 模型）跟兄弟输入框字号不齐 */
    font-size: 13.5px;
}

.sv-theme .select2-container--bootstrap-5.select2-container--focus .select2-selection,
.sv-theme .select2-container--bootstrap-5.select2-container--open .select2-selection {
    border-color: var(--sv-primary);
    box-shadow: 0 0 0 3px rgba(var(--sv-primary-rgb), 0.12);
}

/* multi-select chips — pill, accent tint, no solid blue */
.sv-theme .select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice {
    background-color: rgba(var(--sv-primary-rgb), 0.08);
    border: 1px solid rgba(var(--sv-primary-rgb), 0.25);
    color: var(--sv-primary);
    border-radius: 999px;
    padding: 3px 10px;
    font-size: 13.5px;
    font-weight: 500;
}

.sv-theme .select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice .select2-selection__choice__remove {
    filter: none;
    opacity: 0.6;
}

.sv-theme .select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice .select2-selection__choice__remove:hover {
    opacity: 1;
}

/* panel + rows — appended to <body>, hence no .sv-theme prefix */
.select2-container--bootstrap-5 .select2-dropdown {
    border-color: var(--sv-border, #E7E2DA);
    border-radius: var(--sv-radius, 10px);
    box-shadow: 0 8px 28px rgba(41, 37, 36, 0.12);
    overflow: hidden;
}

/* 面板内搜索框与选项行同样对齐 13.5px（skin 写死 1rem）。本页 skin 由 View 在
   主题之后注入，同形选择器会输，故叠一个 .select2-container 抬高优先级，
   与加载顺序解耦 */
.select2-container.select2-container--bootstrap-5 .select2-dropdown .select2-search .select2-search__field,
.select2-container.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option {
    font-size: 13.5px;
}

.select2-container--bootstrap-5 .select2-dropdown .select2-search .select2-search__field:focus {
    border-color: var(--sv-primary, #0D9488);
    box-shadow: 0 0 0 3px rgba(var(--sv-primary-rgb), 0.12);
}

.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--highlighted {
    background-color: rgba(var(--sv-primary-rgb), 0.08);
    color: var(--sv-primary, #0D9488);
}

.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--selected,
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option[aria-selected="true"]:not(.select2-results__option--highlighted) {
    background-color: rgba(var(--sv-primary-rgb), 0.14);
    color: var(--sv-primary, #0D9488);
    font-weight: 500;
}

/* ── Cards — float on the warm canvas: hairline + resting shadow-sm,
      one step of lift on hover so interactive grids feel alive. ── */
.sv-theme .card {
    background: var(--sv-bg-card);
    border: 1px solid var(--sv-border);
    border-radius: var(--sv-radius);
    box-shadow: var(--sv-shadow-sm);
}

.sv-theme .card-header {
    /* A whisper of the inset tone separates the header band from the
       white body without a visible seam change. */
    background: rgba(240, 237, 230, 0.45);
    border-bottom: 1px solid var(--sv-border-light);
}

.sv-theme .card-footer {
    background: transparent;
    border-top: 1px solid var(--sv-border-light);
}

/* ── Tables — warm hairlines, stone uppercase header ── */
.sv-theme .table {
    --bs-table-bg: transparent;
    border-color: var(--sv-border);
}

.sv-theme .table > :not(caption) > * > * {
    border-bottom-color: var(--sv-border-light);
}

.sv-theme .table > thead > * > * {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--sv-text-secondary);
    /* Inset tone anchors the header band; the strong border below
       separates it from the rows. */
    background-color: var(--sv-bg-inset);
    border-bottom: 2px solid var(--sv-border-strong);
}

.sv-theme .table-hover > tbody > tr:hover > * {
    background: var(--sv-bg-hover);
}

/* Zebra rows read in pairs; the hover wash still wins on top. */
.sv-theme .table-striped > tbody > tr:nth-of-type(odd) > * {
    --bs-table-bg: rgba(41, 37, 36, 0.023);
    background-color: rgba(41, 37, 36, 0.023);
    color: var(--sv-text);
}

/* Selected / active rows carry the primary tint so multi-select
   tables give unambiguous feedback. */
.sv-theme .table > tbody > tr.table-active > *,
.sv-theme .table > tbody > tr.selected > * {
    background-color: rgba(var(--sv-primary-rgb), 0.09);
    color: var(--sv-text);
}

/* ── Alerts / Notifications — left color-bar + tinted bg ──
   Solid tints, not 4% alpha: an alert has to stay legible on a white card. */
.sv-theme .alert {
    border: 1px solid var(--sv-border-light);
    border-left: 3px solid transparent;
    border-radius: var(--sv-radius-sm);
    font-size: 13px;
    box-shadow: none;
}

.sv-theme .alert-danger {
    border-color: #FECDD3;
    border-left-color: var(--sv-danger);
    background: #FFF1F2;
    color: #9F1239;
}

.sv-theme .alert-warning {
    border-color: #FDE68A;
    border-left-color: var(--sv-warning);
    background: #FFFBEB;
    color: #92400E;
}

.sv-theme .alert-success {
    border-color: #A7F3D0;
    border-left-color: var(--sv-success);
    background: #ECFDF5;
    color: #065F46;
}

.sv-theme .alert-info {
    border-color: #BAE6FD;
    border-left-color: var(--sv-info);
    background: #F0F9FF;
    color: #075985;
}

/* ── Badges — pill ── */
.sv-theme .badge {
    border-radius: 999px;
    font-weight: 500;
    font-size: 11px;
    padding: 3px 9px;
}

/* Neutral badge default — a tinted pill instead of Bootstrap's heavy
   solid grey; contextual .bg-* / .text-bg-* classes still override. */
.sv-theme .badge.bg-secondary {
    background-color: var(--sv-bg-inset) !important;
    border: 1px solid var(--sv-border);
    color: var(--sv-text-secondary) !important;
}

/* ── Code — inline code and pre blocks gain the warm inset surface,
      keeping markdown/chat code legible on white cards. ── */
.sv-theme code {
    color: #BE185D;
    background-color: var(--sv-bg-code);
    border-radius: 4px;
    padding: 1px 5px;
    font-family: var(--sv-font-mono);
    font-size: 0.9em;
}

.sv-theme pre {
    background-color: var(--sv-bg-code);
    border: 1px solid var(--sv-border-light);
    border-radius: var(--sv-radius-sm);
    padding: 12px 14px;
}

.sv-theme pre code {
    background: transparent;
    padding: 0;
    color: inherit;
}

/* ── kbd — matches the code surface language ── */
.sv-theme kbd {
    background-color: #44403C;
    border-radius: 5px;
    padding: 2px 6px;
}

/* ── Modals — floating surface; header/footer get the faintest inset
      tone so the three zones of a dialog read apart. ── */
.sv-theme .modal-content {
    background: var(--sv-bg-white);
    border: 1px solid var(--sv-border);
    border-radius: var(--sv-radius-lg);
    box-shadow: var(--sv-shadow-xl);
}

.sv-theme .modal-header {
    background: rgba(240, 237, 230, 0.45);
    border-bottom: 1px solid var(--sv-border-light);
}

.sv-theme .modal-footer {
    background: rgba(240, 237, 230, 0.30);
    border-top: 1px solid var(--sv-border-light);
}

.sv-theme .modal-backdrop.show {
    opacity: 0.45;
}

/* ── Offcanvas — same floating-surface language as modals ── */
.sv-theme .offcanvas {
    background: var(--sv-bg-white);
    border-color: var(--sv-border);
    box-shadow: var(--sv-shadow-xl);
}

/* ── Progress — soft 6px rounded bar; the fill carries the aurora
      sweep so quota/usage meters read as brand moments. ── */
.sv-theme .progress {
    background: var(--sv-border-light);
    border-radius: 999px;
    height: 6px;
}

.sv-theme .progress-bar {
    background: var(--sv-gradient-brand);
    border-radius: 999px;
}

/* ── Nav tabs — underline style ── */
.sv-theme .nav-tabs {
    border-bottom: 1px solid var(--sv-border);
}

.sv-theme .nav-tabs .nav-link {
    color: var(--sv-text-secondary);
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    font-size: 13px;
    font-weight: 500;
    padding: 8px 14px;
    transition: color 0.16s ease-out, border-color 0.16s ease-out;
}

.sv-theme .nav-tabs .nav-link:hover {
    color: var(--sv-text);
    border-bottom-color: var(--sv-border-strong);
}

.sv-theme .nav-tabs .nav-link.active {
    color: var(--sv-primary-dark);
    border-bottom-color: var(--sv-primary);
    background: transparent;
    font-weight: 600;
}

/* ── Pagination ── */
.sv-theme .page-link {
    color: var(--sv-text-secondary);
    border-color: var(--sv-border);
    border-radius: var(--sv-radius-sm);
    background: var(--sv-bg-white);
}

.sv-theme .page-link:hover {
    background: var(--sv-primary-bg);
    border-color: var(--sv-primary);
    color: var(--sv-primary-dark);
}

.sv-theme .page-item.active .page-link {
    background: var(--sv-primary);
    border-color: var(--sv-primary);
    color: #fff;
    box-shadow: var(--sv-shadow-brand);
}

.sv-theme .page-item.disabled .page-link {
    background: var(--sv-bg-canvas);
    color: var(--sv-text-light);
}

/* ── Breadcrumb link color ── */
.sv-theme .breadcrumb-item a {
    color: var(--sv-text-secondary);
}

.sv-theme .breadcrumb-item a:hover {
    color: var(--sv-primary);
}

/* ── List group — soft rows ── */
.sv-theme .list-group-item {
    border-color: var(--sv-border-light);
    background: transparent;
}

.sv-theme .list-group-item:hover {
    background: var(--sv-bg-hover);
}

.sv-theme .list-group-item.active {
    background: var(--sv-primary-bg);
    border-color: var(--sv-border-light);
    color: var(--sv-primary-dark);
    font-weight: 600;
}

/* Flush lists (no outer border) get the hover wash too */
.sv-theme .list-group-flush .list-group-item:hover {
    background: var(--sv-bg-hover);
}

/* ── Accordion — inset header chip, tinted open state ── */
.sv-theme .accordion-item {
    background: var(--sv-bg-white);
    border-color: var(--sv-border);
}

.sv-theme .accordion-button {
    background: var(--sv-bg-inset);
    color: var(--sv-text);
}

.sv-theme .accordion-button:not(.collapsed) {
    background: var(--sv-primary-bg);
    color: var(--sv-primary-dark);
    box-shadow: inset 0 -1px 0 var(--sv-border);
}

.sv-theme .accordion-button:focus {
    border-color: var(--sv-primary);
    box-shadow: 0 0 0 3px rgba(var(--sv-primary-rgb), 0.12);
}

/* ── Input group seams — keep addon tones in the surface system ── */
.sv-theme .input-group-text {
    background: var(--sv-bg-inset);
    border-color: var(--sv-border-input);
    color: var(--sv-text-secondary);
}

/* ── Toast (framework) ── */
.sv-theme .jq-toast-single {
    border-radius: var(--sv-radius-sm);
    box-shadow: var(--sv-shadow-lg);
}

/* ═══════════════════════════════════════════════════════════
   FLOATING TOASTS — alerts positioned over page content
   The inline-alert treatment (hairline border, no shadow) disappears
   when the alert floats over a white card, so give the floating variants a
   real surface: white bg, full border, elevation, room for the close button.
   Covers both spellings in use — an app-owned #settingsToastContainer and
   Bootstrap's own .position-fixed utility.
   ═══════════════════════════════════════════════════════════ */
.sv-theme #settingsToastContainer .alert,
.sv-theme .alert-container .alert,
.sv-theme .alert.position-fixed {
    --sv-toast-accent: var(--sv-text-muted);   /* left bar */
    --sv-toast-edge: var(--sv-border);         /* surrounding hairline */
    background: var(--sv-bg-white);
    border: 1px solid var(--sv-toast-edge);
    border-left: 3px solid var(--sv-toast-accent);
    border-radius: var(--sv-radius);
    box-shadow: var(--sv-shadow-xl);
    padding: 12px 38px 12px 14px;
    font-size: 13px;
    line-height: 1.5;
}

/* Severity keeps its meaning here. Required-field validation is raised as
   'danger' at the call sites, so warning is free to stay amber for actual
   warnings instead of being forced red at the theme level. */
.sv-theme #settingsToastContainer .alert-warning,
.sv-theme .alert-container .alert-warning,
.sv-theme .alert-warning.position-fixed {
    --sv-toast-accent: var(--sv-warning);
    --sv-toast-edge: #FDE68A;
    color: #92400E;
}

.sv-theme #settingsToastContainer .alert-danger,
.sv-theme .alert-container .alert-danger,
.sv-theme .alert-danger.position-fixed {
    --sv-toast-accent: var(--sv-danger);
    --sv-toast-edge: #FECDD3;
    color: #9F1239;
}

.sv-theme #settingsToastContainer .alert-success,
.sv-theme .alert-container .alert-success,
.sv-theme .alert-success.position-fixed {
    --sv-toast-accent: var(--sv-success);
    --sv-toast-edge: #A7F3D0;
    color: #065F46;
}

.sv-theme #settingsToastContainer .alert-info,
.sv-theme .alert-container .alert-info,
.sv-theme .alert-info.position-fixed {
    --sv-toast-accent: var(--sv-info);
    --sv-toast-edge: #BAE6FD;
    color: #075985;
}

.sv-theme #settingsToastContainer .btn-close,
.sv-theme .alert.position-fixed .btn-close {
    position: absolute;
    top: 50%;
    right: 10px;
    transform: translateY(-50%);
    width: 10px;
    height: 10px;
    padding: 0;
    background-size: 10px;
    opacity: 0.45;
}

.sv-theme #settingsToastContainer .btn-close:hover,
.sv-theme .alert.position-fixed .btn-close:hover { opacity: 0.8; }

/* ═══════════════════════════════════════════════════════════
   MODULE CARD ENRICHMENT — recognisability pass (v2.1)
   The AI module's interactive cards (.app-card / .tool-card /
   .model-card / .kbv2-kb-card) share one anatomy: icon tile |
   title+desc | footer strip with badges & meta. The module CSS
   keeps them flat white-on-white; this section adds the missing
   layering — gradient card wash, ringed icon tiles, inset footer
   strips, bordered status chips — using ONLY existing class
   names. Every rule carries the .sv-theme prefix so it
   out-specifies the module sheets that load afterwards.
   ═══════════════════════════════════════════════════════════ */

/* Card surface: a whisper of vertical wash so cards stop reading
   as flat white; hover deepens the wash toward the brand hue and
   adds a soft teal ring on top of the module's lift. */
.sv-theme .app-card,
.sv-theme .tool-card,
.sv-theme .model-card,
.sv-theme .kbv2-kb-card {
    background: linear-gradient(180deg, #FFFFFF 0%, #FCFBF7 100%);
    border-color: var(--sv-border);
    box-shadow: var(--sv-shadow-sm);
}

.sv-theme .app-card:hover,
.sv-theme .tool-card:hover,
.sv-theme .model-card:hover,
.sv-theme .kbv2-kb-card:hover {
    background: linear-gradient(180deg, #FFFFFF 0%, #F5FBF9 100%);
    box-shadow: var(--sv-shadow-lg), 0 0 0 3px rgba(var(--sv-primary-rgb), 0.07);
}

/* Icon tiles: hairline ring + soft drop so the artwork sits in a
   visible frame instead of floating on the card. */
.sv-theme .app-icon,
.sv-theme .tool-card-icon,
.sv-theme .model-card-icon,
.sv-theme .kbv2-kb-icon {
    border: 1px solid var(--sv-border);
    box-shadow: 0 2px 6px rgba(41, 37, 36, 0.10), inset 0 0 0 1px rgba(255, 255, 255, 0.55);
    background-image: linear-gradient(145deg, rgba(var(--sv-primary-rgb), 0.16), rgba(6, 182, 212, 0.10));
}

.sv-theme .app-card:hover .app-icon,
.sv-theme .tool-card:hover .tool-card-icon,
.sv-theme .model-card:hover .model-card-icon,
.sv-theme .kbv2-kb-card:hover .kbv2-kb-icon {
    border-color: var(--sv-primary-light);
    box-shadow: 0 3px 10px rgba(var(--sv-primary-rgb), 0.20), inset 0 0 0 1px rgba(255, 255, 255, 0.55);
}

/* Title picks up the brand ink on hover — the whole card reads as
   one clickable object. */
.sv-theme .app-card:hover .app-card-title,
.sv-theme .tool-card:hover .tool-card-title,
.sv-theme .model-card:hover .model-card-title {
    color: var(--sv-primary-dark);
}

/* Footer strip: an inset status band separates badges/meta from the
   card body; margin-top:auto (module) still pins it to the bottom. */
.sv-theme .app-card-foot,
.sv-theme .tool-card-foot,
.sv-theme .model-card-foot {
    margin-top: auto;
    padding: 8px 10px;
    background: linear-gradient(180deg, rgba(240, 237, 230, 0.35), rgba(240, 237, 230, 0.75));
    border-top: 1px solid var(--sv-border-light);
    border-radius: 8px;
}

/* Badges: the icon-only squares gain tint-matched borders so each
   status family reads apart at a glance. */
.sv-theme .type-badge {
    background: var(--sv-bg-inset);
    border-color: var(--sv-border);
    color: var(--sv-text-secondary);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

.sv-theme .classify-badge.unclassified {
    background: var(--sv-success-bg);
    border: 1px solid var(--sv-success-border);
    color: #047857;
}

.sv-theme .classify-badge.restricted {
    background: var(--sv-warning-bg);
    border: 1px solid var(--sv-warning-border);
    color: #B45309;
}

.sv-theme .classify-badge.confidential {
    background: var(--sv-danger-bg);
    border: 1px solid var(--sv-danger-border);
    color: #BE123C;
}

.sv-theme .origin-badge.origin-downloaded {
    background: var(--sv-info-bg);
    border: 1px solid var(--sv-info-border);
    color: #0369A1;
}

.sv-theme .origin-badge.origin-received {
    background: var(--sv-primary-bg);
    border: 1px solid rgba(var(--sv-primary-rgb), 0.30);
    color: var(--sv-primary-dark);
}

/* Model pill: a white chip with hairline so the model name stops
   floating bare in the footer strip. */
.sv-theme .app-foot-model {
    background: var(--sv-bg-white);
    border: 1px solid var(--sv-border);
    border-radius: 999px;
    padding: 2px 10px;
    box-shadow: var(--sv-shadow-sm);
}

.sv-theme .app-foot-model > span {
    font-family: var(--sv-font-mono);
    font-size: 11px;
}

/* Online/offline dots: soft halo in their own colour. */
.sv-theme .tool-card-status .dot,
.sv-theme .model-card-status .dot {
    box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 15%, transparent);
}

/* KB profile pills: same inset-chip language as the type badge. */
.sv-theme .kbv2-ppill {
    background: var(--sv-bg-inset);
    border-color: var(--sv-border);
    color: var(--sv-text-secondary);
}

/* Workspace tabs: inset track + ringed active pill so the selected
   tab reads instantly against the white card. */
.sv-theme .workspace-tabs {
    background: var(--sv-bg-inset);
    border-color: var(--sv-border);
}

.sv-theme .workspace-tab.active {
    background: var(--sv-primary-bg-hover);
    box-shadow: inset 0 0 0 1px rgba(var(--sv-primary-rgb), 0.28);
}

/* Count pill inside the active tab needs a step MORE tint than the
   tab itself or it melts into the track. */
.sv-theme .workspace-tab.active .count {
    background: rgba(var(--sv-primary-rgb), 0.20);
}

/* Search field: resting tint like the theme's form controls. */
.sv-theme .list-search {
    background: var(--sv-bg-input);
}

/* View toggle: the active segment carries the aurora sweep instead
   of the flat ink block. */
.sv-theme .view-toggle button.active {
    background: var(--sv-gradient-brand);
    color: #fff;
}

/* Empty state: the bare glyph becomes a tinted tile. */
.sv-theme .empty-state i {
    width: 88px;
    height: 88px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 36px;
    color: var(--sv-primary);
    background: linear-gradient(145deg, rgba(var(--sv-primary-rgb), 0.12), rgba(6, 182, 212, 0.08));
    border: 1px solid var(--sv-border);
    border-radius: 22px;
    opacity: 1;
}

/* ═══════════════════════════════════════════════════════════
   MOTION SAFETY — respect the user's reduced-motion preference:
   drop entrance/ambient animation, keep instant state changes.
   ═══════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
    .sv-page-content,
    .sv-dropdown,
    .sv-nav-dropdown,
    .sv-theme .login-box,
    .sv-nav-overlay {
        animation: none !important;
    }

    .sv-theme *,
    .sv-theme *::before,
    .sv-theme *::after {
        transition-duration: 0.01ms !important;
    }
}
