////
///
/// App Shell
/// ===========================================================================
///
/// Full-height application frame for tool demos and dashboards: a header,
/// optional left and right sidebars, a main viewport and an optional
/// status / footer bar.
///
///     <div class="ss-l-app">
///         <header class="ss-l-app__header">…</header>
///         <aside class="ss-l-app__sidebar" id="nav">…</aside>
///         <main class="ss-l-app__main ss-l-app__main--bleed">
///             <canvas>…</canvas>
///         </main>
///         <aside class="ss-l-app__sidebar ss-l-app__sidebar--right">…</aside>
///         <footer class="ss-l-app__footer">…</footer>
///     </div>
///
/// Every part is optional except `__main`. The main area has a minimum
/// size of zero so a canvas, map or 3D view can fill it without
/// stretching the shell; `--bleed` removes padding and scrolling.
///
/// Sizing tokens (set on `.ss-l-app` or any ancestor):
///   `--ss-app-header-height`, `--ss-app-footer-height`,
///   `--ss-app-sidebar-width`, `--ss-app-sidebar-left-width`,
///   `--ss-app-sidebar-right-width`.
///
/// `--ss-app-overlay-top` is the header height when the shell has a
/// header (else 0). Fixed overlays inside the shell (the top toast
/// regions, `ss-c-messages--toast`) start below it, so they do not
/// cover the header controls.
///
/// `--scroll`: the whole document scrolls instead of `__main` (long pages,
/// scroll-driven players). The header sticks to the top, sidebars stick
/// below it, and the shell is at least one viewport tall.
///
/// Sidebar state is `data-state` on the sidebar: none (shown on wide
/// screens, hidden below `md`), `"open"` (shown; an overlay below `md`)
/// or `"closed"` (hidden). `SheetManager` drives it from a button with
/// `data-ss-sheet-toggle` and `aria-controls`; `SplitPaneManager` can
/// resize it via `--ss-app-sidebar-*-width`.
///
/// @group Layout
/// @author Scape Press
/// @link https://scape.style
/// @since 0.5.0
/// @access public
///
////

@use "../01-core/prefix" as *;
@use "../01-core/external" as *;
@use "breakpoints" as *;

@layer ss.layout {
    .#{$ss-prefix-layout}-app {
        --ss-app-header-height: #{q(56)};
        --ss-app-content-width: #{q(1152)};
        --ss-app-footer-height: #{q(32)};
        --ss-app-sidebar-width: #{q(280)};
        --ss-app-sidebar-left-width: var(--ss-app-sidebar-width);
        --ss-app-sidebar-right-width: var(--ss-app-sidebar-width);

        position: relative;
        box-sizing: border-box;
        display: grid;
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-rows: auto minmax(0, 1fr) auto;
        grid-template-areas:
            "header header header"
            "left   main   right"
            "footer footer footer";
        block-size: 100vh;
        block-size: 100dvh;
        inline-size: 100%;
        overflow: hidden;
    }

    // Fill a sized parent instead of the viewport (embedded demos, panels).
    .#{$ss-prefix-layout}-app--contained {
        block-size: 100%;
    }

    // Top offset for fixed overlays (toasts) inside a full-viewport shell.
    .#{$ss-prefix-layout}-app:not(.#{$ss-prefix-layout}-app--contained):has(
            > .#{$ss-prefix-layout}-app__header
        ) {
        --ss-app-overlay-top: var(--ss-app-header-height);
    }

    // Document-scrolling shell: the page scrolls, header and sidebars stick.
    .#{$ss-prefix-layout}-app--scroll {
        block-size: auto;
        min-block-size: 100vh;
        min-block-size: 100dvh;
        overflow: visible;

        > .#{$ss-prefix-layout}-app__header {
            position: sticky;
            inset-block-start: 0;
            z-index: var(--ss-z-navbar, 100);
        }

        > .#{$ss-prefix-layout}-app__main {
            overflow: visible;
        }
    }

    // ------------------------------------------------------------------------
    // Header and footer bars
    // ------------------------------------------------------------------------

    .#{$ss-prefix-layout}-app__header {
        grid-area: header;
        display: flex;
        align-items: center;
        gap: var(--ss-space-3);
        box-sizing: border-box;
        min-block-size: var(--ss-app-header-height);
        min-inline-size: 0;
        padding-inline: var(--ss-space-4);
        border-block-end: var(--ss-a-border-width-1, #{q(1)}) solid
            var(--ss-color-border);
    }

    // Pushes everything after it to the end of the header.
    .#{$ss-prefix-layout}-app__spacer {
        flex: 1 1 auto;
    }

    .#{$ss-prefix-layout}-app__footer {
        grid-area: footer;
        display: flex;
        align-items: center;
        gap: var(--ss-space-4);
        box-sizing: border-box;
        min-block-size: var(--ss-app-footer-height);
        min-inline-size: 0;
        padding-inline: var(--ss-space-4);
        overflow: hidden;
        border-block-start: var(--ss-a-border-width-1, #{q(1)}) solid
            var(--ss-color-border);
        white-space: nowrap;
    }

    // ------------------------------------------------------------------------
    // Sidebars
    // ------------------------------------------------------------------------

    .#{$ss-prefix-layout}-app__sidebar {
        grid-area: left;
        position: relative;
        box-sizing: border-box;
        inline-size: var(--ss-app-sidebar-left-width);
        max-inline-size: 100%;
        min-block-size: 0;
        overflow: auto;
        overscroll-behavior: contain;
        border-inline-end: var(--ss-a-border-width-1, #{q(1)}) solid
            var(--ss-color-border);
    }

    // Opt-in inner padding. The base sidebar has none, so content that sets
    // its own padding is not doubled.
    .#{$ss-prefix-layout}-app__sidebar--padded {
        padding: var(--ss-space-4);
    }

    .#{$ss-prefix-layout}-app__sidebar--right {
        grid-area: right;
        inline-size: var(--ss-app-sidebar-right-width);
        border-inline-end: 0;
        border-inline-start: var(--ss-a-border-width-1, #{q(1)}) solid
            var(--ss-color-border);
    }

    .#{$ss-prefix-layout}-app__sidebar[data-state="closed"] {
        display: none;
    }

    // ------------------------------------------------------------------------
    // Main viewport
    // ------------------------------------------------------------------------

    .#{$ss-prefix-layout}-app__main {
        grid-area: main;
        position: relative;
        box-sizing: border-box;
        min-inline-size: 0;
        min-block-size: 0;
        overflow: auto;
    }

    // Full-bleed host for a canvas, map or 3D view: no scrolling, and a
    // direct canvas / svg / iframe / video child fills the area.
    .#{$ss-prefix-layout}-app__main--bleed {
        overflow: hidden;

        > canvas,
        > svg,
        > iframe,
        > video {
            display: block;
            inline-size: 100%;
            block-size: 100%;
            border: 0;
        }

        // Any other host (a grid, a split pane) fills the area too, but
        // keeps its own display.
        > .#{$ss-prefix-layout}-app__fill {
            inline-size: 100%;
            block-size: 100%;
        }
    }

    // Centred reading column inside the main area (demo galleries, docs,
    // forms). Width from `--ss-app-content-width`.
    .#{$ss-prefix-layout}-app__content {
        box-sizing: border-box;
        max-inline-size: var(--ss-app-content-width);
        margin-inline: auto;
        padding: var(--ss-space-6) var(--ss-space-4);
    }

    // Wide charts and tables: a wider column, or the full main width.
    .#{$ss-prefix-layout}-app__content--wide {
        max-inline-size: calc(var(--ss-app-content-width) * 1.5);
    }
    .#{$ss-prefix-layout}-app__content--full {
        max-inline-size: none;
    }

    @include breakpoint-up("md") {
        .#{$ss-prefix-layout}-app--scroll > .#{$ss-prefix-layout}-app__sidebar {
            position: sticky;
            inset-block-start: var(--ss-app-header-height);
            align-self: start;
            max-block-size: calc(100vh - var(--ss-app-header-height));
            max-block-size: calc(100dvh - var(--ss-app-header-height));
        }
    }

    // ------------------------------------------------------------------------
    // Narrow viewports: sidebars overlay the main area
    // ------------------------------------------------------------------------

    @include breakpoint-down("md") {
        .#{$ss-prefix-layout}-app__sidebar {
            display: none;
            position: absolute;
            grid-row: 2;
            grid-column: 1 / -1;
            inset-block: 0;
            inset-inline-start: 0;
            z-index: var(--ss-z-navbar, 100);
            inline-size: min(
                var(--ss-app-sidebar-left-width),
                calc(100% - #{q(48)})
            );
        }

        .#{$ss-prefix-layout}-app__sidebar--right {
            inset-inline: auto 0;
            inline-size: min(
                var(--ss-app-sidebar-right-width),
                calc(100% - #{q(48)})
            );
        }

        .#{$ss-prefix-layout}-app__sidebar[data-state="open"] {
            display: block;
        }

        // In a scrolling shell the overlay stays in view below the header.
        .#{$ss-prefix-layout}-app--scroll > .#{$ss-prefix-layout}-app__sidebar {
            position: fixed;
            inset-block: var(--ss-app-header-height) 0;
        }
    }
}
