/**
 * Page Designer — PAGE LAYOUT ENGINE (shared single source of truth, live half)
 * ═══════════════════════════════════════════════════════════════════════════
 * The ONE stylesheet that owns responsive component layout — how content stacks,
 * sizes and reflows — for every block, on every surface. Loaded on the editor
 * canvas, the public web page, the admin override page, AND the element-block
 * live-preview frame, so layout behaviour can NEVER drift between contexts.
 *
 * Guidance / rationale / tiers / thresholds: saved_scripts/page_layout_formula.md
 * Sibling SoT (look & feel, NOT mechanics): the 10 core web design principles
 *   (top of pd_preset_blocks.js + saved_scripts/global_theme_preset_formula.md).
 *
 * NON-NEGOTIABLE RULES (see the formula doc):
 *   1. Reflow by the CONTAINER (column) width, never the viewport.
 *   2. Text is never clipped — it wraps.
 *   3. No horizontal scrollbars except real data tables.
 *   4. Equal-height rows, even gutters, aligned columns.
 *   5. Media is fluid (max-width:100%).
 *   6. Pure CSS, zero runtime, no bloat.
 *   7. Dynamic — keyed to stable attributes so every current AND future block is
 *      governed automatically.
 *   8. Graceful @supports fallback to an intrinsic auto-fit grid.
 *
 * SCOPE NOTE: today the engine governs ELEMENT BLOCKS (hosted admin widgets that
 * use viewport-based grids and must be re-flowed to fit their column). Preset and
 * web blocks already lay out via the authored .gjs-row/.gjs-cell column system, so
 * they are deliberately NOT swept here yet — extending the engine to opt-in preset
 * blocks is a separate, individually-tested step (per the formula doc). The file
 * loads everywhere now so that extension needs no new wiring.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Make every element block a SIZE CONTAINER, so its hosted widget responds to its
   OWN column width (CSS container queries). Automatic for every current AND future
   element block (keyed to the data-pd-block attribute), zero runtime. */
[data-pd-block="element"] {
    container-type: inline-size;
    container-name: pdelem;
    /* Clip contents to the frame so a Design-panel border-radius actually rounds
       the hosted widget's corners — without this the square widget sits on top of
       the rounded frame and hides the curve. The wrapper grows with its content,
       so this only trims the corners; it never crops the widget. */
    overflow: hidden;
}

/* Base card-grid (shared look + fallback): auto-fit so it still adapts even
   without container-query support; equal-height rows; tidy gap. */
[data-pd-block="element"] .row,
[data-pd-block="element"] [class*="tw-grid"] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
    grid-auto-rows: 1fr;
    gap: 16px; /* 8-point rhythm */
    margin-left: 0;
    margin-right: 0;
}
/* Bootstrap .row adds ::before/::after clearfix spacers. Inside a grid those
   become phantom cells that shove the cards out of alignment — remove them. */
[data-pd-block="element"] .row::before,
[data-pd-block="element"] .row::after {
    content: none;
}

/* Precise column counts keyed to the COLUMN width (container queries). RULE:
   a half-width column (≈ up to ~860px) always stacks ONE big card per row;
   multi-column only kicks in as the column grows toward full width. Tweakable. */
@supports (container-type: inline-size) {
    @container pdelem (max-width: 859px) {
        [data-pd-block="element"] .row,
        [data-pd-block="element"] [class*="tw-grid"] { grid-template-columns: 1fr; }
    }
    @container pdelem (min-width: 860px) {
        [data-pd-block="element"] .row,
        [data-pd-block="element"] [class*="tw-grid"] { grid-template-columns: repeat(2, 1fr); }
    }
    @container pdelem (min-width: 1160px) {
        [data-pd-block="element"] .row,
        [data-pd-block="element"] [class*="tw-grid"] { grid-template-columns: repeat(3, 1fr); }
    }
    @container pdelem (min-width: 1460px) {
        [data-pd-block="element"] .row,
        [data-pd-block="element"] [class*="tw-grid"] { grid-template-columns: repeat(4, 1fr); }
    }
}
/* Neutralise the widget's own fixed column widths so the grid controls sizing */
[data-pd-block="element"] .row > [class*="col-"] {
    width: auto;
    max-width: 100%;
    flex: none;
    float: none;
    padding-left: 0;
    padding-right: 0;
    min-width: 0;
}
/* Flex card rows → allow wrapping */
[data-pd-block="element"] [class*="tw-flex"]:not([class*="tw-flex-col"]) {
    flex-wrap: wrap;
}
/* A widget row that is ITSELF a flex layout (Bootstrap .row + Tailwind tw-flex —
   e.g. a "stats | chart" widget) must NOT be forced into the card-grid above: that
   creates fixed empty tracks and squashes the content into ~half the width of a
   full-width block. Keep it as native flex so it fills the width; the wrap rule
   directly above still lets it stack on narrow columns. (0,0,3,0) beats the grid
   rules' (0,0,2,0), and being outside @container it wins at every width. */
[data-pd-block="element"] .row[class*="tw-flex"] {
    display: flex;
    grid-template-columns: none;
}

/* Rule 2 — never clip text: unwind truncation so labels wrap when space is tight */
[data-pd-block="element"] .tw-truncate,
[data-pd-block="element"] [class*="truncate"] {
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    min-width: 0;
}

/* Rule 3 — no horizontal scrollbars on widget surfaces (tables keep their own) */
[data-pd-block="element"] :is(.panel_s, .widget, .card, .panel, .row, [class*="tw-grid"]) {
    overflow-x: visible;
}

/* Reading measure — long-form paragraph text capped to ~72 characters per line so
   a wide column never produces unreadable over-long lines (50–75 CPL research).
   Inert on narrow cards/stats; only bites on genuinely wide prose. */
[data-pd-block="element"] p {
    max-width: 72ch;
}

/* Hosted widget panels carry Perfex's inter-panel bottom margin (~25px) used to
   space stacked dashboard panels. Inside an element block there's a single widget,
   so that margin is just dead space between the widget and the frame — drop it so
   the frame hugs the widget. The panel's own inner padding (its breathing room) is
   left intact. Global: applies to any hosted panel-based widget. */
[data-pd-block="element"] .panel_s {
    margin-bottom: 0;
}
