/*
 * VLINZZA — GeneratePress Bridge
 * Layer 3 of 4. Depends on tokens.css and base.css; loads before
 * global-classes.css so component rules can always override a bridge rule.
 *
 * ===========================================================================
 * WHAT BELONGS IN THIS FILE
 * ===========================================================================
 *
 * ONLY rules that exist because of a real contact point with the
 * GeneratePress parent theme. Every rule must state:
 *
 *   - the exact GeneratePress selector or behaviour it answers;
 *   - the file or output that produces it;
 *   - what breaks without the rule;
 *   - how to re-test it after a parent-theme update.
 *
 * WHAT DOES NOT BELONG HERE
 *
 *   - component styling of any kind (that is global-classes.css);
 *   - project design values (those come from theme.json via tokens.css);
 *   - Elementor compatibility of any kind — Elementor is not part of this
 *     architecture and no rule here may reference its markup or classes;
 *   - anything keyed to a WordPress page ID, post ID or page title.
 *
 * This file is deliberately short. It is the whole of the project's coupling
 * to GeneratePress internals, so a parent-theme update has exactly one place
 * to be re-verified. Verified against GeneratePress 3.6.1.
 *
 * ===========================================================================
 * BRIDGE INVENTORY — 7 rules
 * ===========================================================================
 *   B-1   Site-content flex row      .vlz-marketing .site-content
 *   B-2   Shell width constraint     .vlz-marketing .site
 *   B-3   Classic group wrapper      .wp-block-group__inner-container (scoped)
 *   B-4a  Core button colour         .wp-block-button:not(.vlz-btn) > .wp-block-button__link
 *   B-4b  Core button geometry       .wp-block-button:not(.vlz-btn) > .wp-block-button__link
 *   B-5   Editor button metrics      .block-editor-block-list__layout .wp-block-button .wp-block-button__link
 *   B-6   Site-content gutter (inline + block) .vlz-marketing.one-container .site-content
 *
 * B-1, B-2 and B-6 are front-end only and scoped to the marketing template.
 * B-3, B-4a and B-4b apply to both surfaces. B-5 is editor-only.
 * ===========================================================================
 */

/* ===================================================================
 * B-1 — GeneratePress lays the content area out as a flex row
 *
 * GeneratePress source:
 *   assets/css/main.min.css → `.site-content { display: flex }`
 *
 * Why it exists: GeneratePress uses that flex row to place the content area
 * beside a sidebar. The VLINZZA Marketing Page has no sidebar and renders its
 * own boundary (.vlz-page) directly inside .site-content, so the flex context
 * would make the project boundary a flex item and stop it filling the row.
 *
 * Without the rule: .vlz-page shrinks to its content and full-width sections
 * stop reaching the viewport edges.
 *
 * Scope: the marketing template only, via the body class the template adds.
 * Every other GeneratePress template keeps the parent behaviour untouched.
 *
 * Re-test after a parent update: full-width section spans the viewport at
 * 1440 / 768 / 390 px.
 * =================================================================== */
.vlz-marketing .site-content {
	display: block;
}

/* ===================================================================
 * B-2 — GeneratePress constrains the shell to its container width
 *
 * GeneratePress source:
 *   header.php → `<div class="site grid-container container hfeed" id="page">`
 *   assets/css/main.min.css → `.grid-container { max-width: 1200px; margin-inline: auto }`
 *   (the 1200px value is the Customizer container width, re-emitted in the
 *   dynamic `generate-style-inline-css` block)
 *
 * Why it exists: that wrapper sits between the viewport and the VLINZZA
 * content boundary. While it is capped, a project section can never be wider
 * than the parent theme's container, so `.alignfull` cannot be full-bleed and
 * `.alignwide` cannot exceed the content width.
 *
 * This is the single point where the project takes ownership of content
 * measure. Once it is released here, width is decided only by
 * `--wp--style--global--content-size` / `--wp--style--global--wide-size`,
 * both of which come from theme.json. The parent theme's container width
 * continues to govern the GeneratePress shell — header, footer and every
 * template that is not the marketing template.
 *
 * `.site` is used rather than `#page` on purpose: it is a class the parent
 * theme documents, and it avoids an ID selector.
 *
 * Without the rule: full-width sections stop at 1200px and the page shows a
 * white band on each side.
 *
 * Re-test after a parent update: confirm the wrapper still carries `.site`
 * and that a `.alignfull` section measures the full client width.
 * =================================================================== */
.vlz-marketing .site {
	max-inline-size: none;
}

/* ===================================================================
 * B-6 — GeneratePress pads the content column for the one-container layout
 *
 * GeneratePress source (dynamic `generate-style-inline-css`, produced by
 *   inc/css-output.php lines 787 and 940, values from the Customizer's own
 *   Layout → Content spacing fields, `inc/defaults.php` lines 351-357):
 *     .one-container .site-content { padding: <content_top/right/bottom/left> }
 *     @media (max-width:768px) {
 *       .one-container .site-content { padding: <mobile_content_top/right/bottom/left> }
 *     }
 *   Measured on App: desktop `content_top`/`content_bottom` = 0 (Owner-configured),
 *   but `mobile_content_top`/`mobile_content_bottom` were never set away from the
 *   GeneratePress default of `30px` each — so 60px of vertical padding survives
 *   under the parent's own `(max-width:768px)` query even though desktop is 0.
 *
 * Why it exists: B-2 releases the `.site` shell's max-width, but `.site-content`
 * itself still carries this padding from the parent's one-container layout, on
 * BOTH axes. `.vlz-content > .alignfull` releases ITS OWN max-width and padding
 * (global-classes.css) so it fills `.vlz-content` exactly — it does not
 * out-dent past an ancestor's padding the way the pre-template `100vw`
 * negative-margin mechanism did. Left unaddressed on the inline axis, every
 * `.alignfull` section stopped short of the viewport edge on both sides: not a
 * defect on its own, but it meant a project full-bleed section was never
 * actually full-bleed under this template, and the resulting gutter combined
 * with a still-live parent-theme selector produced an asymmetric few-pixel
 * inline shift at narrow widths (report `SEO-EXPERT-TPL-B-01` mobile-clipping
 * finding, 2026-08-14). Left unaddressed on the block axis, the same parent
 * padding shows up as a 60px vertical gap between Header and Hero on every
 * Marketing Page at ≤768px width only — desktop stays 0px because the
 * Customizer's desktop value is already 0 (report
 * `HEADER-APP-MOBILE-TABLET-HERO-GAP-FIX.md`, 2026-09-07).
 *
 * This rule is the direct, minimal completion of B-2 for the one remaining
 * parent-theme padding source, on both its inline and block axes. It does not
 * touch `.site-content` display or width — B-1 already owns those — only its
 * own padding, and only under the marketing template.
 *
 * Without the rule: `.alignfull` sections render inset from the viewport by
 * the parent theme's content-column padding instead of true full-bleed, and a
 * 60px Header-to-Hero gap reappears at ≤768px width.
 *
 * Re-test after a parent update: confirm `.one-container .site-content` still
 * carries a padding declaration (desktop and the `(max-width:768px)` query),
 * and that a `.alignfull` section reaches the exact client width with zero
 * left/right asymmetry AND the Hero starts at the header's exact bottom edge
 * (gap = 0px) at 1440 / 1280 / 768 / 390 / 320 px.
 * =================================================================== */
.vlz-marketing.one-container .site-content {
	padding: 0;
}

/* ===================================================================
 * B-3 — The classic-theme group wrapper
 *
 * GeneratePress source (dynamic `generate-style-inline-css`, produced by
 *   inc/css-output.php lines 72, 790 and 943 and inc/block-editor.php line 295):
 *     .wp-block-group__inner-container            { max-width: 1200px; margin-inline: auto }
 *     .site-main .wp-block-group__inner-container { padding: 30px }
 *
 * Why it exists: before this theme had a theme.json, WordPress wrapped every
 * `core/group` child set in `.wp-block-group__inner-container`, and the two
 * parent rules above applied at EVERY nesting level, so they compounded — a
 * pattern four groups deep lost 120px of inline space per side and was
 * clamped to 1200px four times over (measured chain 820 → 740 → 663 → 583px
 * during the LocalWP runtime validation, report 07 §F-1).
 *
 * Status after theme.json — verified in WordPress 7.0.2:
 *
 *   wp-includes/block-supports/layout.php → wp_restore_group_inner_container()
 *   returns the block untouched when `wp_theme_has_theme_json()` is true, so
 *   the wrapper is no longer injected at render time. Measured on the
 *   Foundation runtime: 18 wrappers in the DOM before this task, 0 after.
 *
 *   The SAME function also returns untouched when the stored markup already
 *   contains the wrapper (layout.php line 1102). Content that carries
 *   `wp-block-group__inner-container` literally in the database — anything
 *   authored under an older setup, imported, or pasted as raw block markup —
 *   therefore still renders it, and the parent theme still styles it.
 *
 * The rule is RETAINED for exactly that case. It is not dead code: it is
 * verified against a purpose-built legacy-markup page in the task report,
 * section 11. It is scoped to VLINZZA elements, so nothing outside the
 * project boundary is affected.
 *
 * Specificity matches the parent's (0,2,0) and this file loads after the
 * parent's inline CSS, so the reset wins on order without `!important`.
 *
 * Re-test after a parent update: re-render a page saved before 2026-08-04 and
 * confirm the section still measures the full content width.
 * =================================================================== */
.vlz-section .wp-block-group__inner-container,
.vlz-container .wp-block-group__inner-container,
.vlz-stack > .wp-block-group__inner-container,
.vlz-grid > .wp-block-group__inner-container,
.vlz-hero > .wp-block-group__inner-container,
.vlz-card > .wp-block-group__inner-container,
.vlz-card__icon > .wp-block-group__inner-container,
.vlz-cta > .wp-block-group__inner-container {
	max-inline-size: none;
	padding: 0;
}

/* ===================================================================
 * B-4a — GeneratePress colours the core button above theme.json
 *
 * GeneratePress source (dynamic `generate-style-inline-css`, inc/css-output.php):
 *   a.wp-block-button__link:not(.has-background) { background-color: #55555e; color: #fff }
 *   …:not(.has-background):hover                 { background-color: #3f4047 }
 *
 * Why it exists: that selector is (0,2,1). WordPress emits the theme.json
 * button style as `:root :where(.wp-element-button, .wp-block-button__link)`,
 * which is (0,1,0). The parent theme therefore wins on the front end, while
 * the block editor — which has no GeneratePress dynamic CSS around the
 * canvas button — shows the theme.json colour. The result is a button that
 * looks different in the editor and on the page.
 *
 * This rule re-asserts the theme.json values at the parent's own selector
 * shape so the design system owns the default button on both surfaces. The
 * VALUES are not duplicated: they are read from the same preset custom
 * properties theme.json generates, so the colour still has one origin.
 *
 * The `a` element selector GeneratePress uses is deliberately NOT copied. The
 * block editor renders the button label as a contenteditable `div`, not an
 * anchor, so an `a`-qualified rule silently stopped at the canvas boundary and
 * the editor showed the parent theme's grey #55555e while the front end showed
 * the brand colour. Matching on the class alone covers both surfaces.
 *
 * `:not(.has-background)` is kept deliberately. When an editor picks an
 * explicit background, core adds `.has-background` and both this rule and
 * GeneratePress stand aside — the same contract the parent theme honours.
 *
 * `.wp-block-button:not(.vlz-btn) >` scopes the rule to the DEFAULT core
 * button only. Project buttons are excluded structurally rather than by
 * specificity: an earlier draft of this rule reached (0,3,1) on `:hover` and
 * silently repainted the transparent secondary button, which specificity
 * arithmetic alone made easy to miss. The bridge now governs exactly one
 * thing — the button WordPress renders when no VLINZZA class is applied.
 *
 * Without the rule: default core buttons render GeneratePress grey #55555e on
 * the front end and brand blue in the editor.
 *
 * Re-test after a parent update: insert a plain core/button with no VLINZZA
 * class and compare its computed background in the editor and on the page.
 * =================================================================== */
.wp-block-button:not(.vlz-btn) > .wp-block-button__link:not(.has-background) {
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--text-invert);
}

.wp-block-button:not(.vlz-btn) > .wp-block-button__link:not(.has-background):hover,
.wp-block-button:not(.vlz-btn) > .wp-block-button__link:not(.has-background):focus,
.wp-block-button:not(.vlz-btn) > .wp-block-button__link:not(.has-background):active {
	background-color: var(--wp--preset--color--primary-strong);
	color: var(--wp--preset--color--text-invert);
}

/*
 * B-4b — the same divergence for button GEOMETRY.
 *
 * GeneratePress source (assets/css/main.min.css):
 *   .wp-block-button .wp-block-button__link { padding: 10px 20px; display: inline-block }
 *   .wp-block-button .wp-block-button__link { font-size: inherit; line-height: inherit }
 *
 * That selector is (0,2,0) and outranks the theme.json button rule at (0,1,0),
 * so the parent theme silently replaced the design system's padding, size and
 * leading on the front end while the editor showed the theme.json values.
 * Measured before this rule: 20px inline padding on the front end against the
 * 28px theme.json declares.
 *
 * The declarations below match the parent's selector shape exactly, so they
 * win on load order, and they read the same custom properties theme.json
 * reads — the metrics still have a single origin in tokens.css, and they stay
 * responsive because tokens.css redefines them per breakpoint.
 *
 * Scoped with `:not(.vlz-btn)` for the same reason as B-4a: project buttons
 * are excluded structurally, not by relying on load order.
 * =================================================================== */
.wp-block-button:not(.vlz-btn) > .wp-block-button__link {
	padding-block: var(--vlz-space-2xs);
	padding-inline: var(--vlz-control-padding-inline);
	border-radius: var(--vlz-radius-pill);
	font-size: var(--vlz-control-font-size);
	font-weight: var(--vlz-weight-semibold);
	line-height: var(--vlz-leading-tight);
}

/* ===================================================================
 * B-5 — GeneratePress overrides button metrics inside the editor canvas
 *
 * GeneratePress source:
 *   assets/css/admin/block-editor.css, lines 88-93
 *     .block-editor-block-list__layout .wp-block-button .wp-block-button__link,
 *     .block-editor-block-list__layout .button {
 *       font-size: inherit; padding: 10px 15px; line-height: normal;
 *     }
 *
 * Why it exists: that selector is (0,3,0), which outranks the project's
 * `.vlz-btn .wp-block-button__link` at (0,2,0). It is an editor-only
 * stylesheet, so it produced a button that was correct on the front end and
 * wrong in the canvas — measured 10px/15px padding in the editor against the
 * design system's 8px/28px on the page, plus `line-height: normal` instead of
 * the tight control leading.
 *
 * Loading the project layers after the parent's editor CSS (see
 * inc/enqueue.php, vlz_block_editor_styles) fixes ORDER but not SPECIFICITY,
 * so this rule matches the parent's selector shape exactly and wins on order.
 *
 * It reads the same tokens the component layer reads, so the metrics still
 * have one origin and remain responsive.
 *
 * Scope: this selector only ever exists inside the block editor, so the rule
 * is inert on the front end.
 *
 * Without the rule: buttons look visibly different in the editor and on the
 * page, which is the parity document 83 §6 requires.
 *
 * Re-test after a parent update: compare the computed padding, font-size and
 * line-height of a project button in the canvas and on the front end.
 * =================================================================== */
.block-editor-block-list__layout .wp-block-button .wp-block-button__link {
	padding-block: var(--vlz-space-2xs);
	padding-inline: var(--vlz-control-padding-inline);
	font-size: var(--vlz-control-font-size);
	line-height: var(--vlz-leading-tight);
}
