/* ASSIDU.ai V2 — Layout Styles (Apple Liquid Glass) */

/* Portal layout: sidebar + main content */
.portal-layout { display: flex; min-height: 100vh; }

/* ===== Sidebar — Liquid Glass panel ===== */
.sidebar {
    position: fixed; left: 0; top: 0; bottom: 0;
    width: var(--sidebar-width);
    background: var(--glass-bg);
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
    border-right: 1px solid var(--glass-border);
    box-shadow: var(--glass-inner-glow), 1px 0 20px rgba(0,0,0,0.04);
    z-index: 100; display: flex; flex-direction: column;
    padding: 20px 0; overflow-y: auto;
    transition: transform 0.3s cubic-bezier(0.25,0.46,0.45,0.94);
}

.sidebar-logo {
    padding: 0 20px 24px;
    font-size: 15px; font-weight: 800;
    letter-spacing: 0.05em; color: var(--primary-ink);
}

.nav-section {
    font-size: 10px; font-weight: 700; letter-spacing: 0.12em;
    color: var(--text-muted); padding: 8px 20px 4px;
    text-transform: uppercase;
}

.nav-item {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 16px; margin: 1px 8px;
    font-size: 13px; color: var(--text-secondary);
    cursor: pointer; transition: var(--transition);
    border-radius: var(--radius-sm);
    font-weight: 500; text-decoration: none;
    border: 1px solid transparent;
}
.nav-item:hover {
    background: var(--card);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-color: var(--border-light);
    text-decoration: none;
    color: var(--text);
}
.nav-item.active {
    color: var(--primary-ink);
    background: var(--primary-light);
    border-color: var(--border);
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}

.nav-icon { font-size: 16px; width: 22px; text-align: center; }
.nav-sep { height: 1px; background: var(--border-light); margin: 10px 16px; }

/* Main content area */
.main-content {
    margin-left: var(--sidebar-width);
    flex: 1; padding: 28px 32px;
    min-height: 100vh;
}

/* Stat row */
.stat-row { display: flex; gap: 16px; margin-bottom: 24px; }
.stat-row > * { flex: 1; }

/* Mobile sidebar */
.sidebar-overlay {
    display: none; position: fixed; inset: 0;
    background: var(--overlay-bg);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: 99;
}
.sidebar-toggle {
    display: none; position: fixed; top: 12px; left: 12px;
    z-index: 101;
    background: var(--glass-bg);
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius); padding: 8px 12px;
    cursor: pointer; font-size: 18px;
    box-shadow: var(--shadow);
    color: var(--text);
}

@media (max-width: 768px) {
    .sidebar { transform: translateX(-100%); }
    .sidebar.open { transform: translateX(0); }
    .sidebar-overlay.open { display: block; }
    .sidebar-toggle { display: block; }
    .main-content { margin-left: 0; padding: 60px 16px 16px; }
    .stat-row { flex-direction: column; }
}

/* ===== Auth layout — Liquid Glass card ===== */
.auth-layout {
    display: flex; align-items: center; justify-content: center;
    min-height: 100vh; padding: 20px;
    background: linear-gradient(135deg, #edfffe 0%, #f4fffe 50%, #e8faf9 100%);
}
.auth-layout::before {
    content: '';
    position: fixed; inset: 0;
    background:
        radial-gradient(ellipse at 30% 30%, rgba(62,205,198,0.12) 0%, transparent 50%),
        radial-gradient(ellipse at 70% 70%, rgba(62,205,198,0.08) 0%, transparent 50%);
    pointer-events: none;
}
.auth-card {
    background: var(--glass-bg);
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-xl); padding: 40px;
    width: 100%; max-width: 440px;
    box-shadow: var(--shadow-glow), var(--glass-inner-glow);
}
.auth-logo {
    font-size: 20px; font-weight: 800; color: var(--primary-ink);
    letter-spacing: 0.05em; text-align: center; margin-bottom: 8px;
}
.auth-title {
    font-size: 22px; font-weight: 700; text-align: center; margin-bottom: 4px;
}
.auth-sub {
    font-size: 13px; color: var(--text-muted); text-align: center; margin-bottom: 28px;
}

/* ===== Dark Theme Layout ===== */
[data-theme="dark"] .sidebar {
    background: rgba(10,26,26,0.70);
    border-right-color: rgba(62,205,198,0.10);
    box-shadow: var(--glass-inner-glow), 1px 0 20px rgba(0,0,0,0.2);
}
[data-theme="dark"] .nav-item:hover {
    background: rgba(62,205,198,0.06);
    border-color: rgba(62,205,198,0.10);
    color: var(--text);
}
[data-theme="dark"] .nav-item.active {
    background: rgba(79,224,216,0.12);
    border-color: rgba(79,224,216,0.20);
}
[data-theme="dark"] .sidebar-logo img { filter: none; }
[data-theme="dark"] .sidebar-overlay { background: rgba(0,0,0,0.6); }
[data-theme="dark"] .sidebar-toggle {
    background: rgba(10,26,26,0.70);
    border-color: rgba(62,205,198,0.15);
}

[data-theme="dark"] .auth-layout {
    background: linear-gradient(165deg, #0a1a1a, #0c2020, #0f2a2a);
}
[data-theme="dark"] .auth-layout::before {
    background:
        radial-gradient(ellipse at 20% 80%, rgba(62,205,198,0.08) 0%, transparent 50%),
        radial-gradient(ellipse at 80% 20%, rgba(0,228,200,0.05) 0%, transparent 50%);
}
[data-theme="dark"] .auth-card {
    background: rgba(255,255,255,0.05);
    border-color: rgba(62,205,198,0.12);
    box-shadow: var(--shadow-glow), var(--glass-inner-glow);
}
[data-theme="dark"] .auth-logo img { filter: none; }

/* ===== White-label: app.smileartpavilion.com -> SILVER METALLIC shell (brushed aluminium / chrome).
   Higher specificity than the light/dark .auth-layout/.sidebar/.nav-item rules so it wins in either
   theme. Other hosts are unaffected. The surface is a light polished-silver gradient with a diagonal
   sheen band + a faint brushed-metal texture; panels get a glossy top highlight and a metallic bevel
   carried in the box-shadow (bright inset top edge, dark inset bottom edge). ===== */

/* --- DARK silver-metallic background + animated reflection sheen (login + portal shell).
   A deep gunmetal gradient with a brighter polished steel band through the middle; a soft light
   band (the "reflection") sweeps slowly back-and-forth across it, with a faint brushed texture on
   top. Panels/cards/sidebar stay LIGHT and float on this dark metal. The login card is pinned to an
   opaque silver-white panel just below so it keeps its current light look on the dark canvas. --- */
/* DARK silver-metallic backdrop + animated reflection. Painted on the BODY pseudo-elements — NOT the
   body's own `background`: base.css backgrounds <html> too, so the body's background is NOT propagated
   to the canvas; it sits on the body box IN FRONT of the z-index:-1 pseudos and hides them (a bright
   test band proved invisible). With the body transparent, ::before (static metal) + ::after (moving
   reflection), both z-index:-1, render above the html background and below content. The login's
   .auth-layout is transparent too so the same body backdrop shows through there. */
body.brand-metallic,
body.brand-metallic .auth-layout {
    background: transparent;
}
/* Static brushed metal: deep gunmetal gradient + polished highlight (top-left) + corner shade + grain.
   body::before gets content/position/inset/z-index:-1 from base.css; we only paint it here. */
body.brand-metallic::before {
    background:
        radial-gradient(ellipse at 20% 14%, rgba(255,255,255,0.13) 0%, transparent 52%),
        radial-gradient(ellipse at 86% 90%, rgba(0,0,0,0.34) 0%, transparent 56%),
        repeating-linear-gradient(90deg, rgba(255,255,255,0.022) 0 1px, rgba(0,0,0,0.05) 1px 3px),
        linear-gradient(150deg, #121419 0%, #20252d 21%, #333b45 43%, #434c58 50%, #2b313a 71%, #14161b 100%);
    background-size: 100% 100%, 100% 100%, auto, cover;
    background-repeat: no-repeat, no-repeat, repeat, no-repeat;
}
/* Animated reflection: a soft diagonal light band swept across via transform (translateX) — GPU
   composited so it keeps moving on the fixed layer. Sits ABOVE ::before but below content (both
   z-index:-1; ::after paints last). Range keeps the band on-screen the whole cycle so it's always
   visible gliding across rather than flashing past off-screen. */
body.brand-metallic::after {
    content: '';
    position: fixed;
    top: -60%; bottom: -60%; left: -30%; width: 55%;
    pointer-events: none;
    z-index: -1;
    background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.05) 34%, rgba(255,255,255,0.26) 50%, rgba(255,255,255,0.05) 66%, transparent 100%);
    transform: translateX(5%) rotate(18deg);
    will-change: transform;
    animation: smileartSweep 6s ease-in-out infinite alternate;
}
@keyframes smileartSweep {
    from { transform: translateX(5%) rotate(18deg); }
    to   { transform: translateX(175%) rotate(18deg); }
}
@media (prefers-reduced-motion: reduce) {
    body.brand-metallic::after { animation: none; }
}

/* ══ NUCLEUS iridescent "oil-slick" skin ══════════════════════════════════════════════════════════
   Re-paints ONLY the backdrop of the shared brand-metallic shell (the dark graphite panels/sidebar/
   cards are reused as-is). ::before = layered violet + blue + teal iridescence on near-black, slowly
   drifting so it reads as liquid metal; ::after = a teal/violet version of the metallic light-sweep
   (position + smileartSweep animation inherited from body.brand-metallic::after). Comes AFTER the
   metallic rules → same specificity, source order wins. */
body.brand-nucleus::before {
    background:
        radial-gradient(ellipse at 16% 12%, rgba(147,63,212,0.55) 0%, transparent 46%),
        radial-gradient(ellipse at 84% 18%, rgba(58,79,208,0.44) 0%, transparent 44%),
        radial-gradient(ellipse at 26% 86%, rgba(47,224,212,0.42) 0%, transparent 48%),
        radial-gradient(ellipse at 88% 84%, rgba(168,58,196,0.44) 0%, transparent 50%),
        radial-gradient(ellipse at 58% 48%, rgba(37,208,196,0.16) 0%, transparent 62%),
        linear-gradient(152deg, #0a0612 0%, #150a26 28%, #1b0f30 50%, #0f1032 72%, #08060f 100%);
    background-size: 170% 170%, 160% 160%, 170% 170%, 160% 160%, 220% 220%, 100% 100%;
    background-repeat: no-repeat;
    animation: nucleusDrift 30s ease-in-out infinite alternate;
}
@keyframes nucleusDrift {
    from { background-position: 0% 0%, 100% 0%, 0% 100%, 100% 100%, 50% 50%, 0 0; }
    to   { background-position: 14% 10%, 86% 12%, 10% 90%, 88% 86%, 56% 44%, 0 0; }
}
body.brand-nucleus::after {
    background: linear-gradient(90deg, transparent 0%, rgba(47,224,212,0.10) 32%, rgba(147,63,212,0.28) 50%, rgba(47,224,212,0.10) 68%, transparent 100%);
    mix-blend-mode: screen;
}
@media (prefers-reduced-motion: reduce) {
    body.brand-nucleus::before { animation: none; }
}

/* Iridescent text WORDMARK for brands with no logo image (Nucleus). Violet→teal gradient type, thin +
   wide-tracked to echo the brand's futuristic identity; renders on any dark surface. */
.brand-wordmark { display: inline-flex; flex-direction: column; line-height: 1; gap: 3px; }
.brand-wordmark .bw-main {
    font-weight: 300;
    letter-spacing: 0.30em;
    text-transform: uppercase;
    font-size: 17px;
    padding-left: 0.30em;                 /* offset the trailing tracking so it optically centers */
    background: linear-gradient(100deg, #c3abff 0%, #8f8cff 34%, #38e6da 82%);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent; color: transparent;
}
.brand-wordmark .bw-sub {
    font-weight: 400;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    font-size: 8px;
    padding-left: 0.26em;
    color: rgba(224,230,242,0.55);
}
/* Auth page: larger + glowing, matching the brand's hero wordmark treatment. */
.auth-layout .brand-wordmark .bw-main, .auth-card .brand-wordmark .bw-main {
    font-size: 30px;
    text-shadow: 0 0 26px rgba(47,224,212,0.32);
}
.auth-layout .brand-wordmark .bw-sub, .auth-card .brand-wordmark .bw-sub { font-size: 10px; }
/* Forced-colors / high-contrast: the gradient background is dropped but the fill stays transparent,
   which would blank out the wordmark (the only brand mark for a logo-less brand). Force a solid color. */
@media (forced-colors: active) {
    .brand-wordmark .bw-main { -webkit-text-fill-color: currentColor; color: CanvasText; }
}

/* ══ LAB PORTAL: hold the branded backdrop STILL ═══════════════════════════════════════════════════
   The sweeping sheen and the Nucleus drift are fine on a login page, but the lab portal is a
   workspace people read all day and motion in the periphery pulls the eye off the work. Kept
   scoped to `body.area-lab` (set in _LayoutPortal.cshtml) so login and the other portals are
   untouched. Comes last → same specificity as the brand rules, source order wins.

   The sheen band is REMOVED rather than paused: `animation: none` would park a 26%-white diagonal
   band at its start position, leaving a bright streak down the left of every lab page. The Nucleus
   drift only animates background-position on its gradients, so freezing that one looks identical
   to a deliberately static backdrop. */
body.area-lab.brand-metallic::after { display: none; }
body.area-lab.brand-nucleus::before { animation: none; }

/* ══ LAB PORTAL: readability ═══════════════════════════════════════════════════════════════════════
   Reported by lab users: type too small, and low-contrast greys/blues on the dark shell.

   TYPE — see the +10% sweep applied directly to the Lab views' hardcoded px font-sizes. `zoom` was
   tried first and REVERTED: viewport units resolve against the unzoomed viewport (permanent scrollbar
   on the lab Dashboard, the cockpit drawer pinned at 110vh clipping its own action buttons), media
   queries fire at the wrong width, and getBoundingClientRect/clientX report zoomed px while
   style.left/offsetWidth use local px — which broke the image-editor crop box, GridStack widget drops,
   CBCT pan/window-level and the lightbox's fit-to-screen. Do not reintroduce it. */

/* ⚠ The discriminator is SHELL DARKNESS, not the user's theme preference. `data-theme` is set purely
   from `localStorage.theme || prefers-color-scheme` (_LayoutPortal.cshtml:12) and says NOTHING about
   the brand; `body.brand-metallic` paints an unconditionally dark gunmetal backdrop from the HOST.
   Keying the light rule on theme alone put near-black text on gunmetal (~1.3:1) for every white-label
   lab user whose OS is in light mode — worse than the grey they complained about, for exactly the
   users who complained. Every branded shell carries .brand-metallic (BrandResolver.BodyClass), so
   that one class covers Smile Art, Alfonso and Nucleus. */

/* Genuinely light surface: the complaint is the same — mid-grey too faint — so DEEPEN it. */
body.area-lab:not(.brand-metallic) {
    --text-muted:     #2b3a38;
    --text-secondary: #1b2c2a;
}

/* Dark surface: dark theme, OR any white-label shell regardless of theme. */
html[data-theme="dark"] body.area-lab,
body.area-lab.brand-metallic {
    --text-muted:     #ffffff;   /* the "grey text" complaint */
    --text-secondary: #ffffff;
    --info-ink:       #93c5fd;   /* deep blue → light blue */
    --info:           #93c5fd;
    --primary-ink:    #7fe9e2;   /* teal accent lifted for dark-on-dark headroom */
}

/* Literal hex greys that predate the tokens are deliberately NOT swept here. An attribute matcher
   like [style*="#86868b"] cannot know what that element sits ON — the one element it actually
   reached was on a light panel, so forcing #fff made it invisible. If a specific literal grey is
   too faint, fix it at that call site where the background is known. */

/* Login card → dark graphite glass so the whole site reads dark; a deep drop shadow lifts it off
   the brushed metal and a faint top sheen keeps the metallic feel. */
body.brand-metallic .auth-card {
    background: linear-gradient(180deg, rgba(36,41,51,0.94) 0%, rgba(22,25,32,0.95) 100%);
    backdrop-filter: blur(18px) saturate(140%);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    border: 1px solid rgba(255,255,255,0.12);
    box-shadow: 0 24px 70px rgba(0,0,0,0.62), 0 4px 14px rgba(0,0,0,0.42), inset 0 1px 0 rgba(255,255,255,0.08);
}

/* Page headers sit directly on the dark metal (cards keep dark ink via --text) → light ink. */
body.brand-metallic .page-title { color: #eef1f5; text-shadow: 0 1px 4px rgba(0,0,0,0.45); }
body.brand-metallic .page-sub { color: #aeb6c1; }

/* Dashboard GridStack widgets → dark graphite glass on the metal canvas (white ink stays crisp). */
body.brand-metallic .grid-stack-item-content {
    background: rgba(28,32,40,0.80);
    border: 1px solid var(--border);
    box-shadow: var(--shadow);
}
body.brand-metallic .grid-stack-item-content::before { display: none; }

/* --- Sidebar: dark brushed metal with a faint top sheen + beveled edges --- */
body.brand-metallic .sidebar {
    background:
        linear-gradient(180deg, rgba(40,45,55,0.92) 0%, rgba(28,32,40,0.88) 14%, rgba(19,22,28,0.9) 100%);
    backdrop-filter: blur(28px) saturate(140%);
    -webkit-backdrop-filter: blur(28px) saturate(140%);
    border-right: 1px solid rgba(255,255,255,0.10);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), inset -1px 0 0 rgba(0,0,0,0.30), 1px 0 22px rgba(0,0,0,0.40);
}

/* --- Nav items: subtle metallic hover + chrome-pressed active state --- */
body.brand-metallic .nav-item:hover {
    background: linear-gradient(180deg, rgba(255,255,255,0.09), rgba(255,255,255,0.04));
    border-color: rgba(255,255,255,0.12);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.07);
    color: var(--text);
}
body.brand-metallic .nav-item.active {
    color: #eef1f5;
    background: linear-gradient(180deg, rgba(93,107,129,0.55), rgba(58,66,82,0.50));
    border-color: rgba(255,255,255,0.18);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.12), inset 0 -1px 0 rgba(0,0,0,0.25), 0 1px 3px rgba(0,0,0,0.30);
    font-weight: 600;
}

/* --- Sidebar toggle: matching dark brushed-metal chip --- */
body.brand-metallic .sidebar-toggle {
    background: linear-gradient(180deg, rgba(56,63,75,0.92), rgba(34,39,48,0.9));
    border: 1px solid rgba(255,255,255,0.14);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 4px 14px rgba(0,0,0,0.40);
    color: var(--text);
}

/* --- Top bar (home/portal header): dark brushed metal to match the shell --- */
body.brand-metallic .topbar {
    background: linear-gradient(180deg, rgba(34,39,48,0.90) 0%, rgba(23,26,33,0.85) 100%);
    border-bottom: 1px solid rgba(255,255,255,0.10);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), 0 2px 14px rgba(0,0,0,0.35);
}

/* --- Partner-logo chip + "powered by assidu" co-brand. The Smile Art Pavilion mark is fine,
   dark, thin lettering that washes out on the silver-metallic surface, so seat it on a clean
   bright chip with a soft drop shadow so it lifts off the metal (used on login + the top bar). --- */
body.brand-metallic .brand-cobrand { display: inline-flex; align-items: center; gap: 10px; }
body.brand-metallic .sidebar-logo { display: flex; flex-direction: column; align-items: center; gap: 5px; }
body.brand-metallic .brand-logo-chip {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 7px 14px; border-radius: 11px;
    background: linear-gradient(180deg, #ffffff 0%, #eef1f4 100%);
    border: 1px solid rgba(70,80,95,0.16);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.95), 0 4px 14px rgba(40,46,54,0.22), 0 1px 3px rgba(40,46,54,0.14);
}
body.brand-metallic .brand-logo-chip img { display: block; filter: none; height: 20px; }
body.brand-metallic .brand-poweredby {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted);
}
body.brand-metallic .brand-poweredby img { height: 12px; display: block; }
/* Login: larger, centered chip stack — but keep the "powered by assidu" co-brand small + subtle. */
body.brand-metallic .auth-logo .brand-logo-chip { padding: 12px 22px; border-radius: 14px; }
body.brand-metallic .auth-logo .brand-logo-chip img { height: 38px; max-width: 240px; object-fit: contain; }
body.brand-metallic .auth-logo .brand-poweredby { font-size: 7.5px; gap: 4px; opacity: 0.7; }
body.brand-metallic .auth-logo .brand-poweredby img { height: 9px; }

/* --- Dialogs / modals / popovers / menus / command bar: their hard-coded dark-teal backgrounds
   don't match the steel shell, so re-skin them to a dark graphite-metal panel (white text/inputs
   already come from the re-themed tokens). --- */
body.brand-metallic .app-dialog,
body.brand-metallic .fm-modal,
body.brand-metallic .pd-context-menu,
body.brand-metallic .pd-version-popover,
body.brand-metallic .cmp-overlay,
body.brand-metallic .modal-overlay > .modal,
body.brand-metallic .command-bar-panel {
    background: linear-gradient(180deg, rgba(36,41,51,0.97) 0%, rgba(24,27,34,0.97) 100%);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
}

/* --- Primary buttons: polished steel slab with top gloss + bevel + white text --- */
body.brand-metallic .btn-primary {
    background: linear-gradient(180deg, #5d6878 0%, #4a5568 52%, #3c4555 100%);
    color: #ffffff;
    border: 1px solid rgba(40,46,54,0.4);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), inset 0 -1px 0 rgba(0,0,0,0.2), 0 4px 14px rgba(40,46,54,0.28);
}
body.brand-metallic .btn-primary:hover {
    background: linear-gradient(180deg, #6a7585 0%, #525d70 52%, #404a5b 100%);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), inset 0 -1px 0 rgba(0,0,0,0.22), 0 6px 18px rgba(40,46,54,0.34);
}

/* ══ VECTOR ORTHODONTICS skin ═════════════════════════════════════════════════════════════════════
   Matches vectororthodontics.com. That site is FLAT and architectural — a near-black ground, hairline
   rules, 2px radii, one periwinkle accent, and a signature tiled-mark texture at 8% ink — where the
   shared shell is brushed silver with sheen and glass. So this block re-paints the backdrop AND the
   chrome (sidebar / topbar / nav / cards / login card) that body.brand-metallic styles as metal.

   Appended at the END of the file on purpose: every rule here is the same specificity as the
   brand-metallic rule it replaces, so source order is what makes it win. Do not move it earlier.
   Tokens live in design-tokens.css (body.brand-vector). ══════════════════════════════════════════ */

/* Backdrop: the site's own ground gradient + its tiled "V" texture (vector_tile.svg = the same
   150px pattern the site builds with <pattern id="vTile">, baked at --tex 0.08 on --ink). Replaces
   the gunmetal gradient from body.brand-metallic::before. */
body.brand-vector::before {
    background:
        url('/image/vector_tile.svg') 0 0,
        #0A0D12;
    background-size: 150px 150px, 100% 100%;
    background-repeat: repeat, no-repeat;
    animation: none;
}
/* No sheen: their site has no moving light band, and a 26%-white sweep over a flat near-black ground
   reads as a rendering artefact rather than polish. Removed, not paused — see the note at
   body.area-lab.brand-metallic::after for why `animation:none` alone would park a bright streak. */
body.brand-vector::after { display: none; }

/* base.css hardcodes assidu teal on the scrollbar and the selection highlight; neither is a token, so
   neither re-themes. They are the last mint left on an otherwise periwinkle page. */
body.brand-vector ::-webkit-scrollbar-thumb { background: rgba(122,151,255,0.26); }
body.brand-vector ::-webkit-scrollbar-thumb:hover { background: rgba(122,151,255,0.42); }
body.brand-vector ::selection { background: rgba(122,151,255,0.30); color: #EDF1F6; }

/* ⚠ The lab-readability block above (`body.area-lab.brand-metallic`) is specificity (0,2,1) and pins
   --primary-ink to assidu teal #7fe9e2. body.brand-vector (0,1,1) loses to it, so every lab page would
   keep a mint accent-as-text. Re-assert the periwinkle at matching specificity. --text-muted /
   --text-secondary are deliberately left at that block's #ffffff: it exists because lab users reported
   grey-on-dark as unreadable, and that complaint applies to this shell too. */
/* Both selectors are required. That block has TWO of them and the first,
   `html[data-theme="dark"] body.area-lab`, is specificity (0,2,2) — it outranks a plain
   `body.area-lab.brand-vector` (0,2,1), so on dark theme the accent-as-text silently stayed mint while
   light theme went periwinkle. The qualified twin below is (0,3,2) and settles it in both. */
body.area-lab.brand-vector,
html[data-theme="dark"] body.area-lab.brand-vector { --primary-ink: #A9BCFF; }

/* Login card → flat panel on the ground, hairline border, no glass blur. */
body.brand-vector .auth-card {
    background: #11161E;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: 1px solid #222A35;
    box-shadow: 0 24px 64px rgba(0,0,0,0.62);
}
body.brand-vector .page-title { color: #EDF1F6; text-shadow: none; }
body.brand-vector .page-sub { color: #BCC6D3; }

/* Dashboard widgets → the same flat panel as every other surface. */
body.brand-vector .grid-stack-item-content {
    background: #11161E;
    border: 1px solid #222A35;
    box-shadow: none;
}

/* Sidebar: flat ground with a hairline edge — no brushed-metal gradient, no bevel. */
body.brand-vector .sidebar {
    background: #0D1219;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-right: 1px solid #222A35;
    box-shadow: none;
}
/* Nav: the site's own button language — transparent by default, hairline on hover, accent-soft fill
   with a periwinkle rule when active (their .btn--line / --accent-soft pattern). */
body.brand-vector .nav-item:hover {
    background: #171E28;
    border-color: #333D4B;
    box-shadow: none;
    color: #EDF1F6;
}
body.brand-vector .nav-item.active {
    color: #EDF1F6;
    background: #141C30;               /* the site's --accent-soft */
    border-color: rgba(122,151,255,0.42);
    box-shadow: inset 2px 0 0 #7A97FF; /* accent rule, echoing their 2px-radius hard edges */
    font-weight: 600;
}
body.brand-vector .sidebar-toggle {
    background: #171E28;
    border: 1px solid #222A35;
    box-shadow: none;
    color: #EDF1F6;
}
/* Top bar: mirrors their sticky .hdr — translucent paper + blur + a single hairline underneath. */
body.brand-vector .topbar {
    background: rgba(10,13,18,0.88);
    backdrop-filter: saturate(1.4) blur(12px);
    -webkit-backdrop-filter: saturate(1.4) blur(12px);
    border-bottom: 1px solid #222A35;
    box-shadow: none;
}

/* The white .brand-logo-chip plate exists so Smile Art's dark wordmark lifts off silver metal. Vector's
   mark is inline SVG in currentColor on a dark ground, so the plate would be a white box around it. */
body.brand-vector .brand-logo-chip {
    background: none;
    border: 0;
    box-shadow: none;
    padding: 0;
}

/* Brand mark — the site renders the glyph alone at 52px and hides its wordmark (.brand__wm{display:none}),
   tinted --ink rather than the accent. Kept faithful; sizes are trimmed to fit the portal's chrome. */
/* Their header lockup: the glyph beside the name in wide-tracked geometric caps (.brand + .brand__wm),
   both in --ink. The wordmark is only dropped below 440px on their site, so keep it and mirror that
   breakpoint. Outfit is their display face; it is NOT vendored here and the offline-resilience rule
   forbids pulling it from a CDN, so the stack falls through to Futura / Century Gothic / system-ui —
   the same fallbacks their own --f-display declares. */
.brand-vectormark { display: inline-flex; align-items: center; gap: 11px; color: var(--text); }
.brand-vectormark svg { display: block; height: 30px; width: auto; flex: none; }
.brand-vectormark .bv-wm {
    font-family: "Outfit", "Futura", "Century Gothic", system-ui, sans-serif;
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 0.215em;
    text-transform: uppercase;
    white-space: nowrap;
    line-height: 1;
}
.auth-logo .brand-vectormark { gap: 14px; }
.auth-logo .brand-vectormark svg { height: 46px; }
.auth-logo .brand-vectormark .bv-wm { font-size: 13px; }
.sidebar-logo .brand-vectormark { gap: 9px; }
.sidebar-logo .brand-vectormark svg { height: 26px; }
.sidebar-logo .brand-vectormark .bv-wm { font-size: 10px; letter-spacing: 0.18em; }
@media (max-width: 440px) {
    .brand-vectormark .bv-wm { display: none; }   /* the mark carries the brand on a phone — their rule */
}

/* Buttons — the site's .btn--solid is a FLAT accent fill with near-black ink and no gloss; the shared
   shell renders .btn-primary as a bevelled steel slab (layouts.css:444) and components.css hardcodes a
   teal drop shadow under it, so both have to be unwound here. .btn-secondary follows their .btn--line:
   transparent with a hairline that brightens on hover. */
body.brand-vector .btn-primary {
    background: #7A97FF;
    color: #08101F;
    border: 1px solid transparent;
    box-shadow: none;
}
body.brand-vector .btn-primary:hover {
    background: #A9BCFF;        /* their --accent-ink is the hover fill, not a darker tint */
    box-shadow: none;
}
body.brand-vector .btn-secondary,
body.brand-vector .btn-outline {
    background: transparent;
    border: 1px solid #333D4B;
    color: #EDF1F6;
    box-shadow: none;
}
body.brand-vector .btn-secondary:hover,
body.brand-vector .btn-outline:hover {
    border-color: #EDF1F6;
    background: #11161E;
}

/* Dialogs / modals / menus: brand-metallic re-skins these to graphite glass; flatten them to the same
   panel colour so a modal doesn't reintroduce the metal look mid-page. */
body.brand-vector .app-dialog,
body.brand-vector .fm-modal,
body.brand-vector .pd-context-menu,
body.brand-vector .pd-version-popover,
body.brand-vector .cmp-overlay,
body.brand-vector .modal-overlay > .modal,
body.brand-vector .command-bar-panel {
    background: #11161E;
    border: 1px solid #222A35;
    box-shadow: 0 24px 64px rgba(0,0,0,0.66);
}

/* ── VECTOR: teal cleanup ──────────────────────────────────────────────────────────────────────────
   The token overrides above only reach declarations that go through var(). These are the hardcoded
   assidu-teal literals that survive on a Vector page, found by sweeping the login + lab surfaces.

   ⚠ Every selector here doubles the class: `.brand-metallic.brand-vector`. BrandResolver.BodyClass
   always emits BOTH, and the doubled form is (0,3,x) — enough to beat the `[data-theme="dark"] .x`
   rules in components.css and home.css, which are (0,2,0) AND are linked AFTER layouts.css
   (_LayoutPortal.cshtml:21-28). A plain `body.brand-vector .topbar` ties on specificity and loses on
   source order — that is exactly how the earlier topbar rule ended up dead. */

/* Login backdrop: .auth-layout::before is a fixed, full-viewport pair of mint radial blooms, and
   because .auth-layout/.auth-card are unpositioned it paints OVER the login card. body.brand-metallic
   zeroes the ELEMENT's background (layouts.css:190) but never the pseudo. */
body.brand-metallic.brand-vector .auth-layout::before { background: none; }

/* Full-viewport z-index:9999 scrim shown on every form submit and every link click (app.js:189,:210). */
body.brand-metallic.brand-vector .loading-overlay { background: var(--overlay-bg); }

/* The ROOT scrollbar. base.css:37 matches <html>'s own scrollbar, which a `body.brand-vector *`
   descendant selector can never reach — the document scroller is the one users actually see. */
html:has(body.brand-vector)::-webkit-scrollbar-thumb { background: rgba(122,151,255,0.26); }
html:has(body.brand-vector)::-webkit-scrollbar-thumb:hover { background: rgba(122,151,255,0.42); }

/* components.css dark-theme block: card hover ring, input/select/search resting border + click-focus
   halo, toggle track, chat bubbles, unread notification rows. */
body.brand-metallic.brand-vector .card:hover { border-color: var(--border); }
body.brand-metallic.brand-vector .form-input,
body.brand-metallic.brand-vector .sel,
body.brand-metallic.brand-vector .search-bar { border-color: var(--border); }
body.brand-metallic.brand-vector .form-input:focus,
body.brand-metallic.brand-vector .sel:focus,
body.brand-metallic.brand-vector .search-bar:focus { box-shadow: var(--focus-ring); }
body.brand-metallic.brand-vector .toggle-switch { border-color: var(--border); }
body.brand-metallic.brand-vector .chat-msg-text,
body.brand-metallic.brand-vector .chat-msg-role { background: var(--primary-light); }
body.brand-metallic.brand-vector .notif-item.notif-unread { background: var(--primary-light); }
body.brand-metallic.brand-vector .notif-item.notif-unread:hover { background: var(--card-hover); }

/* Two dialog surfaces the flat-panel list above misses: .modal-panel (whiteboard "Attach Files") and
   the 3×3 app-grid dropdown in the top bar. */
body.brand-metallic.brand-vector .modal-panel,
body.brand-metallic.brand-vector .app-grid-dropdown {
    background: #11161E;
    border: 1px solid #222A35;
    box-shadow: 0 24px 64px rgba(0,0,0,0.66);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* home.css owns the Lab DASHBOARD chrome and loads after this file, so these need the doubled class.
   The lab home uses _LayoutHome (not _LayoutPortal), which is why the top bar shows up here at all. */
body.brand-metallic.brand-vector .topbar {
    background: rgba(10,13,18,0.88);
    border-bottom-color: #222A35;
    box-shadow: none;
}
body.brand-metallic.brand-vector .customize-btn {
    background: var(--primary-light);
    border-color: var(--border);
}
body.brand-metallic.brand-vector .customize-btn:hover { background: var(--card-hover); }
body.brand-metallic.brand-vector .edit-toolbar {
    background: var(--surface-elevated);
    border-color: var(--border);
}
/* the widget re-skin above sets background/border/box-shadow but not the edit-mode dashed outline */
body.brand-metallic.brand-vector .grid-stack.gs-edit-mode .grid-stack-item-content {
    outline-color: rgba(122,151,255,0.30);
}

/* File manager Upload button + the in-app image editor (reached from the lab Repository tab). */
body.brand-metallic.brand-vector .fm-btn-primary:hover { background: var(--primary-hover); }
body.brand-metallic.brand-vector .imed-primary { color: var(--on-primary); }
body.brand-metallic.brand-vector .imed-primary:hover { background: var(--primary-hover); }
body.brand-metallic.brand-vector .imed-tool.active {
    background: var(--primary-light);
    border-color: color-mix(in srgb, var(--primary) 40%, transparent);
}
body.brand-metallic.brand-vector .imed-crop-h { border-color: var(--on-primary); }
