/*
 * Filename: window.scss
 * FullPath: modules/projects/veela.css/src/scss/ui/components/window.scss
 * Change date and time: 23.09.20_23.08.2026
 * Reason for changes: Empty footer-handler collapsed — slot child broke :empty / :has-slotted.
 * FIND:win-footer
 */

/* Shadow sheets import the canonical color function definition. */
@use "../../core/color-mod";

@layer components {
:host(ui-window) {
    /* Tokens — light defaults via light-dark(); dark flips with color-scheme / data-theme */
    --ui-win-radius: var(--radius-lg, 0.75rem);
    --ui-win-titlebar-height: 2.5rem;
    --ui-win-footer-min: 2.25rem;
    --ui-win-control-size: 1.75rem;
    --ui-win-icon-size: var(--ui-window-icon-size, 0.95rem);
    --ui-win-gap: 0.5rem;
    --ui-win-pad-inline: 0.75rem;
    --ui-win-pad-block: 0.65rem;

    /*
     * Prefer document `--color-*` (concrete under data-theme) so Light/Dark pins win.
     * light-dark() kept only as last-resort when veela tokens are absent.
     */
    --ui-win-seed: var(--base-color, var(--color-primary, #5a9ec8));
    --ui-win-bg: var(--color-surface-container-low, light-dark(
        --u2-color-mod(var(--ui-win-seed), 70),
        --u2-color-mod(var(--ui-win-seed), 930)
    ));
    --ui-win-fg: var(--color-on-surface, light-dark(
        --u2-color-mod(var(--ui-win-seed), 900),
        --u2-color-mod(var(--ui-win-seed), 100)
    ));
    --ui-win-muted: var(--color-on-surface-variant, light-dark(
        --u2-color-mod(var(--ui-win-seed), 700),
        --u2-color-mod(var(--ui-win-seed), 280)
    ));
    --ui-win-border: color-mix(in oklab, var(--ui-win-fg) 12%, transparent);
    --ui-win-titlebar-bg: var(--color-surface-container-low, light-dark(
        --u2-color-mod(var(--ui-win-seed), 40),
        --u2-color-mod(var(--ui-win-seed), 960)
    ));
    --ui-win-content-bg: var(--color-surface-container-low, light-dark(
        --u2-color-mod(var(--ui-win-seed), 40),
        --u2-color-mod(var(--ui-win-seed), 950)
    ));
    --ui-win-footer-bg: var(--color-surface-container-low, light-dark(
        --u2-color-mod(var(--ui-win-seed), 120),
        --u2-color-mod(var(--ui-win-seed), 900)
    ));
    --ui-win-shadow:
        light-dark(
            0 18px 40px -18px rgb(15 23 42 / 0.28),
            0 22px 48px -16px rgb(0 0 0 / 0.55)
        );
    /* WHY: transparent idle so controls share the solid titlebar fill (no “chip strip”). */
    --ui-win-control-bg: transparent;
    --ui-win-control-bg-hover: color-mix(in oklab, var(--ui-win-fg) 14%, transparent);
    --ui-win-control-fg: var(--ui-win-fg);
    --ui-win-close-bg: transparent;
    --ui-win-close-bg-hover: light-dark(
        --u2-color-mod(#ef4444, 550),
        --u2-color-mod(#ef4444, 480)
    );
    --ui-win-close-fg: var(--ui-win-fg);
    --ui-win-close-fg-hover: --u2-color-mod(var(--ui-win-seed), 40);
    --icon-color: var(--ui-win-fg);
    /* WHY: do not set --icon-size on the host — it inherits into Explorer/viewer
     * and shrinks list + toolbar glyphs to titlebar chrome size (0.95rem). */

    /*
     * WHY: `light dark` made window chrome follow OS while Settings locked light — cream panel
     * + dark-scheme fg. Inherit document/app scheme; explicit data-theme still wins below.
     */
    color-scheme: inherit;
    box-sizing: border-box;
    /* WHY: Prefer :host display over setting style attr in CE lifecycle (createElement rules). */
    display: block;
    position: relative;
    inline-size: var(--ui-win-width, min(32rem, 92vw));
    block-size: var(--ui-win-height, min(22rem, 70vh));
    min-inline-size: 16rem;
    min-block-size: 10rem;
    color: var(--ui-win-fg);
    font-family: "InterVariable", "Inter", "Segoe UI", ui-sans-serif, system-ui, sans-serif;
    font-size: 0.875rem;
    line-height: 1.35;
    border-radius: var(--ui-win-radius);
    overflow: hidden;
    box-shadow: var(--ui-win-shadow);
    isolation: isolate;
    contain: layout paint style;
    container-type: inline-size;
    container-name: ui-window;

    &,
    *,
    *::before,
    *::after {
        box-sizing: border-box;
    }

    /* WHY: footer always contains <slot>, so :empty / :has-slotted never hid the slab. */
    .footer-handler[data-empty],
    .footer-handler[hidden] {
        display: none !important;
    }
}

/* Explicit theme overrides (playground / app shell) */
:host(ui-window[data-theme="light"]),
:host(ui-window.theme-light) {
    color-scheme: light;
}

:host(ui-window[data-theme="dark"]),
:host(ui-window.theme-dark) {
    color-scheme: dark;
}

:host(ui-window[managed]) {
    position: absolute;
    /* WHY: environment-shell owns geometry via inline left/top/width/height. */
    transform: none !important;
}

/* WHY: Focused window gets a slightly stronger edge so z-order changes are visible. */
:host(ui-window[managed][data-focused]) {
    box-shadow:
        var(--ui-win-shadow),
        0 0 0 1px color-mix(in oklab, var(--ui-win-fg) 22%, transparent);
}

/*
 * WHY: CWSP views own their chrome padding; default ui-window pad crushed toolbars into overlaps.
 * INVARIANT: `native-mode` / `data-native-active` need the same flex fill as `managed`, otherwise
 * slotted Explorer (`.view-explorer` → `ui-file-manager`) collapses to toolbar-only height.
 */
:host(ui-window[managed]) .content-handler,
:host(ui-window[native-mode]) .content-handler,
:host(ui-window[data-native-active]) .content-handler {
    padding: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

:host(ui-window[managed]) .content-handler ::slotted(*),
:host(ui-window[native-mode]) .content-handler ::slotted(*),
:host(ui-window[data-native-active]) .content-handler ::slotted(*) {
    flex: 1 1 auto;
    min-block-size: 0;
    min-inline-size: 0;
    max-inline-size: none;
    inline-size: 100%;
    block-size: 100%;
}

:host(ui-window[maximized]) {
    --ui-win-radius: 0;
    inset: 0 !important;
    inline-size: 100% !important;
    block-size: 100% !important;
    border-radius: 0;
    transform: none !important;
}

/*
 * Mobile (env shell): full-bleed; Home FAB overlays the window (no dock slab).
 * Titlebar becomes an empty spacer under the transparent overlay statusband
 * (`--env-status-inset-top`) unless standalone (`data-no-titlebar`).
 */
:host(ui-window[data-mobile-max]) {
    --ui-win-radius: 0;
    /* Spacer height matches overlay status / notch when status-gap is on. */
    --ui-win-titlebar-height: var(--env-status-inset-top, max(2rem, env(safe-area-inset-top, 0px)));
    inset: 0 !important;
    inline-size: 100% !important;
    block-size: 100% !important;
    border-radius: 0;
    transform: none !important;

    @media screen and (pointer: coarse) and (hover: none) {
        block-size: stretch !important;
    }
}

:host(ui-window[data-mobile-max]) .title-minimize,
:host(ui-window[data-mobile-max]) .title-maximize,
:host(ui-window[data-mobile-max]) .title-close,
:host(ui-window[data-mobile-max]) .title-exit-native {
    display: none !important;
}

:host(ui-window[data-mobile-max]) .title-handler {
    cursor: default;
    /* WHY: transparent spacer sampled as black theme-color and broke Settings/Launcher unity. */
    background: var(--ui-win-titlebar-bg, var(--color-surface-container-low, --u2-color-mod(var(--ui-win-seed), 940)));
    border-block-end: 0;
    min-block-size: var(--ui-win-titlebar-height);
    padding-block: 0;
    pointer-events: none;
}

:host(ui-window[data-mobile-max]) .title-handler-main,
:host(ui-window[data-mobile-max]) .title-handler-actions,
:host(ui-window[data-mobile-max]) .title-handler-buttons {
    display: none !important;
}

/* WHY: a squeezed desktop pane (Cursor debug) is under 640px but still has a mouse.
 * Phone chrome stays hidden; fine pointers keep close / minimize on screen. */
@media (pointer: fine) {
    :host(ui-window[data-mobile-max]) {
        --ui-win-titlebar-height: 2.5rem;
    }

    :host(ui-window[data-mobile-max]) .title-minimize,
    :host(ui-window[data-mobile-max]) .title-maximize,
    :host(ui-window[data-mobile-max]) .title-close,
    :host(ui-window[data-mobile-max]) .title-exit-native {
        display: inline-flex !important;
    }

    :host(ui-window[data-mobile-max]) .title-handler {
        pointer-events: auto;
        cursor: default;
    }

    :host(ui-window[data-mobile-max]) .title-handler-main,
    :host(ui-window[data-mobile-max]) .title-handler-actions,
    :host(ui-window[data-mobile-max]) .title-handler-buttons {
        display: flex !important;
        pointer-events: auto;
    }
}

/* Standalone PWA mobile: no titlebar — content is edge-to-edge (safe-area via views if needed). */
:host(ui-window[data-no-titlebar]) {
    --ui-win-titlebar-height: 0px;
}

:host(ui-window[data-no-titlebar]) .title-handler {
    display: none !important;
}

/* Desktop/fullscreen with status overlay: maximized windows also reserve the top band. */
:host(ui-window[data-status-gap]:not([data-no-titlebar])) {
    --ui-win-titlebar-height: var(--env-status-inset-top, max(2rem, env(safe-area-inset-top, 0px)));
}

:host(ui-window[data-status-gap]:not([data-no-titlebar])) .title-handler {
    cursor: default;
    background: var(--ui-win-titlebar-bg, var(--color-surface-container-low, --u2-color-mod(var(--ui-win-seed), 940)));
    border-block-end: 0;
    min-block-size: var(--ui-win-titlebar-height);
    padding-block: 0;
    pointer-events: none;
}

:host(ui-window[data-status-gap]:not([data-no-titlebar])) .title-handler-main,
:host(ui-window[data-status-gap]:not([data-no-titlebar])) .title-handler-actions,
:host(ui-window[data-status-gap]:not([data-no-titlebar])) .title-handler-buttons {
    display: none !important;
}

/* WHY: status-gap hides chrome under the overlay band. A fine pointer in a
 * narrow pane still needs Close — the band is not a phone gesture surface. */
@media (pointer: fine) {
    :host(ui-window[data-mobile-max][data-status-gap]:not([data-no-titlebar])) {
        --ui-win-titlebar-height: 2.5rem;
    }

    :host(ui-window[data-mobile-max][data-status-gap]:not([data-no-titlebar])) .title-handler {
        pointer-events: auto;
    }

    :host(ui-window[data-mobile-max][data-status-gap]:not([data-no-titlebar])) .title-handler-main,
    :host(ui-window[data-mobile-max][data-status-gap]:not([data-no-titlebar])) .title-handler-actions,
    :host(ui-window[data-mobile-max][data-status-gap]:not([data-no-titlebar])) .title-handler-buttons {
        display: flex !important;
        pointer-events: auto;
    }
}

:host(ui-window[data-desk-max]) {
    --ui-win-radius: 0;
    /* WHY: titlebar is inside the window — subtracting it left a shadowed slab above the taskbar (PWA). */
    inset: 0 0 var(--env-shell-chrome-stack-reserve, 2.5rem) 0 !important;
    inline-size: auto !important;
    block-size: auto !important;
    border-radius: 0;
    box-shadow: none !important;
    transform: none !important;

    @media screen and (pointer: coarse) and (hover: none) {
        block-size: stretch !important;
    }
}

:host(ui-window[managed][data-focused][data-desk-max]) {
    box-shadow: none !important;
}

:host(ui-window[minimized]) {
    block-size: var(--ui-win-titlebar-height) !important;
    min-block-size: var(--ui-win-titlebar-height);
}

:host(ui-window[minimized]) .content-handler,
:host(ui-window[minimized]) .footer-handler,
:host(ui-window[minimized]) .window-resizer {
    display: none;
}

:host(ui-window[hidden-window]) {
    visibility: hidden !important;
    pointer-events: none !important;
}

:host(ui-window[maximized]) .window-resizer,
:host(ui-window[data-mobile-max]) .window-resizer,
:host(ui-window[data-desk-max]) .window-resizer,
:host(ui-window[data-native-active]) .window-resizer {
    display: none;
}

/* -------------------------------------------------------------------------- */
/* native-mode: full-bleed + WCO / standalone / in-tab fallback               */
/* -------------------------------------------------------------------------- */

:host(ui-window[native-mode]),
:host(ui-window[data-native-active]) {
    --ui-win-radius: 0;
    position: fixed !important;
    inset: 0 !important;
    inline-size: 100% !important;
    block-size: 100% !important;
    max-inline-size: none;
    max-block-size: none;
    border-radius: 0;
    transform: none !important;
    box-shadow: none;
    /* WHY: above env chrome (~2e9 in env vars can minify oddly); stay under system overlays. */
    z-index: 100000;
}

:host(ui-window[data-native-wco]) .title-handler,
:host(ui-window[data-native-standalone]) .title-handler {
    /* Prefer standardized window-drag; keep Chromium legacy aliases. */
    window-drag: move;
    app-region: drag;
    -webkit-app-region: drag;
    cursor: default;
    /* Titleband: cover WCO / safe-area strip */
    min-block-size: max(
        var(--ui-win-titlebar-height),
        env(titlebar-area-height, var(--ui-win-titlebar-area-height, 0px)),
        calc(env(safe-area-inset-top, 0px) + 1.75rem)
    );
    padding-block-start: max(env(safe-area-inset-top, 0px), env(titlebar-area-y, 0px));
    padding-inline-start: max(
        env(safe-area-inset-left, 0px),
        env(titlebar-area-x, var(--ui-win-titlebar-area-x, 0px)),
        var(--ui-win-pad-inline)
    );
    padding-inline-end: max(
        env(safe-area-inset-right, 0px),
        max(0px, calc(100vi - env(titlebar-area-x, 0px) - env(titlebar-area-width, 100vi))),
        var(--ui-win-pad-inline)
    );
}

:host(ui-window[data-native-wco]) .title-handler-buttons,
:host(ui-window[data-native-wco]) .title-handler-actions,
:host(ui-window[data-native-standalone]) .title-handler-buttons,
:host(ui-window[data-native-standalone]) .title-handler-actions,
:host(ui-window[data-native-wco]) .title-handler-buttons button,
:host(ui-window[data-native-standalone]) .title-handler-buttons button {
    window-drag: none;
    app-region: no-drag;
    -webkit-app-region: no-drag;
}

/* WCO: OS owns min/max/close — hide custom duplicates. */
:host(ui-window[data-native-wco]) .title-minimize,
:host(ui-window[data-native-wco]) .title-maximize,
:host(ui-window[data-native-wco]) .title-close,
:host(ui-window[data-native-wco]) .title-exit-native {
    display: none !important;
}

/* Mobile / installed standalone: hide resize-like chrome; keep exit-native for env restore. */
:host(ui-window[data-native-standalone]) .title-minimize,
:host(ui-window[data-native-standalone]) .title-maximize,
:host(ui-window[data-native-standalone]) .title-close {
    display: none !important;
}

:host(ui-window[data-native-active]) .footer-handler[data-empty],
:host(ui-window[data-native-active]) .footer-handler[hidden],
:host(ui-window[data-mobile-max]) .footer-handler {
    display: none !important;
}

/*
 * WHY: `.title-handler-buttons button { display: inline-flex }` beats bare `[hidden]` /
 * `.title-exit-native { display: none }` — without !important the 4th control always leaks.
 * INVARIANT: exit-native only for installed standalone; fallback uses maximize as exit.
 */
.title-exit-native,
.title-exit-native[hidden] {
    display: none !important;
}

:host(ui-window[data-native-standalone]) .title-exit-native:not([hidden]) {
    display: inline-flex !important;
}

.window-container {
    display: grid;
    grid-template-rows: minmax(0, max-content) minmax(0, 1fr) minmax(0, max-content);
    grid-template-areas:
        "title"
        "content"
        "footer";
    inline-size: 100%;
    block-size: 100%;
    background: var(--ui-win-bg);
    color: var(--ui-win-fg);
    border: 1px solid var(--ui-win-border);
    border-radius: inherit;
    overflow: hidden;
    /* WHY: isolate title vs content stacking so slotted paint cannot cover chrome. */
    isolation: isolate;
}

.title-handler {
    grid-area: title;
    /*
     * WHY: Slotted view roots (e.g. settings) can create stacking contexts that paint over
     * the title grid row and swallow drag + min/max/close. Keep chrome above content.
     * INVARIANT: title z > content z (same pattern as env `.wf-frame` titlebar).
     */
    position: relative;
    z-index: 50;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    gap: var(--ui-win-gap);
    min-block-size: var(--ui-win-titlebar-height);
    padding-inline: var(--ui-win-pad-inline);
    padding-block: 0.35rem;
    background: var(--ui-win-titlebar-bg);
    /*border-block-end: 1px solid var(--ui-win-border);*/
    border: 0px none transparent;
    border-block-end: 0px none transparent;
    cursor: grab;
    user-select: none;
    touch-action: none;
    pointer-events: auto;

    &:active {
        cursor: grabbing;
    }
}

.title-handler-main {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-inline-size: 0;
    overflow: hidden;
    pointer-events: none;

    ::slotted(*),
    .title-text {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-weight: 600;
        letter-spacing: -0.01em;
    }
}

.title-handler-actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    min-inline-size: 0;
}

.title-handler-buttons {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-shrink: 0;
    position: relative;
    z-index: 51;
    pointer-events: auto;
    background: transparent;
    /* WHY: parent titlebar uses touch-action:none for drag; controls need click synthesis. */
    touch-action: manipulation;
}

.title-handler-buttons button,
.title-handler-actions button {
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: var(--ui-win-control-size);
    block-size: var(--ui-win-control-size);
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: var(--ui-win-control-bg);
    color: var(--ui-win-control-fg);
    --icon-color: currentColor;
    cursor: pointer;
    pointer-events: auto;
    transition:
        background-color 0.15s ease,
        color 0.15s ease,
        transform 0.12s ease;

    &:hover {
        background: var(--ui-win-control-bg-hover);
    }

    &:active {
        transform: scale(0.94);
    }

    &:focus-visible {
        outline: 2px solid color-mix(in oklab, var(--color-primary, #5a7fff) 70%, transparent);
        outline-offset: 2px;
    }

    ui-icon {
        inline-size: var(--ui-win-icon-size);
        block-size: var(--ui-win-icon-size);
        min-inline-size: var(--ui-win-icon-size);
        min-block-size: var(--ui-win-icon-size);
        flex-shrink: 0;
        --ui-icon-size: var(--ui-win-icon-size);
        --ui-icon-padding: 0;
        pointer-events: none;
    }
}

.title-handler-buttons .title-close {
    background: var(--ui-win-close-bg);
    color: var(--ui-win-close-fg);
    --icon-color: currentColor;

    &:hover {
        background: var(--ui-win-close-bg-hover);
        color: var(--ui-win-close-fg-hover);
    }
}

/* Maximize glyph swaps via JS (`#syncMaximizeIcon`) — one ui-icon, never dual corners. */

.content-handler {
    grid-area: content;
    /*
     * WHY (radical): views with `position: fixed; inset: 0` (settings/markdown) escape the
     * content grid and swallow titlebar hits. `transform` makes this the fixed containing
     * block; `contain: paint` keeps compositing under the chrome row.
     */
    position: relative;
    z-index: 0;
    isolation: isolate;
    transform: translateZ(0);
    contain: paint;
    min-block-size: 0;
    min-inline-size: 0;
    overflow: auto;
    padding: 0px;/*var(--ui-win-pad-block) var(--ui-win-pad-inline);*/
    background: var(--ui-win-content-bg);
    color: var(--ui-win-fg);
    /*
     * WHY: `:host(ui-window[hidden-window])` sets `pointer-events: none !important` on the host;
     * without an explicit `auto` here the slotted view inherits `none` and the entire body
     * (settings tabs, explorer, etc.) becomes unclickable even while visible.
     */
    pointer-events: auto;
    /*
     * INVARIANT: window content does not inherit the titlebar icon token.
     * Explorer and other views choose their own component token locally.
     */

    ::slotted(*) {
        max-inline-size: 100%;
        /* WHY: keep view roots inside the content box; do not cover chrome. */
        max-block-size: 100%;
        min-block-size: 0;
        pointer-events: auto;
    }
}

.footer-handler {
    grid-area: footer;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
    min-block-size: var(--ui-win-footer-min);
    padding: 0.45rem var(--ui-win-pad-inline);
    background: var(--ui-win-footer-bg);
    border-block-start: 1px solid var(--ui-win-border);
    color: var(--ui-win-muted);

    &[data-empty],
    &[hidden] {
        display: none;
    }
}

/* SE resize affordance (optional slot / child) */
.window-resizer {
    position: absolute;
    z-index: 4;
    inset-inline-end: 4px;
    inset-block-end: 4px;
    inline-size: 12px;
    block-size: 12px;
    cursor: nwse-resize;
    border-radius: 2px;
    background: linear-gradient(
        135deg,
        transparent 48%,
        color-mix(in oklab, var(--ui-win-muted) 55%, transparent) 50%
    );
    opacity: 0.55;
    pointer-events: auto;

    &:hover {
        opacity: 0.9;
    }
}

/*
 * WHY: Inline `container-type: size` on `.content-handler` + print `height: auto` sizes
 * the box as empty (size containment). Chrome then paginates blank pages.
 * INVARIANT: Print kills size/paint containment and lets slotted markdown grow.
 */
@media print {
    :host(ui-window) {
        display: block !important;
        position: static !important;
        inset: auto !important;
        transform: none !important;
        overflow: visible !important;
        contain: none !important;
        container-type: normal !important;
        isolation: auto !important;
        inline-size: 100% !important;
        max-inline-size: 100% !important;
        block-size: auto !important;
        min-block-size: 0 !important;
        max-block-size: none !important;
        height: auto !important;
        min-height: 0 !important;
        max-height: none !important;
        box-shadow: none !important;
        border: none !important;
        border-radius: 0 !important;
        background: #fff !important;
        color: #000 !important;
    }

    .window-container {
        display: block !important;
        overflow: visible !important;
        contain: none !important;
        isolation: auto !important;
        inline-size: 100% !important;
        block-size: auto !important;
        height: auto !important;
        min-block-size: 0 !important;
        max-block-size: none !important;
        border: none !important;
        box-shadow: none !important;
        background: #fff !important;
        color: #000 !important;
    }

    .title-handler,
    .window-resizer,
    .footer-handler {
        display: none !important;
    }

    .content-handler,
    :host(ui-window[managed]) .content-handler,
    :host(ui-window[native-mode]) .content-handler,
    :host(ui-window[data-native-active]) .content-handler {
        display: block !important;
        position: static !important;
        transform: none !important;
        contain: none !important;
        container-type: normal !important;
        overflow: visible !important;
        isolation: auto !important;
        flex: none !important;
        inline-size: 100% !important;
        block-size: auto !important;
        min-block-size: 0 !important;
        max-block-size: none !important;
        height: auto !important;
        background: #fff !important;
        color: #000 !important;
    }

    .content-handler ::slotted(*),
    :host(ui-window[managed]) .content-handler ::slotted(*),
    :host(ui-window[native-mode]) .content-handler ::slotted(*),
    :host(ui-window[data-native-active]) .content-handler ::slotted(*) {
        display: block !important;
        flex: none !important;
        overflow: visible !important;
        contain: none !important;
        inline-size: 100% !important;
        max-inline-size: 100% !important;
        block-size: auto !important;
        min-block-size: 0 !important;
        max-block-size: none !important;
        height: auto !important;
    }
}
}
