/* ===================================================================
 * tokens.css — Brand Pass 1 (Linnea spec §1, §4, §5, §7)
 * Universal primitives: focus baseline, reading-width, motion guard,
 * adjacent-band rhythm, link refinements, selection.
 * Loads first; later sheets layer on top.
 * =================================================================== */

/* === Heading wrap balance — tighter ragged edges on serif H1/H2/H3 === */
h1, h2, h3 {
	text-wrap: balance;
}

/* === Body links inside long-form content === */
.entry-content a,
.tec-page-body__inner a {
	text-underline-offset: 0.18em;
	text-decoration-thickness: 1px;
}
.entry-content a:hover,
.tec-page-body__inner a:hover {
	text-decoration-thickness: 2px;
}

/* === Card-title link treatment ===
 * Shared by tec/event-card and tec/post-card (both consume the
 * `is-style-tec-card` block style variation). Title at rest carries
 * accent-yellow via the `has-accent-yellow-color` class (textColor
 * attribute on wp:post-title); no underline. On hover the colour
 * shifts to navy via the global `a:hover` rule in style.css —
 * intentionally no underline added on hover so both cards match
 * (Alfonso 2026-05-02). */
.is-style-tec-card .wp-block-post-title a {
	text-decoration: none;
}

/* === Adjacent constrained-band rhythm (§5) === */
main > .wp-block-group:not(.alignfull) + .wp-block-group:not(.alignfull) {
	margin-top: var(--wp--preset--spacing--90);
}

/* === Focus baseline (§7) === */
:focus { outline: none; }                  /* mouse — silent */
:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent-yellow);
	outline-offset: 2px;
	border-radius: 2px;
}
.has-navy-background-color :focus-visible,
.has-charcoal-background-color :focus-visible,
.tec-surface-dark :focus-visible,
body.tec-surface-dark-header .tec-page-header :focus-visible {
	outline-color: var(--wp--preset--color--white);
}

/* === Skip link === */
.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 10001;
	padding: 0.75rem 1rem;
	background: var(--wp--preset--color--navy);
	color: var(--wp--preset--color--white);
	text-decoration: none;
	font-weight: 700;
}
.skip-link:focus,
.skip-link:focus-visible {
	left: 1rem;
	top: 1rem;
}

/* === Reduced motion guard (§7) ===
 * !important here is the documented exception — overrides any
 * cascading transition author code, which is the correct behaviour. */
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* === Selection === */
::selection {
	background-color: var(--wp--preset--color--accent-yellow);
	color: var(--wp--preset--color--navy);
}

/* === Breakpoint reference (documentation-only — not consumable from @media) ===
 * Author rules use the literal pixel values below so the @media queries
 * themselves stay declarative. Token names match what Linnea uses in spec text.
 *   --tec-bp-sm: 600px   (1-up ↔ 2-up)
 *   --tec-bp-md: 900px   (2-up ↔ 3-up)
 *   --tec-bp-lg: 1200px  (3-up ↔ 4-up)
 * Previously these were declared on :root for dev reference; declarations
 * removed 2026-05-05 (Holt quick-win pass) — they had zero consumers and
 * @media can't read them anyway. Reinstate if a use case appears.
 */
:root {
	--tec-grid-gap: var(--wp--preset--spacing--40, 1.5rem);

	/* Width tier aliases (short names authors actually type).
	 * Source of truth lives in theme.json `settings.custom.width.*`,
	 * which WP exposes as `--wp--custom--width--*`. The aliases below
	 * are pure indirection — if a token changes, theme.json wins.
	 *
	 * As of 2026-05-02 the default container tier was widened from
	 * 1000px to 1200px (Alfonso sign-off). content == wide == 1200;
	 * long-form text is constrained to 680 (prose) by a scoped rule in
	 * style.css — not by the container tier. Token names preserved for
	 * backward compatibility — `--tec-width-content` is now an alias of
	 * `--tec-width-wide`, every existing consumer keeps working.
	 *
	 *   --tec-width-prose:   680px   (single-column reading)
	 *   --tec-width-content: 1200px  (default body / layout blocks)
	 *   --tec-width-wide:    1200px  (full bands, archives, hero rows)
	 *   --tec-gutter:        clamp(1rem, 4vw, 2rem)  universal page gutter */
	--tec-width-prose:   var(--wp--custom--width--prose,   680px);
	--tec-width-content: var(--wp--custom--width--content, 1200px);
	--tec-width-wide:    var(--wp--custom--width--wide,    1200px);
	--tec-gutter:        var(--wp--custom--gutter--default, clamp(1rem, 4vw, 2rem));
}

/* === Band utilities — outer gutter + inner width tier ===
 * The TEC band model. Two responsibilities, two classes, two DOM levels.
 * Apply both — gutter on the outer section, max-width on the inner wrapper.
 *
 *   .tec-band         → outer alignfull section. Owns the fluid edge gutter.
 *                       (`padding-inline: var(--tec-gutter)`)
 *   .tec-band-inner   → inner content wrapper. Owns the tier max-width
 *                       and centring. NO gutter — that already lives on
 *                       the outer .tec-band.
 *
 * Tier modifiers on .tec-band-inner (default = content tier, 1000px):
 *   .tec-band-inner--prose  → 680px   reading column
 *   .tec-band-inner--wide   → 1200px  archive / hero row
 *
 * Canonical usage:
 *   <section class="alignfull tec-band">
 *     <div class="tec-band-inner tec-band-inner--wide"> … </div>
 *   </section>
 *
 * If the band hosts a Query Loop / post-template that should fill the
 * tier, set `align:"wide"` on the Query Loop block so core's layout
 * machinery stretches it to the wrapper's max-width.
 *
 * Why two classes (not one combined utility)? Because legitimate bands
 * need an outer with a background colour / image and an inner with the
 * constrained content column — the gutter belongs on the painted box,
 * the max-width belongs on the column inside it. Splitting the
 * responsibilities makes both `alignfull-with-bg` AND simpler bands
 * compose from the same primitives.
 *
 * Replaces inline `style="padding-left:…;padding-right:…"` on patterns
 * and inline `style="max-width:…;margin:0 auto;padding:0 …"` on sections
 * rendered from PHP. Logical properties so RTL / vertical writing modes
 * work without further patching. */
.tec-band {
	padding-inline: var(--tec-gutter);
}
.tec-band-inner {
	max-width: var(--tec-width-content);
	margin-inline: auto;
	/* No padding-inline — the gutter lives on the parent .tec-band. */
}
.tec-band-inner--prose { max-width: var(--tec-width-prose); }
.tec-band-inner--wide  { max-width: var(--tec-width-wide); }

/* === Generic responsive card-grid recipe (Stage 3 hygiene refactor) ===
 * Replaces five bespoke grid rules (.tec-cast-grid, .tec-posts-archive-grid,
 * .tec-latest-grid, .tec-single-post-related__grid, .tec-musicians-archive__grid,
 * .tec-archive--recording .tec-archive__grid, .tec-events-archive-past__grid).
 *
 * Consumers add `tec-grid tec-grid--3up` (or `--4up`) on the grid container.
 * For wp:post-template surfaces, ALSO set displayLayout.columns on the block
 * attribute so core's inline grid-template-columns matches — this avoids the
 * !important arms race the audit flagged. The class drives the responsive
 * step-down; the block attribute drives the desktop column count.
 *
 * Per-consumer gap overrides via `--tec-grid-gap` on the container's style
 * attribute or scoped class (e.g. .tec-posts-archive { --tec-grid-gap: 2rem; }).
 */
.tec-grid {
	display: grid;
	gap: var(--tec-grid-gap);
	list-style: none;
	padding: 0;
	margin: 0;
}
.tec-grid--3up { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tec-grid--4up { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 1199px) {
	.tec-grid--4up { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 899px) {
	.tec-grid--3up,
	.tec-grid--4up { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 599px) {
	.tec-grid--3up,
	.tec-grid--4up { grid-template-columns: 1fr; }
}

/* Per-consumer gap override: the homepage Latest grid (page 20613)
 * uses 2rem rhythm rather than the default 1.5rem. The legacy
 * `.tec-latest-grid` class is preserved on the post-template markup
 * solely as the hook for this override — column count + display:grid
 * come from `tec-grid tec-grid--3up`. */
.tec-latest-grid { --tec-grid-gap: 2rem; }

/* === Initials fallback utility (Stage 3 hygiene refactor) ===
 * Centred caps inside a square portrait/cover box when no image exists.
 * Consumed by .tec-musician-card__portrait-fallback (musician archive
 * mu-plugin) and .tec-cast-card__photo--fallback (cast-list template
 * part). Replaces .tec-musician-card__initials + .tec-cast-card__initials. */
.tec-initials {
	font-family: var(--wp--preset--font-family--sans-heading, "objektiv-mk3", "Objektiv Mk3", sans-serif);
	font-size: var(--wp--preset--font-size--h4, 1.5rem);
	font-weight: 600;
	color: var(--wp--preset--color--ink-low-emphasis, #555555);
	letter-spacing: 0.05em;
}

/* === core/media-text — remove default 8% inline padding ===
 * WP core ships `.wp-block-media-text > .wp-block-media-text__content
 * { padding: 0 8%; }` (wp-includes/blocks/media-text/style.css). At a
 * 600px text side this resolves to 48px L/R, which makes Media & Text
 * inset its text relative to a sibling core/columns block (columns have
 * zero default padding on each .wp-block-column). On a page that uses
 * both blocks for the same 50/50 text+image rhythm (e.g. About us,
 * page 255) the two paragraphs land at different x positions.
 *
 * Reset to zero so the two blocks behave consistently: each side is a
 * clean rectangle, text sits flush against the boundary. Authors who
 * want internal padding apply it per-instance via the inspector
 * Padding control, which writes inline style and wins on specificity. */
.wp-block-media-text > .wp-block-media-text__content {
	padding: 0;
}

/* === core/media-text — match core/columns inter-column gap ===
 * core/media-text is a CSS grid with `grid-template-columns: 50% 1fr`
 * and no column-gap by default — its two sides touch. core/columns,
 * by contrast, uses the global block-gap (24px) between columns. On a
 * page with both blocks (e.g. About us) the visual rhythm differs:
 * Columns has air between text and image, Media & Text doesn't.
 *
 * Apply the same block-gap as a grid column-gap. Each side shrinks by
 * gap/2 (12px) — identical behaviour to Columns, which also subtracts
 * gap/2 from each column's flex-basis. Mobile keeps single-column
 * grid (`grid-template-columns: 100%`), so column-gap is inert there. */
.wp-block-media-text {
	column-gap: var(--wp--style--block-gap, 1.5rem);
}
