/* ─── Base Elements ─────────────────────────────────────────────────────── */

/* Minimal reset: remove browser defaults that trip up layouts */
*, *::before, *::after { box-sizing: border-box; }

html {
    scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

body {
    margin: 0;
    font-family: var(--font-body);
    font-weight: var(--font-weight-body, 400);
    font-size: calc(var(--fs-body) * var(--hzo-type-scale, 1) * var(--hzo-body-scale, 1));
    line-height: var(--body-line-height, 1.6);
    letter-spacing: var(--body-letter-spacing, normal);
    color: var(--text-body);
    background-color: var(--bg-page);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
    font-family: var(--font-heading);
    font-weight: var(--font-weight-heading, 400);
    line-height: 1.15;
    color: var(--text-heading);
    margin: 0 0 var(--space-md);
}

h5, h6 {
    font-family: var(--font-body);
    color: var(--text-heading);
    margin: 0 0 var(--space-md);
}

/* Headings — 7-zone responsive scale matching the six CSS breakpoints
   (480, 768, 1024, 1250, 1440, 1920). Each level's font-size reads its
   --fs-* token through the scale multipliers; the breakpoint blocks below
   redefine only the tokens (on :root), so the hand-tuned ladder is preserved
   and the .hzo-visual-* classes reuse the same tokens. h1-h4 follow the
   heading-size control; h5/h6 (small label text) follow the body-size one.
   font-weight falls back to each level's tuned weight until the widget sets
   --font-weight-heading. */
h1 { font-size: calc(var(--fs-h1) * var(--hzo-type-scale, 1) * var(--hzo-heading-scale, 1) * var(--h1-scale, 1)); font-weight: var(--font-weight-heading, var(--h1-weight, 700)); line-height: 1.05; color: var(--h1-color, var(--text-heading)); }
h2 { font-size: calc(var(--fs-h2) * var(--hzo-type-scale, 1) * var(--hzo-heading-scale, 1) * var(--h2-scale, 1)); font-weight: var(--font-weight-heading, var(--h2-weight, 700)); line-height: 1.1; color: var(--h2-color, var(--text-heading)); }
h3 { font-size: calc(var(--fs-h3) * var(--hzo-type-scale, 1) * var(--hzo-heading-scale, 1) * var(--h3-scale, 1)); font-weight: var(--font-weight-heading, var(--h3-weight, 600)); line-height: 1.2; color: var(--h3-color, var(--text-heading)); }
h4 { font-size: calc(var(--fs-h4) * var(--hzo-type-scale, 1) * var(--hzo-heading-scale, 1) * var(--h4-scale, 1)); font-weight: var(--font-weight-heading, var(--h4-weight, 600)); line-height: 1.3; color: var(--h4-color, var(--text-heading)); }
h5 { font-size: calc(var(--fs-h5) * var(--hzo-type-scale, 1) * var(--hzo-body-scale, 1) * var(--h5-scale, 1)); font-weight: var(--font-weight-heading, var(--h5-weight, 500)); line-height: 1.4; color: var(--h5-color, var(--text-heading)); }
h6 { font-size: calc(var(--fs-h6) * var(--hzo-type-scale, 1) * var(--hzo-body-scale, 1) * var(--h6-scale, 1)); font-weight: var(--font-weight-heading, var(--h6-weight, 600)); line-height: 1.4; text-transform: uppercase; letter-spacing: 0.05em; color: var(--h6-color, var(--text-heading)); }

@media (min-width: 480px) {
    :root { --fs-h1: 36px; --fs-h2: 26px; --fs-h3: 21px; --fs-h4: 18px; --fs-h5: 14px; --fs-h6: 13px; }
}
@media (min-width: 768px) {
    :root { --fs-h1: 40px; --fs-h2: 28px; --fs-h3: 22px; --fs-h4: 19px; --fs-h5: 15px; --fs-h6: 13px; }
}
@media (min-width: 1024px) {
    :root { --fs-h1: 44px; --fs-h2: 32px; --fs-h3: 24px; --fs-h4: 20px; --fs-h5: 16px; --fs-h6: 13px; }
}
@media (min-width: 1250px) {
    :root { --fs-h1: 48px; --fs-h2: 36px; --fs-h3: 26px; --fs-h4: 21px; --fs-h5: 16px; --fs-h6: 14px; }
}
@media (min-width: 1440px) {
    :root { --fs-h1: 56px; --fs-h2: 38px; --fs-h3: 27px; --fs-h4: 22px; --fs-h5: 17px; --fs-h6: 14px; }
}
@media (min-width: 1920px) {
    :root { --fs-h1: 64px; --fs-h2: 40px; --fs-h3: 28px; --fs-h4: 22px; --fs-h5: 17px; --fs-h6: 14px; }
}

p { margin: 0 0 var(--space-lg); } /* 24px paragraph rhythm (was --space-md/16px) */

/* ── Visual heading classes ──────────────────────────────────────────────
   SEO pattern: section headlines are <p> tags (the eyebrow above is the
   real heading tag carrying the keyword). These classes make <p> elements
   look exactly like headings without being heading tags.
   See quality-rules.md §6.2 for the full rationale. */
/* These reuse the same --fs-h1..4 tokens as the real headings above, so the
   responsive ladder + the widget's heading-size control drive both with one
   source of truth (the breakpoint :root redefinitions above). */
.hzo-visual-h1 {
    font-family: var(--font-heading);
    font-size: calc(var(--fs-h1) * var(--hzo-type-scale, 1) * var(--hzo-heading-scale, 1) * var(--h1-scale, 1));
    font-weight: var(--font-weight-heading, var(--h1-weight, 700)); line-height: 1.05;
    color: var(--h1-color, var(--text-heading));
}
.hzo-visual-h2 {
    font-family: var(--font-heading);
    font-size: calc(var(--fs-h2) * var(--hzo-type-scale, 1) * var(--hzo-heading-scale, 1) * var(--h2-scale, 1));
    font-weight: var(--font-weight-heading, var(--h2-weight, 700)); line-height: 1.1;
    color: var(--h2-color, var(--text-heading));
}
.hzo-visual-h3 {
    font-family: var(--font-heading);
    font-size: calc(var(--fs-h3) * var(--hzo-type-scale, 1) * var(--hzo-heading-scale, 1) * var(--h3-scale, 1));
    font-weight: var(--font-weight-heading, var(--h3-weight, 600)); line-height: 1.2;
    color: var(--h3-color, var(--text-heading));
}
.hzo-visual-h4 {
    font-family: var(--font-heading);
    font-size: calc(var(--fs-h4) * var(--hzo-type-scale, 1) * var(--hzo-heading-scale, 1) * var(--h4-scale, 1));
    font-weight: var(--font-weight-heading, var(--h4-weight, 600)); line-height: 1.3;
    color: var(--h4-color, var(--text-heading));
}

/* Dark section: display + visual headings go pure white. Without this,
   `.hzo-section--dark p` (85% white) wins on these <p>-based heading
   classes since it has higher specificity than .hzo-display / .hzo-visual-*
   alone — leaving the headline visually the same color as the subtitle. */
.hzo-section--dark .hzo-display,
.hzo-section--dark .hzo-visual-h1,
.hzo-section--dark .hzo-visual-h2,
.hzo-section--dark .hzo-visual-h3,
.hzo-section--dark .hzo-visual-h4 { color: var(--heading-color-on-dark, #fff); }

/* Widget-editable heading type attributes — default to no-op (normal/none),
   so rendering is unchanged until the design widget sets one. */
h1, h2, h3, h4,
.hzo-visual-h1, .hzo-visual-h2, .hzo-visual-h3, .hzo-visual-h4 {
    letter-spacing: var(--heading-letter-spacing, normal);
    text-transform: var(--heading-transform, none);
}
/* .hzo-display has its own tuned -0.015em tracking — tokenized in primitives.css
   so it keeps that default but still follows the heading type-attr controls. */

/* ── Text wrapping polish (Roadmap Batch 1) ──────────────────────────────
   Headings balance their line lengths (no single-word orphan on line two);
   prose paragraphs/list items avoid typographic orphans via `pretty`.
   Both are progressive enhancements — older browsers ignore the property
   and render exactly as before.

   The prose rule is wrapped in :where() so it carries ZERO class specificity
   (0,0,1 — element only). The <p>-based visual headings (.hzo-visual-h1..4,
   .hzo-display in primitives.css) therefore still win with `balance` even
   though they live inside .hzo-section; a plain `.hzo-section p` (0,1,1)
   selector would have silently overridden them with `pretty`.
   Scoped to .hzo-section / .hzo-prose / card text so nav links, buttons and
   menu items are never affected. */
h1, h2, h3, h4,
.hzo-visual-h1, .hzo-visual-h2, .hzo-visual-h3, .hzo-visual-h4 {
    text-wrap: balance;
}
:where(.hzo-section, .hzo-prose) p,
:where(.hzo-section, .hzo-prose) li,
.hzo-card__text {
    text-wrap: pretty;
}

a {
    color: var(--brand-text);
    text-decoration: var(--link-decoration, underline);
    transition: color var(--transition-base) ease, text-decoration-thickness var(--transition-base) ease;
}

a:visited { color: var(--brand-text); }
a:hover {
    color: var(--brand-hover-on-dark); /* brighter brand — a clear jump on hover */
    text-decoration-thickness: 1.25px; /* just a hair thicker than the resting underline */
}

/* Guard: the bare post-title link (archive / query loops render
   `<h2 class="wp-block-post-title"><a>`) is a heading — it must never wear a
   client content-link `background-image` highlight-wipe. `:not([class])` lifts
   this to (0,2,1) so it wins over a `:where(main) a:not([class])` client skin.
   Colour + underline are intentionally left to the base link / per-client styling. */
.wp-block-post-title a:not([class]) { background-image: none; }

:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

img { max-width: 100%; height: auto; }

input, select, textarea {
    font-size: 16px; /* 16px prevents iOS zoom on focus */
}

button, [role="button"], label[for], summary { cursor: pointer; }

/* ─── Section Layout ──────────────────────────────────────────────────────
   Vertical padding scales across three zones via the QA breakpoints:
   --space-xl (48px) below 768, --space-2xl (64px) at tablet, --space-3xl
   (80px) at desktop. Horizontal padding belongs to .hzo-container. */
.hzo-section { padding: var(--space-xl) 0; }

@media (min-width: 768px) {
    .hzo-section { padding: var(--space-2xl) 0; }
}
@media (min-width: 1250px) {
    .hzo-section { padding: var(--space-3xl) 0; }
}

/* ─── Bare-prose safety net (ships WITH the PF-064 layout change) ─────────
   The engine's block templates wrap post content in a FLOW-layout <main>, not
   a constrained one, so that `.hzo-section` bands span the viewport instead of
   being clipped to the 1350px content-size. The cost of flow layout is that WP
   no longer constrains anything: a page whose post_content is NOT wrapped in
   the `<section class="hzo-section"><div class="hzo-container">` skeleton would
   run its paragraphs edge to edge.

   That is not hypothetical — post_content is editable in wp-admin, and the
   failure is silent and ugly. This rule gives the container treatment back to
   BARE block-level prose that sits directly in <main> or in the post-content
   wrapper. It deliberately targets leaf prose elements only:
     • it must NOT match the post-content wrapper itself, or every page would
       be re-boxed one level down and PF-064 would simply move;
     • it must NOT match `.hzo-section`, which is the whole point;
     • it must NOT match block wrappers (.wp-block-group and friends), which
       own their own alignment.

   :where() keeps the ancestor part at zero specificity and :is() over element
   names lands the whole selector at (0,0,1), so anything with a class beats it
   without a fight. Padding mirrors _base/container.css exactly.

   Correct authoring still wins: wrap the content in the section skeleton. This
   is the net under the trapeze, not the trapeze. */
:where(main, .entry-content) > :is(p, h1, h2, h3, h4, h5, h6, ul, ol, dl, blockquote, pre, table, figure, hr) {
    max-width: var(--container-max-width);
    margin-inline: auto;
    padding-inline: var(--space-md);
}
@media (min-width: 480px)  { :where(main, .entry-content) > :is(p, h1, h2, h3, h4, h5, h6, ul, ol, dl, blockquote, pre, table, figure, hr) { padding-inline: var(--space-lg); } }
@media (min-width: 768px)  { :where(main, .entry-content) > :is(p, h1, h2, h3, h4, h5, h6, ul, ol, dl, blockquote, pre, table, figure, hr) { padding-inline: var(--space-lg-2); } }
@media (min-width: 1024px) { :where(main, .entry-content) > :is(p, h1, h2, h3, h4, h5, h6, ul, ol, dl, blockquote, pre, table, figure, hr) { padding-inline: var(--space-xl); } }
@media (min-width: 1250px) { :where(main, .entry-content) > :is(p, h1, h2, h3, h4, h5, h6, ul, ol, dl, blockquote, pre, table, figure, hr) { padding-inline: var(--space-2xl); } }
