/* =========================================================================
   layout-app.css — Bare-element grid layout
   Loaded only by pages using the bare `.app` / `aside` / `#previewArea` /
   `#resizer` grid layout (b-spline-gen index.html, b-spline-gen
   bspline_gen_palette.html, frame-builder index.html).
   Contains:
   - .app grid container + responsive variants
   - header grid placement
   - aside, #previewArea, #resizer, #bottomStatusBar grid placement
   - .sticky-actions (sidebar pinned action block)
   - Color-coded panel border-left accents (.panel-stock etc.)
   - Sub-panel system (.panel-sub)
   - .panel-filter-tweaks + .tweak-row + .ck-toggle (b-spline-gen-specific)
   - Header button positioning overrides (#btnDownload, #theme-btn etc.)
   - Mobile/vertical responsive @media blocks (max-width: 700px / 400px)
   ========================================================================= */

/* =========================================================================
   1. Main app grid (3 columns: sidebar | resizer | preview)
   ========================================================================= */
.app {
    --sidebar-width: 320px;
    --preview-height: 50vh;
    display: grid;
    grid-template-columns: var(--sidebar-width) 8px 1fr;
    /* 8px for the resizer */
    grid-template-rows: auto 1fr auto auto;
    width: 100%;
    height: 100%;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
}

/* Header spans full width of grid in app layout */
header {
    grid-column: 1 / -1;
}

/* Sidebar */
aside {
    grid-column: 1;
    grid-row: 2;
    border-right: none;
    background: var(--surface);
    overflow-y: auto;
    padding: 14px 14px 60px 14px;
    display: flex;
    flex-direction: column;
    gap: var(--gap);
    min-height: 0;
}

/* Pin the seed + undo/redo block to the top of the sidebar so it
   remains accessible regardless of which panels are scrolled. The
   negative margins extend it edge-to-edge over the aside's padding,
   and top:-14px compensates for that same padding so it sits flush
   at the top of the scroll viewport. */
.sticky-actions {
    position: sticky;
    top: -14px;
    z-index: 20;
    margin: -14px -14px 0 -14px;
    padding: 12px 14px 10px 14px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 4px 6px -4px rgba(0, 0, 0, 0.18);
}

/* =========================================================================
   2. Color-coded panel accents
   ========================================================================= */
.panel-stock {
    border-left-color: #64748b;
}

.panel-terrain {
    border-left-color: #0066cc;
}

.panel-smooth {
    border-left-color: #8b5cf6;
}

.panel-sculpt-t {
    border-left-color: #059669;
}

.panel-thicken {
    border-left-color: #d97706;
}

.panel-sculpt-b {
    border-left-color: #dc2626;
}

.panel-stamp {
    border-left-color: #20c997;
}

.panel-resolution {
    border-left-color: #65a30d;
}

.panel-preset {
    border-left-color: #0e7490;
}

/* =========================================================================
   3. Sub-panels (nested category groupings)
   ========================================================================= */
.panel-sub {
    background: rgba(0, 0, 0, 0.02);
    border-left: 2px solid rgba(0, 0, 0, 0.08);
    border-radius: 3px;
    overflow: hidden;
    flex-shrink: 0;
}

.panel-sub .panel-header {
    font-size: 10px;
    padding: 5px 10px;
    background: rgba(0, 0, 0, 0.03);
    letter-spacing: 0.08em;
}

.panel-sub .panel-header::before {
    font-size: 11px;
}

.panel-sub.collapsed .panel-header::before {
    transform: rotate(-90deg);
}

.panel-sub.collapsed .panel-body {
    display: none;
}

/* =========================================================================
   4. Edit-Filter sub-panel (b-spline-gen tweak sliders)
   ========================================================================= */
.panel-filter-tweaks .panel-header {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* The label span eats remaining space so the Reset button hugs the right.
   The chevron ::before pseudo-element stays left of the label. */
.panel-filter-tweaks .panel-header > span {
    flex: 1;
}

.filter-tweaks-reset {
    all: unset;
    cursor: pointer;
    font-size: 10px;
    letter-spacing: 0.04em;
    padding: 2px 8px;
    border-radius: 3px;
    color: var(--text-dim, #64748b);
    border: 1px solid var(--border, rgba(0, 0, 0, 0.12));
    background: var(--surface, #fff);
    text-transform: none;
}

.filter-tweaks-reset:hover {
    color: var(--text);
    background: var(--surface2, rgba(0, 0, 0, 0.04));
}

.panel-filter-tweaks .panel-body {
    gap: 8px;
    display: flex;
    flex-direction: column;
    padding-top: 8px;
}

.tweak-row {
    gap: 4px;
}

.tweak-row > .slider-row > input[type=range] {
    flex: 1;
    min-width: 0;
    accent-color: var(--accent);
}

.tweak-row > span {
    font-size: 11px;
    letter-spacing: 0.02em;
}

.tweak-row.tweak-modified > span {
    color: var(--accent, #2563eb);
    font-weight: 600;
}

.tweak-row.tweak-modified > span::after {
    content: ' •';
}

.tweak-reset {
    all: unset;
    cursor: pointer;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    color: var(--text-dim, #64748b);
    border-radius: 3px;
}

.tweak-reset:hover {
    color: var(--text);
    background: var(--surface2, rgba(0, 0, 0, 0.06));
}

/* =========================================================================
   5. ck_ constraint toggles (b-spline-gen)
   ========================================================================= */
.ck-toggle-wrap .slider-header {
    padding-bottom: 0;
}

.ck-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    cursor: pointer;
    user-select: none;
}

.ck-toggle input[type=checkbox] {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--good);
}

.ck-toggle.ck-on {
    color: var(--good);
}

.ck-toggle.ck-off {
    color: var(--text-dim);
}

/* =========================================================================
   6. Header button overrides (b-spline-gen header)
   ========================================================================= */
#btnDownload {
    background: linear-gradient(180deg, #1d4ed8, #2563eb) !important;
    color: #ffffff !important;
    border-color: #1e40af !important;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
    font-weight: 700;
    min-width: 84px !important;
    padding: 0 14px !important;
}

#btnDownloadAddin {
    min-width: 84px !important;
    padding: 0 14px !important;
}

#theme-btn,
#settings-btn {
    width: 32px !important;
    min-width: 32px !important;
    padding: 0 !important;
}

#btnDownload:hover {
    background: linear-gradient(180deg, #2563eb, #1d4ed8) !important;
}

/* =========================================================================
   7. Preview area
   ========================================================================= */
#previewArea {
    grid-column: 3;
    grid-row: 2;
    border-left: none;
    position: relative;
    background: transparent !important;
    overflow: hidden;
    padding: 0;
    min-height: 0;
    min-width: 0;
    display: flex;
    align-items: stretch;
    justify-content: stretch;
    width: 100%;
    height: 100%;
}

#previewCanvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    opacity: 0;
    background: transparent !important;
}

#previewCanvas.ready {
    animation: canvasFadeIn 2s ease-out both;
}

@keyframes canvasFadeIn {
    to { opacity: 1; }
}

.preview-hint {
    position: absolute;
    bottom: 12px;
    right: 14px;
    font-size: 11px;
    color: var(--muted);
    pointer-events: none;
    background: rgba(255, 255, 255, .8);
    padding: 3px 8px;
    border-radius: 4px;
    border: 1px solid var(--border);
}

/* =========================================================================
   8. Bottom status bar
   ========================================================================= */
#bottomStatusBar {
    grid-row: 4;
}

/* =========================================================================
   9. Resizer
   ========================================================================= */
#resizer {
    grid-column: 2;
    grid-row: 2;
    background: var(--surface2);
    border-left: 1px solid var(--border);
    border-right: 1px solid var(--border);
    cursor: col-resize;
    touch-action: none;
    /* Prevent scroll on mobile drag */
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 50;
    transition: background 0.1s;
}

#resizer:hover,
#resizer:active {
    background: #d4d4d4;
}

/* Little grip lines */
#resizer::after {
    content: '';
    display: block;
    width: 2px;
    height: 24px;
    background: #a0a0a0;
    border-radius: 2px;
}

/* =========================================================================
   10. Responsive — Vertical / Mobile layout
   =========================================================================
   index.html uses bare elements (`.app`, `aside`, `#previewArea`,
   `#resizer`) rather than the `.cad-*` palette layout. These rules stack
   the sections in a single column when the viewport gets narrow:
     row 1 — header
     row 2 — 3D preview (anchored, fixed height)
     row 3 — horizontal resizer
     row 4 — sidebar (panels), takes remaining space
     row 5 — bottom status bar
   The aside flips back to a normal block flow so its panels lay out
   top-to-bottom under the preview, instead of being squished into a
   320px column. */
@media (max-width: 700px) {
    .app {
        --sidebar-width: 100%;
        --preview-height: 40vh;
        grid-template-columns: 1fr !important;
        grid-template-rows: auto var(--preview-height) 12px 1fr auto !important;
    }

    header {
        grid-column: 1 !important;
        grid-row: 1 !important;
    }

    #previewArea {
        grid-column: 1 !important;
        grid-row: 2 !important;
        border-left: none;
        border-bottom: 1px solid var(--border);
        min-height: 0;
    }

    #resizer {
        grid-column: 1 !important;
        grid-row: 3 !important;
        width: 100% !important;
        height: 12px !important;
        cursor: row-resize !important;
        border-left: none !important;
        border-right: none !important;
        border-top: 1px solid var(--border);
        border-bottom: 1px solid var(--border);
    }

    #resizer::after {
        width: 32px;
        height: 2px;
    }

    aside {
        grid-column: 1 !important;
        grid-row: 4 !important;
        width: 100%;
        border-right: none;
        border-top: none;
        padding: 12px 12px 60px 12px;
    }

    #bottomStatusBar {
        grid-column: 1 !important;
        grid-row: 5 !important;
    }

    /* Sticky seed/undo block stays pinned at top of the (now bottom)
       sidebar — user can still reach it without scrolling within the
       sidebar block. Pull padding compensation matches the new aside
       padding above. */
    .sticky-actions {
        top: -12px;
        margin: -12px -12px 0 -12px;
        padding: 10px 12px 8px 12px;
    }
}

@media (max-width: 400px) {
    .app {
        --preview-height: 35vh;
    }
    header {
        padding: 8px 10px;
        gap: 8px;
    }
}
