﻿/**
 * XWUIShellApp Component Styles
 * Structure and behavior only — colors come from theme CSS variables.
 *
 * Style Dependencies:
 * - Base: reset.css, typography.css, utilities.css
 * - Brand: brand/xwui/brand.css
 * - Style: style/modern/spacing.css, style/modern/shadows.css
 * - Theme: theme/colors/{selected-theme}.css   (MANDATORY — color variables)
 * - Theme: theme/accents/{selected-accent}.css (MANDATORY — accent variables)
 * - Lines: theme/lines/balanced.css            (global border widths)
 * - Typography: theme/typography/*.css
 *
 * Layout: a vertical shell (header / body / footer); the body is a horizontal
 * row of sidebar + main. The sidebar width is driven INLINE by XWUIShellApp.ts
 * (`expanded` = sidebarWidth, `collapsed` = sidebarCollapsedWidth rail,
 * `hidden` = 0); this file only supplies structure, transitions and theming.
 */

/* ── Shell root ────────────────────────────────────────────────────────────*/
.xwui-shell-app {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    width: 100%;
    /* Positioning context for the absolutely-positioned skip-to-content link. */
    position: relative;
}

/* ── Shell host ────────────────────────────────────────────────────────────
   The app shell IS an XWUIShell — the SAME universal 5-region primitive
   (header / [first | body | last] / footer) the XWUIShellPage also composes.
   This host carries that shell; it fills the app-shell root between the
   (absolutely-positioned) skip link and the (flex-shrink:0) status bar. */
.xwui-shell-app-shell-host {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}
.xwui-shell-app-shell-host > .xwui-shell {
    flex: 1 1 auto;
    min-height: 0;
}

/* FIRST slot wrapper — pairs the activity bar (far edge) with the sidebar
   side-by-side. Plain row; widths come from each child's own CSS. */
.xwui-shell-app-first {
    display: flex;
    flex-direction: row;
    height: 100%;
    box-sizing: border-box;
}

/* BODY slot wrapper — stacks the main region over the optional bottom dock
   panel (the dock sits below the main, same column-width). */
.xwui-shell-app-body-col {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    height: 100%;
}

/* ── Shell header / footer (full width, above / below the body) ────────────*/
.xwui-shell-app-header {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: var(--spacing-sm, 0.5rem);
    border-bottom: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
    padding: var(--spacing-md, 1rem);
}

.xwui-shell-app-footer {
    flex-shrink: 0;
    border-top: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
    padding: var(--spacing-md, 1rem);
}

/* ── Body row (sidebar + main) ─────────────────────────────────────────────*/
.xwui-shell-app-body {
    flex: 1 1 auto;
    display: flex;
    min-height: 0;
    overflow: hidden;
    position: relative; /* positioning context for the mobile backdrop */
}

/* RTL / right-anchored sidebar — mirror the body row. */
.xwui-shell-app-rtl .xwui-shell-app-body,
.xwui-shell-app-sidebar-right .xwui-shell-app-body {
    flex-direction: row-reverse;
}

/* ── Sidebar ───────────────────────────────────────────────────────────────*/
.xwui-shell-app-sidebar {
    position: relative; /* anchors the in-sidebar toggle button */
    /* Flex item: grow/shrink 0 so the used width is exactly the `flex-basis`
       set inline by XWUIShellApp.ts. `min-width: 0` removes the automatic
       content-size floor that would otherwise stop it collapsing. The collapse
       is intentionally NOT transitioned — a transition on a flex item's sizing
       property makes the flex layout ignore the new value (it stays stuck at
       the pre-collapse width), so the state change is instant. */
    flex-grow: 0;
    flex-shrink: 0;
    min-width: 0;
    box-sizing: border-box;
    overflow: hidden;
    border-right: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
}

.xwui-shell-app-rtl .xwui-shell-app-sidebar,
.xwui-shell-app-sidebar-right .xwui-shell-app-sidebar {
    border-right: none;
    border-left: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
}

.xwui-shell-app-sidebar-hidden {
    border-color: transparent;
}

/* ── Main ──────────────────────────────────────────────────────────────────*/
.xwui-shell-app-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    overflow: hidden;
}

/* The app provides its own chrome (sidebar toggle, menu button, splitters), so
   the inner XWUIShellPart's hover controls strip would DUPLICATE the sidebar
   toggle (two collapse affordances on the same edge). Hide the part controls
   inside a shell-app — the app's own toggle is the single source of truth. */
.xwui-shell-app .xwui-shell-part-controls {
    display: none !important;
}

/* ── In-sidebar collapse toggle ────────────────────────────────────────────*/
.xwui-shell-app-sidebar-toggle {
    position: absolute;
    top: var(--spacing-sm, 0.5rem);
    inset-inline-end: var(--spacing-sm, 0.5rem);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
    border-radius: var(--radius-sm, 6px);
    background: var(--bg-elevated, var(--bg-primary));
    color: var(--text-secondary);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.xwui-shell-app-sidebar-toggle:hover {
    color: var(--accent-primary);
    border-color: var(--accent-primary);
    background: var(--bg-hover, var(--bg-secondary));
}
.xwui-shell-app-sidebar-toggle:focus-visible {
    outline: none;
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 3px rgba(var(--accent-primary-rgb, 25, 118, 210), 0.25);
}

/* ── Hamburger menu button (lives in the shell / main header) ──────────────*/
.xwui-shell-app-menu-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: var(--radius-sm, 6px);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease;
}
.xwui-shell-app-menu-btn:hover {
    color: var(--accent-primary);
    background: var(--bg-hover, var(--bg-secondary));
}
.xwui-shell-app-menu-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(var(--accent-primary-rgb, 25, 118, 210), 0.25);
}

/* ── Resizable splitter ────────────────────────────────────────────────────
   The splitter lives inside XWUIShell's positions-only body-row overlay
   (`.xwui-shell-bodyrow-shadow`), which has NO in-flow columns — the real
   first/body/last parts are grid siblings elsewhere. So it is absolutely
   positioned on the FIRST-slot boundary via `--xwui-shell-app-first-width`
   (activity bar + sidebar, published by the shell on every sidebar resize). */
.xwui-shell-app-splitter {
    position: absolute;
    inset-block: 0;
    inset-inline-start: calc(
        var(--xwui-shell-app-first-width, var(--xwui-shell-app-sidebar-width, 280px)) - 2px
    ); /* center the 5px handle on the boundary line */
    width: 5px;
    cursor: col-resize;
    background: transparent;
    transition: background 0.15s ease;
    z-index: 3;
}
/* Right-anchored sidebar: the first slot mirrors to the inline-end edge. */
.xwui-shell-app-sidebar-right .xwui-shell-app-splitter {
    inset-inline-start: auto;
    inset-inline-end: calc(
        var(--xwui-shell-app-first-width, var(--xwui-shell-app-sidebar-width, 280px)) - 2px
    );
}
.xwui-shell-app-splitter:hover,
.xwui-shell-app-dragging .xwui-shell-app-splitter {
    background: var(--accent-primary);
}
/* The splitter is a keyboard-operable `role="separator"` — give it a clear
   focus ring so keyboard users can see they've landed on the resize handle. */
.xwui-shell-app-splitter:focus-visible {
    outline: none;
    background: var(--accent-primary);
    box-shadow: 0 0 0 2px var(--bg-app, #fff), 0 0 0 4px var(--accent-primary);
}

/* While dragging the splitter: no text selection. */
.xwui-shell-app-dragging {
    user-select: none;
    cursor: col-resize;
}

/* ── Mobile: the sidebar becomes an overlay over the main area ─────────────*/
.xwui-shell-app-backdrop {
    position: absolute;
    inset: 0;
    /* A dim scrim + a light blur on the page behind — enough to push the
       content back without fully hiding it (the menu itself is opaque). */
    background: rgba(0, 0, 0, 0.4);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
    z-index: 8;
}

.xwui-shell-app-mobile .xwui-shell-app-sidebar {
    position: absolute;
    top: 0;
    bottom: 0;
    inset-inline-start: 0;
    z-index: 10;
    /* As an overlay the sidebar floats over the page content, so it needs an
       opaque surface of its own — in-flow on desktop it sits on the app bg. */
    background: var(--bg-primary, var(--bg-app));
    box-shadow: var(--shadow-lg, 0 10px 30px rgba(0, 0, 0, 0.25));
}
.xwui-shell-app-sidebar-right.xwui-shell-app-mobile .xwui-shell-app-sidebar {
    inset-inline-start: auto;
    inset-inline-end: 0;
}

.xwui-shell-app-sidebar-overlay .xwui-shell-app-backdrop {
    opacity: 1;
    pointer-events: auto;
}

/* The in-sidebar collapse toggle and the splitter make no sense on mobile,
   where the sidebar is an open/closed overlay rather than a sized column. */
.xwui-shell-app-mobile .xwui-shell-app-sidebar-toggle,
.xwui-shell-app-mobile .xwui-shell-app-splitter {
    display: none;
}

/* ══ Built-in nav menu — hosts an XWUITree ════════════════════════════════
   `data.nav` is rendered by COMPOSING an XWUITree into `.xwui-shell-app-nav`
   (see XWUIShellApp.ts). The tree owns its own `.xwui-tree-*` markup +
   theming; this wrapper only sets the sidebar padding and the collapsed-rail
   behaviour against the tree's elements. */
.xwui-shell-app-nav {
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: var(--spacing-sm, 0.5rem);
}
.xwui-shell-app-nav .xwui-tree {
    min-width: 0;
}

/* Collapsed rail — icons only, FIRST LEVEL only. Hide the hosted XWUITree's
   labels / badges / expand-arrows and its nested child lists, then center the
   remaining icon, so the rail stays a clean column of icons. */
.xwui-shell-app-sidebar-collapsed .xwui-shell-app-nav .xwui-tree-node-label,
.xwui-shell-app-sidebar-collapsed .xwui-shell-app-nav .xwui-tree-node-badge,
.xwui-shell-app-sidebar-collapsed .xwui-shell-app-nav .xwui-tree-expand-icon,
.xwui-shell-app-sidebar-collapsed .xwui-shell-app-nav .xwui-tree-spacer {
    display: none !important;
}
.xwui-shell-app-sidebar-collapsed .xwui-shell-app-nav .xwui-tree-children {
    display: none !important;
}
.xwui-shell-app-sidebar-collapsed .xwui-shell-app-nav .xwui-tree-node-content {
    justify-content: center;
    padding-inline-start: 0 !important;
}

/* ══ Main header (breadcrumbs + consumer header + tab strip) ═══════════════ */
.xwui-shell-app-main-header {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.xwui-shell-app-main-header-content { min-width: 0; }

/* Header bar — a flex row pairing the breadcrumb trail (start) with the
   right-aligned theme-switcher slot (end). Only rendered inside the main
   header; the switcher itself is a composed XWUIStyleSwitch. */
.xwui-shell-app-main-header-bar {
    display: flex;
    align-items: center;
    gap: var(--spacing-md, 1rem);
    min-width: 0;
}
.xwui-shell-app-main-header-bar > .xwui-shell-app-breadcrumbs {
    flex: 1 1 auto;
}
/* Theme-switcher slot — pinned to the end of the header bar / site-header
   actions. The shell only positions the slot; XWUIStyleSwitch owns its UI. */
.xwui-shell-app-header-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    margin-inline-start: auto;
}
.xwui-shell-app-site-header-actions {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm, 0.5rem);
}
.xwui-shell-app-themeswitcher {
    display: inline-flex;
    align-items: center;
}

/* ── Breadcrumb trail — hosts an XWUINavBreadcrumbs ────────────────────────
   `data.breadcrumbs` is rendered by composing an XWUINavBreadcrumbs into this
   wrapper; the component owns its own `.xwui-breadcrumbs-*` markup + theming. */
.xwui-shell-app-breadcrumbs {
    min-width: 0;
}
.xwui-shell-app-breadcrumbs-empty { display: none; }

/* ── Tab strip — hosts an XWUINavTabs ──────────────────────────────────────
   In `tabs` nav mode the active section's children are rendered by composing
   an XWUINavTabs (strip-only, no content panels) into this wrapper. */
.xwui-shell-app-tabstrip {
    min-width: 0;
}
.xwui-shell-app-tabstrip-hidden { display: none !important; }

/* ══ Nav renderer: rail — hosts an XWUINavRail ═════════════════════════════
   The `rail` renderer composes an XWUINavRail (scope: container) into the
   sidebar's nav slot; the rail positions itself absolutely inside, so the
   host must be a positioned, flex-filling box. */
.xwui-shell-app-nav[data-nav-renderer="rail"] {
    position: relative;
    flex: 1 1 auto;
    padding: 0;
}

/* ══ Layout preset: website ════════════════════════════════════════════════
   header (XWUIBarSiteHeader) + full-width main + footer (XWUIBarSiteFooter).
   No sidebar row — the shell is a plain vertical stack and the PAGE scrolls
   (the site header pins itself via its own `position: sticky`). */
.xwui-shell-app[data-layout="website"] {
    min-height: 100vh;
}
.xwui-shell-app-site-header,
.xwui-shell-app-site-footer {
    flex-shrink: 0;
    display: block;
    width: 100%;
}
.xwui-shell-app[data-layout="website"] .xwui-shell-app-main {
    /* Override the dashboard main: the website main grows with its content and
       lets the document scroll, rather than owning an inner scroll region. */
    display: block;
    overflow: visible;
    flex: 1 0 auto;
    /* WHY no containment: `contain: layout` (below) makes the main a stacking
       context, which re-roots sticky descendants (an app-rendered site header)
       to this box and lets body-portaled overlays — e.g. XWUIInputSelect
       dropdowns at z:100 — paint OVER that header (z:200), since the whole
       contained main sits at root z:auto. The website/blank presets host the
       app's OWN chrome and scroll the document, so the dashboard perf win
       (isolating an inner scroll region) doesn't apply. Drop it to restore
       viewport-level stacking. */
    contain: none;
}

/* ══ Layout preset: blank ══════════════════════════════════════════════════
   Just the main region — no header / sidebar / footer chrome. */
.xwui-shell-app[data-layout="blank"] {
    height: 100vh;
    height: 100dvh;
}
.xwui-shell-app[data-layout="blank"] .xwui-shell-app-main {
    flex: 1 1 auto;
    /* Same reason as the website preset above: no layout containment, so the
       app's own sticky header + body-portaled dropdowns stack against the
       viewport instead of being trapped in the contained box. */
    contain: none;
}

/* ══ Accessibility ═════════════════════════════════════════════════════════ */

/* Direction follows the document, always.
   Components sometimes stamp literal dir="ltr"/"rtl" on hosts/inner nodes when
   they construct before the locale registers (boot order), which freezes layout
   even after html[dir] flips — and those attributes are never re-stamped on
   locale switch. Author CSS outranks the UA's [dir] mapping, so re-inherit the
   real document direction on the shell tree. This is what makes AR ⇄ EN
   switching reflow the layout live. Direction itself comes from each locale
   JSON's `locale.direction` via XWUILocale.setLocale → <html dir>. */
html[dir="rtl"] xwui-shell-app,
html[dir="rtl"] .xwui-shell-app,
html[dir="rtl"] .xwui-shell-app [dir="ltr"] {
    direction: rtl;
}
html[dir="ltr"] xwui-shell-app,
html[dir="ltr"] .xwui-shell-app,
html[dir="ltr"] .xwui-shell-app [dir="rtl"] {
    direction: ltr;
}

/* Skip-to-content link — visually hidden until it receives keyboard focus,
   then it slides into the top-left corner (WCAG 2.4.1 "Bypass Blocks"). It is
   the first focusable element in the shell, so it's the very first Tab stop. */
.xwui-shell-app-skip-link {
    position: absolute;
    inset-inline-start: 0;
    /* Fully off-screen until focused. A fixed negative offset (not a % transform)
       guarantees the link never peeks — the old translateY(-150%) only cleared
       the element by a few px, so a sliver could show mid-transition or at some
       zoom levels. It stays in the a11y tree + tab order, sliding in only on
       keyboard focus (WCAG 2.4.1 "Bypass Blocks"). */
    top: -100px;
    z-index: 100;
    margin: 0.5rem;
    padding: 0.55rem 1rem;
    border-radius: var(--radius-sm, 6px);
    background: var(--accent-primary, #1976d2);
    color: #fff;
    font-weight: 600;
    font-size: 0.9rem;
    text-decoration: none;
    transition: top 0.15s ease;
}
/* When this stylesheet loads late (SPA that injects xwui CSS after first paint),
   the unstyled link can flash at the page corner. Pin the visually-hidden state
   until focus — same a11y contract as :focus above. */
.xwui-shell-app-skip-link:not(:focus):not(:focus-visible) {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}
.xwui-shell-app-skip-link:focus,
.xwui-shell-app-skip-link:focus-visible {
    top: 0;
    outline: 2px solid var(--bg-app, #fff);
    outline-offset: 2px;
}

/* The main region is `tabindex="-1"` so the skip link can move focus into it;
   that focus is programmatic, not a keyboard Tab stop, so suppress the ring. */
.xwui-shell-app-main:focus {
    outline: none;
}

/* ══ Performance ═══════════════════════════════════════════════════════════
   `contain` lets the browser isolate layout / paint / style recalculation to
   the sidebar and main subtrees instead of reflowing the whole document when
   their contents change — the big win for long-lived dashboards. */
.xwui-shell-app-sidebar,
.xwui-shell-app-main {
    contain: layout style;
}
/* The website footer is reliably below the fold — let the browser skip
   rendering work for it until it scrolls near the viewport. */
.xwui-shell-app-site-footer {
    content-visibility: auto;
    contain-intrinsic-size: auto 320px;
}

/* ══ Reduced motion ════════════════════════════════════════════════════════
   Honour `prefers-reduced-motion`: drop the chrome transitions (the sidebar
   collapse is already instant by design — see the sidebar note above). */
@media (prefers-reduced-motion: reduce) {
    .xwui-shell-app-sidebar-toggle,
    .xwui-shell-app-menu-btn,
    .xwui-shell-app-splitter,
    .xwui-shell-app-backdrop,
    .xwui-shell-app-skip-link {
        transition: none !important;
    }
}

/* ══ Dockable regions ══════════════════════════════════════════════════════
   The inspector + bottom dock are each an XWUIPanel; the shell only sizes
   their host (width / height driven inline by XWUIShellApp.ts) and themes
   the dividers. The status bar is a thin slot pinned at the very bottom. */

/* Right inspector panel — an in-flow flex item after the main region. Same
   sizing trick as the sidebar: grow/shrink 0 + min-width 0 so the used width
   is exactly the inline flex-basis (and it can collapse to 0). */
.xwui-shell-app-rightpanel {
    flex-grow: 0;
    flex-shrink: 0;
    min-width: 0;
    box-sizing: border-box;
    overflow: hidden;
    contain: layout style;
    border-inline-start: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
}
.xwui-shell-app-rightpanel:not(.xwui-shell-app-rightpanel-open) {
    border-color: transparent;
}
/* No room for a docked inspector on phones — it collapses out. (A later phase
   morphs it into a bottom sheet, per the adaptive-mapping spec.) */
.xwui-shell-app[data-viewport="phone"] .xwui-shell-app-rightpanel {
    display: none;
}
/* Inspector relocated to the bottom dock — full width, height-sized, top border
   instead of the side border. */
.xwui-shell-app-rightpanel.xwui-shell-app-rightpanel-bottom {
    width: auto !important;
    flex-basis: auto !important;
    border-inline-start: none;
    border-block-start: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
}
.xwui-shell-app-rightpanel-bottom:not(.xwui-shell-app-rightpanel-open) {
    border-color: transparent;
}

/* Bottom dock panel — a docked strip below the body row (console / activity). */
.xwui-shell-app-bottompanel {
    flex-shrink: 0;
    min-height: 0;
    box-sizing: border-box;
    overflow: hidden;
    contain: layout style;
    border-top: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
}
.xwui-shell-app-bottompanel:not(.xwui-shell-app-bottompanel-open) {
    border-color: transparent;
}

/* Status bar — a thin OS-style strip at the very bottom (editor / desktop). */
.xwui-shell-app-statusbar {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: var(--spacing-md, 1rem);
    min-height: 26px;
    padding: 0 var(--spacing-md, 1rem);
    border-top: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
    background: var(--bg-secondary, var(--bg-app));
    color: var(--text-secondary);
    font-size: 0.78rem;
}

/* ══ Top loading bar ═══════════════════════════════════════════════════════
   A hairline XWUIProgressBar pinned to the top edge of the shell — route
   transitions / async work. The shell only positions the host; the bar
   itself (track / fill / indeterminate sweep) is pure XWUIProgressBar. */
.xwui-shell-app-loadingbar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 60;
    pointer-events: none;
}
.xwui-shell-app-loadingbar .xwui-progress {
    /* Let the progress bar span the shell edge-to-edge with no chrome. */
    width: 100%;
}

/* The toast host is a base-class plumbing slot only — XWUIToast renders its
   own body-level container, so the slot must never take up layout space. */
.xwui-shell-app-toast-host {
    display: none;
}

/* ══ Contextual save bar ═══════════════════════════════════════════════════
   A sticky, in-flow strip docked at the top/bottom of the main region — so it
   always tracks the sidebar + content width with no positioning math. It is
   composed from XWUIButtons; the shell only themes the strip + lays it out. */
.xwui-shell-app-has-savebar .xwui-shell-app-main {
    /* Stack the main panel + the save bar instead of the default row. */
    flex-direction: column;
}
.xwui-shell-app-has-savebar .xwui-shell-app-main > .xwui-panel {
    /* The panel defaults to height:100% — let it share the column instead. */
    height: auto;
    flex: 1 1 0;
    min-height: 0;
}
.xwui-shell-app-savebar {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--spacing-md, 1rem);
    padding: var(--spacing-sm, 0.5rem) var(--spacing-md, 1rem);
    box-sizing: border-box;
    background: var(--bg-secondary, var(--bg-app));
    border-top: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
}
.xwui-shell-app-savebar[data-position="top"] {
    order: -1;
    border-top: none;
    border-bottom: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
}
/* `host.hidden` only wins against the UA `display:none` — re-assert it here
   because the rule above sets `display:flex`. */
.xwui-shell-app-savebar[hidden] {
    display: none;
}
.xwui-shell-app-savebar-message {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-primary, var(--text-color));
}
.xwui-shell-app-savebar-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--spacing-sm, 0.5rem);
}

/* ══ Activity bar ══════════════════════════════════════════════════════════
   A slim vertical XWUINavRail on the far edge of the body row (the VS Code
   activity-bar pattern). The rail is `scope: container` — it positions itself
   absolutely inside — so the host is a positioned, fixed-width, full-height
   flex item. The view host is the swappable sidebar body it drives. */
.xwui-shell-app-activitybar {
    position: relative;
    flex: 0 0 auto;
    width: var(--xwui-shell-app-activitybar-width, 56px);
    box-sizing: border-box;
    overflow: hidden;
    background: var(--bg-secondary, var(--bg-app));
    border-inline-end: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
    contain: layout style;
}
/* The view host fills the sidebar body and scrolls — the activity rail swaps
   its content; the host itself is just a stable, themable scroll container. */
.xwui-shell-app-view-host {
    height: 100%;
    overflow: auto;
}

/* ══ Collapsed-rail flyout ═════════════════════════════════════════════════
   When the sidebar is the collapsed icon rail, hovering / focusing a parent
   nav item pops this flyout — a vertical XWUINavMenu of its children. The
   shell positions it (position:fixed, set inline); XWUINavMenu owns the item
   markup + theming, the shell just frames + themes the popover shell. */
.xwui-shell-app-rail-flyout {
    position: fixed;
    z-index: 70;
    min-width: 200px;
    max-width: 320px;
    max-height: 70vh;
    overflow: auto;
    box-sizing: border-box;
    padding: var(--spacing-xs, 0.25rem);
    background: var(--bg-primary, var(--bg-app));
    border: var(--border-container-width, var(--border-width-regular, 1.5px)) var(--border-container-style, solid) var(--border-container-color, var(--border-color));
    border-radius: var(--radius-md, 8px);
    box-shadow: var(--shadow-lg, var(--shadow-xl));
}
.xwui-shell-app-rail-flyout[hidden] {
    display: none;
}
.xwui-shell-app-rail-flyout-title {
    padding: var(--spacing-xs, 0.25rem) var(--spacing-sm, 0.5rem);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
}
@media (prefers-reduced-motion: reduce) {
    .xwui-shell-app-rail-flyout {
        transition: none !important;
    }
}

/* ══ Density: compact chrome ═══════════════════════════════════════════════
   Tightens the app chrome (header / main-header / tab strip / status bar)
   without touching the consumer's page content. */
.xwui-shell-app-density-compact {
    --xwui-shell-app-density: compact;
}
.xwui-shell-app-density-compact .xwui-shell-app-header,
.xwui-shell-app-density-compact .xwui-shell-app-main-header,
.xwui-shell-app-density-compact .xwui-shell-app-tabstrip {
    padding-block: var(--spacing-xxs, 4px);
    min-height: 0;
}
.xwui-shell-app-density-compact .xwui-shell-app-statusbar {
    min-height: 22px;
    font-size: var(--font-size-xs, 0.72rem);
}

/* ══ Watermark overlay ═════════════════════════════════════════════════════
   A repeating, non-interactive diagonal text overlay (security / branding).
   Sits above content but ignores pointer events; blends so it reads on both
   light and dark surfaces. */
.xwui-shell-app-watermark {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    opacity: 0.45;
    background-repeat: repeat;
    mix-blend-mode: multiply;
}
[data-theme="dark"] .xwui-shell-app-watermark,
.xwui-theme-dark .xwui-shell-app-watermark {
    mix-blend-mode: screen;
}

/* ══ Status-bar item groups (start / centre / end) ═════════════════════════ */
.xwui-shell-app-statusbar-start,
.xwui-shell-app-statusbar-end {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--spacing-sm, 0.5rem);
}
.xwui-shell-app-statusbar-center {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--spacing-sm, 0.5rem);
}
.xwui-shell-app-statusbar-end {
    justify-content: flex-end;
}

/* ══ Settings drawer ═══════════════════════════════════════════════════════ */
.xwui-shell-app-settings-gear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--text-secondary, var(--text-color));
    border-radius: var(--radius-sm, 6px);
    cursor: pointer;
    transition: background-color 0.12s ease, color 0.12s ease;
}
.xwui-shell-app-settings-gear:hover {
    background: var(--bg-hover, rgba(0, 0, 0, 0.06));
    color: var(--text-primary, var(--text-color));
}
.xwui-shell-app-settings {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-lg, 1.25rem);
    padding: var(--spacing-md, 1rem);
}
.xwui-shell-app-settings-group {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-xs, 0.5rem);
}
.xwui-shell-app-settings-label {
    font-size: var(--font-size-xs, 0.72rem);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-secondary);
}
.xwui-shell-app-settings-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-xs, 0.5rem);
}

/* ── Editor split-panes ─────────────────────────────────────────────────────
   The main panel body is replaced by a flex container of panes + draggable
   gutters. Panes own their own scroll; gutters are thin grab strips. */
.xwui-shell-app-split {
    display: flex;
    width: 100%;
    height: 100%;
    min-height: 0;
}
.xwui-shell-app-split[data-orientation="vertical"] { flex-direction: column; }
.xwui-shell-app-split-pane {
    min-width: 0;
    min-height: 0;
    overflow: auto;
}
.xwui-shell-app-split-gutter {
    flex: 0 0 auto;
    position: relative;
    background: var(--border-color, #e2e8f0);
    transition: background 120ms ease;
    touch-action: none;
}
.xwui-shell-app-split-gutter[data-orientation="horizontal"] { width: 5px; cursor: col-resize; }
.xwui-shell-app-split-gutter[data-orientation="vertical"]   { height: 5px; cursor: row-resize; }
.xwui-shell-app-split-gutter:hover,
.xwui-shell-app-split-gutter-dragging {
    background: var(--color-primary, #3b82f6);
}

/* ── Utility bar (pinned tool popovers) ─────────────────────────────────────
   A thin vertical icon rail pinned to the end edge of the shell; clicking a
   button toggles a floating XWUIPanel popover next to the rail. */
.xwui-shell-app-utilitybar {
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    z-index: 30;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    padding: 0.4rem 0.25rem;
    background: var(--bg-secondary, #f8fafc);
    border-inline-start: var(--border-width-regular, 1.5px) solid var(--border-color, #e2e8f0);
}
.xwui-shell-app-utility-popover {
    position: absolute;
    inset-block-start: 0.5rem;
    inset-inline-end: 3rem;
    z-index: 31;
    width: min(320px, 70vw);
    max-height: calc(100% - 1rem);
    overflow: auto;
    background: var(--bg-primary, #fff);
    border: var(--border-width-regular, 1.5px) solid var(--border-color, #e2e8f0);
    border-radius: var(--radius-md, 10px);
    box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.28);
}

/* ── App launcher grid ──────────────────────────────────────────────────────*/
.xwui-shell-app-launcher-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 0.5rem;
    padding: 0.5rem;
}
.xwui-shell-app-launcher-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.9rem 0.5rem;
    border: var(--border-width-regular, 1.5px) solid transparent;
    border-radius: var(--radius-md, 10px);
    background: var(--bg-secondary, #f8fafc);
    color: var(--text-primary, #0f172a);
    font: inherit;
    cursor: pointer;
    transition: border-color 120ms ease, background 120ms ease;
}
.xwui-shell-app-launcher-tile:hover {
    border-color: var(--color-primary, #3b82f6);
    background: var(--bg-primary, #fff);
}
.xwui-shell-app-launcher-tile[aria-current="true"] {
    border-color: var(--color-primary, #3b82f6);
}
.xwui-shell-app-launcher-tile-label {
    font-size: 0.78rem;
    text-align: center;
    line-height: 1.2;
}

/* ── Phone bottom-sheet morph ───────────────────────────────────────────────
   On phone, the bottom-docked inspector reads as a sheet: rounded top corners,
   a grab handle, and a stronger shadow lifting it off the content. */
.xwui-shell-app-phone-sheet .xwui-shell-app-rightpanel-bottom {
    border-start-start-radius: var(--radius-lg, 16px);
    border-start-end-radius: var(--radius-lg, 16px);
    box-shadow: 0 -8px 24px -10px rgba(0, 0, 0, 0.3);
    overflow: hidden;
}
.xwui-shell-app-phone-sheet .xwui-shell-app-rightpanel-bottom::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-start: 6px;
    margin-inline: auto;
    width: 36px;
    height: 4px;
    border-radius: 2px;
    background: var(--border-color, #cbd5e1);
    z-index: 2;
}

/* ── Auto bottom navigation bar (config.bottomBar) ──────────────────────────
 * The host is a passthrough; XWUINavBottom owns the fixed positioning. When the
 * bar is visible for the current viewport, pad the main region so page content
 * isn't hidden behind the fixed bar. */
.xwui-shell-app-bottom-bar[hidden] {
    display: none;
}

.xwui-shell-app.xwui-shell-app-has-bottom-bar .xwui-shell-app-main,
.xwui-shell-app.xwui-shell-app-has-bottom-bar .xwui-shell-app-main-website {
    padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px));
}
