/* ============================================================================
   jaykarr.com — design system
   ----------------------------------------------------------------------------
   theme.json owns what WordPress can express natively (palette, fonts, fluid
   sizes, spacing, layout, element styles). This file owns everything else, and
   it opens by aliasing the generated custom properties into short names so no
   rule below has to spell out --wp--preset--*.

   Accessible action tokens are deliberately separate from brand tokens. Brand
   moss (#77775F) is 3.76:1 on ink and brand ochre (#B7761F) is 3.31:1 on paper —
   both fail AA for small text. The palette keeps the brand values so the editor
   shows real brand colour; every interactive surface and every small label
   points at the derived --action--* value instead. Large decorative type may
   use the brand value directly (see the marquee), because AA for large text is
   3:1. The contract is enforced by `npm run audit:contrast`.
   ========================================================================== */

/* ---------- 0. Reset ---------- */
/* The prototype resets box-sizing globally. Without this, max-width + padding on
   .jk-wrap adds up to a wider box than the constraint asks for, and every
   padded container in the theme is quietly wider than its design width. */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

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

/* The header is sticky, so anchor targets need to clear it. */
[id] { scroll-margin-top: 84px; }

/* ---------- Palette vocabulary ----------
   theme.json palette slugs are the DESIGNSYSTEM.md names, one to one:

     ink · ink-deep · ink-raise · paper · bone · sage · moss
     gold · ochre · ink-text · ink-body · stone   (+ paper-warm, linen, olive)

   Do not reach for a palette colour in a block rule. Use the surface-aware
   aliases below — --text-1..4, --surface-1..3, --accent, --rule — which change
   meaning with the surface a block is sitting on. A block that names a colour
   directly renders wrong the first time somebody puts it on paper.
   --------------------------------------------------------------------- */

/* ---------- 1. Alias layer ---------- */

:root {
	/* Surfaces */
	--surface-1: var(--wp--preset--color--ink);
	--surface-2: var(--wp--preset--color--ink-deep);
	--surface-3: var(--wp--preset--color--ink-raise);
	--surface-light-1: var(--wp--preset--color--paper);
	--surface-light-2: var(--wp--preset--color--paper-warm);
	--surface-accent: var(--wp--preset--color--gold);

	/* Text on dark surfaces */
	--text-1: var(--wp--preset--color--paper);
	--text-2: var(--wp--preset--color--bone);
	--text-3: var(--wp--preset--color--sage);
	--text-4: var(--wp--custom--action--moss);      /* accessible variant, not the brand swatch */

	/* Text on light surfaces */
	--text-light-1: var(--wp--preset--color--ink-text);
	--text-light-2: var(--wp--preset--color--ink-body);
	--text-light-3: var(--wp--custom--action--stone);

	/* Accents */
	--accent: var(--wp--preset--color--gold);
	--accent-on-light: var(--wp--custom--action--ochre);
	--accent-brand-deep: var(--wp--preset--color--ochre);

	/* Rules. DS §2: .14 section dividers · .16 list rows · .12 dense table rows. */
	--rule: var(--wp--custom--line--hairline);
	--rule-strong: var(--wp--custom--line--strong);
	--rule-dense: var(--wp--custom--line--dense);
	--rule-light: var(--wp--custom--line--on-light);
	--rule-light-strong: var(--wp--custom--line--on-light-strong);
	/* Separator inside a hairline row stack. Heavier than the section divider on
	   dark, lighter than the stack's own top rule on paper — which is what the
	   prototype does in .tenets and .principles. */
	--rule-rows: var(--rule-strong);

	/* Type */
	--font-serif: var(--wp--preset--font-family--serif);
	--font-sans: var(--wp--preset--font-family--sans);
	--font-mono: var(--wp--preset--font-family--mono);

	/* Rhythm */
	--maxw: var(--wp--custom--maxw);
	--gut: var(--wp--custom--gut);
	--pad-section: var(--wp--custom--section-pad);
	--pad-section-tight: var(--wp--custom--section-pad-tight);

	/* Motion */
	--dur-fast: var(--wp--custom--motion--fast);
	--dur-base: var(--wp--custom--motion--base);
	--dur-slow: var(--wp--custom--motion--slow);
	--ease: var(--wp--custom--motion--ease);
	--ease-out: var(--wp--custom--motion--ease-out);
}

/* ---------- 2. Surface variants ---------- */
/* Editors pick a surface, never a hex. Registered as block styles in inc/blocks.php. */

.is-style-dark-1  { background-color: var(--surface-1); color: var(--text-2); }
.is-style-dark-2  { background-color: var(--surface-2); color: var(--text-2); }
.is-style-dark-3  { background-color: var(--surface-3); color: var(--text-2); }
.is-style-light-1 { background-color: var(--surface-light-1); color: var(--text-light-2); }
.is-style-light-2 { background-color: var(--surface-light-2); color: var(--text-light-2); }
.is-style-accent  { background-color: var(--surface-accent); color: var(--surface-1); }

/* Surface-aware text rules. A block does not need to know which surface it is
   on; the surface tells its descendants what the palette means. */
.is-style-light-1, .is-style-light-2 {
	--text-1: var(--text-light-1);
	--text-2: var(--text-light-2);
	--text-3: var(--text-light-3);
	--text-4: var(--text-light-3);
	--accent: var(--accent-on-light);
	--rule: var(--rule-light);
	--rule-strong: var(--rule-light-strong);
	--rule-dense: var(--rule-light);
	--rule-rows: var(--rule-light);
}
.is-style-accent {
	--text-1: var(--surface-1);
	--text-2: var(--surface-1);
	--text-3: rgba(25, 28, 23, .8);
	--text-4: rgba(25, 28, 23, .8);
	--accent: var(--surface-1);
	--rule: rgba(25, 28, 23, .22);
	--rule-strong: rgba(25, 28, 23, .28);
	--rule-dense: rgba(25, 28, 23, .22);
	--rule-rows: rgba(25, 28, 23, .28);
}

/* ---------- 3. Section transitions (single-owner) ---------- */
/* The RECEIVING block owns its own top boundary through one field. There is no
   paired top/bottom setting and no neighbour inspection — that design produces
   ordering bugs nobody can debug in the editor. */

.jk-top--hairline   { border-top: 1px solid var(--rule); }
.jk-top--rule       { border-top: 1px solid var(--rule-strong); }
.jk-top--none       { border-top: 0; }
.jk-top--overlap    { margin-top: calc(var(--pad-section) * -0.5); position: relative; z-index: 1; }

/* ---------- 4. Container + section rhythm ----------

   Specificity note, and it matters for the whole file below this point:
   WordPress inlines each block's stylesheet near the top of <head>, while this
   file is enqueued and lands last. Source order therefore makes the design
   system the TOP layer, not the base — the opposite of what it is for. A block
   rule like .jk-hero { padding-block } would lose to .jk-section { padding-block }
   purely because of print order.

   The primitives a block is expected to build on are wrapped in :where(), which
   zeroes their specificity. A block rule at 0,1,0 then wins regardless of order,
   with no !important and no cascade layer. Layering the file instead would make
   it lose to every unlayered core and plugin rule, which breaks things like the
   navigation override in §9.
   --------------------------------------------------------------------- */

/* Sections run edge to edge; .jk-wrap is the only constraint on the page.
   This mirrors the prototype, where <body> carries no side padding and every
   .wrap owns max-width + gutter. It also removes the need for alignfull to
   escape a constrained ancestor, which it cannot reliably do. */
.jk-wrap {
	max-width: var(--maxw);
	margin-inline: auto;
	padding-inline: var(--gut);
}

:where(.jk-section) { padding-block: var(--pad-section) var(--pad-section-tight); }
:where(.jk-section--tight) { padding-block: var(--pad-section-tight); }
:where(.jk-section--flush) { padding-block: 0; }

:where(.jk-section__head) {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	margin-bottom: clamp(26px, 3.4vw, 44px);
}
:where(.jk-section__head--tight) { margin-bottom: 14px; }

/* ---------- 5. Type primitives ----------

   Split deliberately. A primitive's LOOK stays at class specificity so it beats
   the element rules theme.json generates for h1–h4 — .jk-display lives on an
   <h1>/<h2>, and .jk-eyebrow lives on an <h2> in the talk list and the split, so
   a zero-specificity rule there loses its colour and size to `h2 { ... }` and
   renders paper-on-paper.

   Only the box properties a block legitimately re-declares — margin, and the
   display of the split's eyebrow — are wrapped in :where(), so a block rule at
   0,1,0 wins despite this file printing last. See the note in §4.
   --------------------------------------------------------------------- */

.jk-eyebrow,
.jk-meta {
	font-family: var(--font-mono);
	font-size: var(--wp--preset--font-size--mono-xs);
	font-weight: var(--wp--custom--weight--regular);
	line-height: 1.4;
	text-transform: uppercase;
}
.jk-eyebrow { color: var(--accent); letter-spacing: var(--wp--custom--tracking--widest); }
.jk-meta    { color: var(--text-4); letter-spacing: var(--wp--custom--tracking--wider); }

.jk-lede {
	font-size: var(--wp--preset--font-size--lg);
	font-weight: var(--wp--custom--weight--light);
	line-height: 1.62;
	color: var(--text-2);
	text-wrap: pretty;
}
.jk-display {
	font-family: var(--font-serif);
	font-weight: var(--wp--custom--weight--light);
	color: var(--text-1);
	text-wrap: balance;
}
.jk-prose { color: var(--text-2); text-wrap: pretty; }

.jk-mono {
	font-family: var(--font-mono);
	font-size: var(--wp--preset--font-size--mono-sm);
	letter-spacing: var(--wp--custom--tracking--wide);
}

/* Overridable box properties — zero specificity on purpose. */
:where(.jk-eyebrow, .jk-meta, .jk-lede, .jk-display, .jk-prose) { margin: 0; }
:where(.jk-prose + .jk-prose) { margin-top: 20px; }

em.jk-accent, .jk-accent { font-style: italic; color: var(--accent); }

/* ---------- 6. Hairline row stacks ---------- */

:where(.jk-rows) { border-top: 1px solid var(--rule-strong); }
:where(.jk-rows > *) { border-bottom: 1px solid var(--rule-rows); }
:where(.jk-rows > *:last-child) { border-bottom: 0; }

.jk-row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	padding-block: 13px;
	font-family: var(--font-mono);
	font-size: var(--wp--preset--font-size--mono-lg);
	color: var(--text-2);
}
.jk-row dt { letter-spacing: var(--wp--custom--tracking--wide); margin: 0; }
.jk-row dd { margin: 0; text-align: right; color: var(--text-1); }
.jk-row dd.is-accent { color: var(--accent); }

/* ---------- 7. CTA primitives ---------- */

:where(.jk-cta) {
	display: inline-block;
	font-family: var(--font-mono);
	font-size: var(--wp--preset--font-size--mono-lg);
	font-weight: var(--wp--custom--weight--medium);
	letter-spacing: var(--wp--custom--tracking--wide);
	text-decoration: none;
	padding: 14px 22px;
	border: 1px solid transparent;
	transition: background-color var(--dur-base) var(--ease),
	            color var(--dur-base) var(--ease),
	            border-color var(--dur-base) var(--ease);
}
.jk-cta--fill    { background: var(--accent); color: var(--surface-1); }
.jk-cta--fill:hover, .jk-cta--fill:focus-visible { background: var(--text-1); color: var(--surface-1); }
.jk-cta--outline { color: var(--text-1); border-color: currentColor; }
.jk-cta--outline:hover, .jk-cta--outline:focus-visible { background: var(--text-1); color: var(--surface-1); }
.jk-cta--invert  { background: var(--surface-1); color: var(--wp--preset--color--gold); font-size: 13px; padding: 19px 32px; }
.jk-cta--invert:hover, .jk-cta--invert:focus-visible { background: var(--surface-light-1); color: var(--surface-1); }
.jk-cta--sm      { font-size: 11px; padding: 11px 18px; }
.jk-cta--quiet   { padding: 0; color: var(--text-2); border: 0; }
.jk-cta--quiet:hover { color: var(--accent); }

/* ---------- 8. Accessibility ---------- */

/* Core's block-template skip link, restyled. It ships with .screen-reader-text,
   which clips it to 1px; the reset below un-clips it on focus and gives it the
   design's ochre chip. Targeting core's element rather than emitting a second
   one keeps a single link in the tab order. */
.skip-link,
.skip-link.screen-reader-text {
	position: absolute;
	left: 8px;
	top: -60px;
	z-index: 100;
	width: auto;
	height: auto;
	margin: 0;
	padding: 12px 18px;
	overflow: visible;
	clip: auto;
	clip-path: none;
	background: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--ink);
	font-family: var(--font-mono);
	font-size: 12px;
	font-weight: var(--wp--custom--weight--medium);
	letter-spacing: var(--wp--custom--tracking--wide);
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
	transition: top var(--dur-base) var(--ease);
}
.skip-link:focus,
.skip-link.screen-reader-text:focus { top: 8px; }

:where(a, button, summary, input, select, textarea):focus-visible {
	outline: 2px solid var(--wp--preset--color--gold);
	outline-offset: 3px;
}

.screen-reader-text {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ---------- 9. Header / footer ---------- */

.jk-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: rgba(25, 28, 23, .9);
	backdrop-filter: saturate(140%) blur(10px);
	border-bottom: 1px solid var(--rule);
}
.jk-header__inner { align-items: center; }

.jk-brand { align-items: baseline; min-width: 0; }
.jk-brand-tag {
	white-space: nowrap;
	font-family: var(--font-mono);
	font-size: 10px;
	letter-spacing: var(--wp--custom--tracking--wider);
	color: var(--text-3);
}

.jk-nav { align-items: center; }
.jk-nav .wp-block-navigation-item__content {
	padding: 8px 12px;
	font-family: var(--font-mono);
	font-size: var(--wp--preset--font-size--mono-xs);
	letter-spacing: 0.1em;
	color: var(--text-2);
	text-decoration: none;
	transition: color var(--dur-base) var(--ease);
}
.jk-nav .wp-block-navigation-item__content:hover,
.jk-nav .wp-block-navigation-item__content:focus-visible,
.jk-nav .wp-block-navigation-item__content[aria-current] { color: var(--accent); }
.jk-nav .jk-cta--fill { margin-left: 10px; }

/* The prototype drops the section links below 900px rather than collapsing them
   into an overlay. The CTA is the only action that survives the narrow header. */
@media (max-width: 1080px) { .jk-header .jk-brand-tag { display: none; } }
/* Specificity note: core ships .wp-block-navigation { display: flex }, which is
   also 0,1,0 and prints after the theme stylesheet. Scoping to .jk-header wins
   without an !important. */
@media (max-width: 900px)  { .jk-header .jk-nav__links { display: none; } }

.jk-footer {
	font-family: var(--font-mono);
	font-size: var(--wp--preset--font-size--mono-xs);
	letter-spacing: var(--wp--custom--tracking--wide);
	color: var(--text-4);
}
.jk-footer a { color: var(--text-4); text-decoration: none; transition: color var(--dur-base) var(--ease); }
.jk-footer a:hover, .jk-footer a:focus-visible { color: var(--accent); }

/* ---------- 10. Motion ---------- */

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
}

/* ---------- 11. Third-party token adapters ---------- */
/* Map our semantic tokens into a plugin's own custom properties rather than
   overriding its rules. No !important wars; the plugin can update freely.
   Cascade note: a plugin shipping styles inside @layer loses to unlayered
   theme CSS regardless of specificity — check before adding overrides here. */

:root {
	/* The SEO Framework admin bar / breadcrumbs, if it ever renders on front. */
	--tsf-accent: var(--accent);
}

/* ---------- 12. Footer bar ---------- */

.jk-footer__bar {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 20px;
}
.jk-footer__nav { display: flex; flex-wrap: wrap; gap: 22px; }
