/**
 * Builder V8 — Utility Classes
 * Spacing helpers, text-colour helpers, display utilities.
 */

/* ---- Display ---- */
.v8-block          { display: block; }
.v8-inline-block   { display: inline-block; }
.v8-hidden         { display: none; }

@media (max-width: 767px) {
    .v8-hidden-mobile { display: none; }
}

@media (min-width: 768px) {
    .v8-hidden-desktop { display: none; }
}

/* ---- Text alignment ---- */
.v8-text-left    { text-align: left; }
.v8-text-center  { text-align: center; }
.v8-text-right   { text-align: right; }

/* ---- Text colours ---- */
.v8-text-primary   { color: var(--color-primary, #2563eb); }
.v8-text-secondary { color: var(--color-text-secondary, #475569); }
.v8-text-light     { color: var(--color-text-light, #94a3b8); }
.v8-text-on-dark   { color: var(--color-text-on-dark, #f8fafc); }
.v8-text-accent    { color: var(--color-accent, #f59e0b); }

/* ---- Font weight ---- */
.v8-font-normal   { font-weight: 400; }
.v8-font-medium   { font-weight: 500; }
.v8-font-semibold { font-weight: 600; }
.v8-font-bold     { font-weight: 700; }

/* ---- Margin helpers ---- */
.v8-mt-0  { margin-top: 0; }
.v8-mt-4  { margin-top: var(--space-4, 1rem); }
.v8-mt-6  { margin-top: var(--space-6, 1.5rem); }
.v8-mt-8  { margin-top: var(--space-8, 2rem); }
.v8-mb-0  { margin-bottom: 0; }
.v8-mb-4  { margin-bottom: var(--space-4, 1rem); }
.v8-mb-6  { margin-bottom: var(--space-6, 1.5rem); }
.v8-mb-8  { margin-bottom: var(--space-8, 2rem); }
.v8-mb-12 { margin-bottom: var(--space-12, 3rem); }
.v8-mx-auto { margin-inline: auto; }

/* ---- Padding helpers ---- */
.v8-p-4  { padding: var(--space-4, 1rem); }
.v8-p-6  { padding: var(--space-6, 1.5rem); }
.v8-p-8  { padding: var(--space-8, 2rem); }
.v8-px-4 { padding-inline: var(--space-4, 1rem); }
.v8-px-6 { padding-inline: var(--space-6, 1.5rem); }
.v8-py-4 { padding-block: var(--space-4, 1rem); }
.v8-py-8 { padding-block: var(--space-8, 2rem); }

/* ---- Width / sizing ---- */
.v8-w-full  { width: 100%; }
.v8-max-w-sm  { max-width: 480px; }
.v8-max-w-md  { max-width: 640px; }
.v8-max-w-lg  { max-width: 800px; }
.v8-max-w-xl  { max-width: 1024px; }

/* ---- Object fit ---- */
.v8-img-cover {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

/* ---- Rounded ---- */
.v8-rounded-sm  { border-radius: var(--radius-sm, 4px); }
.v8-rounded-md  { border-radius: var(--radius-md, 8px); }
.v8-rounded-lg  { border-radius: var(--radius-lg, 16px); }
.v8-rounded-xl  { border-radius: var(--radius-xl, 24px); }
.v8-rounded-full { border-radius: var(--radius-full, 9999px); }

/* ---- Overflow ---- */
.v8-overflow-hidden { overflow: hidden; }

/* ---- Position helpers ---- */
.v8-relative { position: relative; }
.v8-absolute { position: absolute; }
.v8-inset-0  { inset: 0; }

/* ---- Aspect ratios ---- */
.v8-aspect-video { aspect-ratio: 16 / 9; }
.v8-aspect-square { aspect-ratio: 1; }
.v8-aspect-4-3   { aspect-ratio: 4 / 3; }

/* ---- Dividers ---- */
.v8-divider {
    border: none;
    border-top: 1px solid var(--border-color, #e2e8f0);
    margin-block: var(--space-8, 2rem);
}

/* ---- Screen-reader only ---- */
.v8-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ============================================================
 * WP-012 — Franken UI responsive visibility helpers
 *
 * The vendored Franken UI build (2.0.0-internal.26) ships the legacy
 * `uk-navbar` / `uk-grid` class family but OMITS the `@s|@m|@l|@xl`
 * responsive visibility helpers entirely. The v8 block library and the
 * VH-003 verify probe both depend on `.uk-hidden@s` / `.uk-visible@s`
 * with desktop-first semantics:
 *
 *   .uk-hidden@s   = hidden on mobile (< 640 px), visible from @s up
 *   .uk-visible@s  = visible on mobile (< 640 px), hidden from @s up
 *
 * These mirror the block-library wrapping pattern in
 * `data/block-library/header.*.html`:
 *   <div class="uk-navbar-right uk-hidden@s"> ← desktop nav links
 *   <div class="uk-navbar-right uk-visible@s"> ← mobile hamburger
 *
 * `@s` corresponds to UIkit-3's small breakpoint (640px).
 * Class names contain `@` which is escaped in selectors as `\@`.
 * `!important` defends against inline `style="display:..."` drift
 * (see generator.md anti-example #2).
 * Do not extend this section without coordinating with VH-003's
 * mobile-nav assertion in `scripts/verify-pages.js`.
 * ============================================================ */

@media (max-width: 639px) {
    .uk-hidden\@s { display: none !important; }
}

@media (min-width: 640px) {
    .uk-visible\@s { display: none !important; }
}

/* ============================================================
 * WP-012-2b — Minimum uk-navbar flex layout + uk-hidden@s cascade
 *
 * Franken UI 2.0.0-internal.26 ships ~3091 `uk-*` selectors but ZERO
 * `uk-navbar*` rules. Without these, `<nav class="uk-navbar">` falls
 * back to default <nav> {display:block}, and the hamburger button
 * (an empty <span>×3 inline-block) collapses to 0×0 since UIkit-3's
 * `uk-navbar-item` padding/min-height never lands.
 *
 * Plus: VH-003's verify probe in scripts/verify-pages.js iterates
 * each `.v8-nav__link` and asserts `getComputedStyle(link).display`
 * is "none". Per CSS spec, `display:none` on a parent does NOT
 * propagate to a child's computed style — getComputedStyle returns
 * the child's own declared/inherited value (inline for <a>). So the
 * parent-only `.uk-hidden\@s { display:none }` rule above is correct
 * but insufficient for the probe; the descendant selector below
 * forces each link's own computed display to "none".
 *
 * Known constraint of these semantics: `.uk-hidden\@s *` is broad.
 * Any future block that uses `uk-hidden@s` on a parent which should
 * still display some descendants (e.g. an SR-only inner label) will
 * be hidden by this rule. Today the only project use is the header
 * navbar wrapper, so the blast radius is contained. If the v8 block
 * library grows additional `uk-hidden@s` usage, revisit by moving to
 * v8-native `v8-hidden-mobile` classes (see Path 3 in build/blockers.md).
 *
 * Do not extend without coordinating with VH-003's mobile-nav
 * assertion in `scripts/verify-pages.js`.
 * ============================================================ */

.uk-navbar { display: flex; align-items: center; justify-content: space-between; }
.uk-navbar-right, .uk-navbar-nav { display: flex; align-items: center; gap: 1rem; }
.uk-navbar-item { display: inline-flex; align-items: center; padding: 0 1rem; min-height: 60px; }

@media (max-width: 639px) {
    .uk-hidden\@s,
    .uk-hidden\@s * { display: none !important; }
}

/* ============================================================
 * WP-024 — @m / @l responsive visibility helpers (ADDITIVE)
 *
 * The WP-012 layer above only shipped the `@s` (640px) visibility
 * variants. The vendored Franken UI build omits `@m` (960px) and
 * `@l` (1200px) entirely, so any block using `uk-hidden@m` /
 * `uk-visible@m` / `uk-hidden@l` / `uk-visible@l` had NO effect — the
 * desktop nav could collapse and the hamburger could leak at those
 * breakpoints. This block restores them with the SAME desktop-first
 * inversion the project's block library expects (mirrors `@s`):
 *
 *   .uk-hidden@m   = hidden < 960px, visible from @m up
 *   .uk-visible@m  = visible < 960px, hidden from @m up
 *   .uk-hidden@l   = hidden < 1200px, visible from @l up
 *   .uk-visible@l  = visible < 1200px, hidden from @l up
 *
 * STRICTLY ADDITIVE: the `@s` rules and the `.uk-hidden\@s *`
 * descendant trick above are left byte-intact. The matching
 * `.uk-hidden\@m *` / `.uk-hidden\@l *` descendant rules are included
 * so VH-003's `getComputedStyle(link).display` probe (AC7) reads
 * "none" on each nav link at those breakpoints too. `!important`
 * matches the `@s` rules and defends against inline `style` drift.
 *
 * Do not extend this section (or the `@s` block above) without
 * coordinating with VH-003's mobile-nav assertion in
 * `scripts/verify-pages.js`.
 * ============================================================ */

@media (max-width: 959px) {
    .uk-hidden\@m,
    .uk-hidden\@m * { display: none !important; }
}

@media (min-width: 960px) {
    .uk-visible\@m { display: none !important; }
}

@media (max-width: 1199px) {
    .uk-hidden\@l,
    .uk-hidden\@l * { display: none !important; }
}

@media (min-width: 1200px) {
    .uk-visible\@l { display: none !important; }
}

/* ============================================================
 * VH-007 V2 — Hamburger icon lines
 *
 * Block-library header.sticky-solid.html emits the standard
 * `<button id="v8-hamburger">` with three empty <span> children
 * intended as the three horizontal bars. The franken-ui vendor
 * bundle does not include a `.v8-hamburger span` rule (it is a
 * project-local class), so without these declarations the spans
 * collapse to 0x0 and the hamburger renders as an invisible
 * click target on mobile (verify probe's offsetWidth>0 assertion
 * still passes because the button itself has padding).
 * ============================================================ */

.v8-hamburger {
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    background: transparent;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
    color: var(--color-text-primary, #0f172a);
}

.v8-hamburger span {
    display: block;
    width: 22px;
    height: 2px;
    background-color: currentColor;
    border-radius: 1px;
    transition: transform 200ms ease, opacity 200ms ease;
}
