/*
 * Palettes and colour schemes — two composable surface axes.
 *
 * Deliberately NOT block style variations. A block carries one `is-style-*` at
 * a time, and these are orthogonal: a section can be `palette--primary` AND
 * `color-scheme--dark` AND `is-style-<surface treatment>` at once. Plain
 * classes compose; variations do not. The editor writes them through the
 * Surface panel (assets/editor/palette-controls.js), so the one `is-style-*`
 * slot stays free for the treatment axis.
 *
 * WHY THE ROLES ARE RESTATED IN EVERY PALETTE
 * A custom property's var() references are substituted at computed-value time
 * on the element that DECLARES it. So `--raised: oklch(from var(--...--bg) …)`
 * written once on :root bakes in :root's bg and never reflows when a palette
 * class redefines bg further down the tree. Each palette therefore declares all
 * four roles itself, which is also what makes `from var(--...--bg)` inside them
 * resolve against the palette's OWN bg — same element, same computed pass.
 *
 * WHY light-dark() RATHER THAN A SECOND CLASS PER PALETTE
 * Every role holds both sides at once. `color-scheme--dark` flips which side
 * resolves, so one palette class serves both schemes and the scheme axis stays
 * a single class instead of a palette x scheme matrix.
 */

:root {
	color-scheme: light;
}

/*
 * Any palette or scheme class paints its own surface. Zero specificity via
 * :where() so a block's own background-color, a cover overlay, or a media
 * scheme-lock still wins without needing !important.
 */
:where([class*="palette--"], [class*="color-scheme--"]) {
	background-color: var(--wp--preset--color--bg);
	color: var(--wp--preset--color--foreground);
}

/*
 * Cover is the only block that hardcodes a text colour: core ships
 * `:where(.wp-block-cover:not(.has-text-color)){color:#fff}`, flipped to #000
 * by the `is-light` class that the editor derives from overlay luminance. That
 * derivation cannot read our tokens — every role is a `light-dark()` whose
 * luminance the editor has no way to compute — so it guesses, and a cover over
 * a light overlay silently renders white on white.
 *
 * So take the axis away from core: no scheme class means what it means on every
 * other block, the page's foreground. A cover that genuinely sits on media opts
 * in with `color-scheme--dark`. Zero specificity, so both the rule above and any
 * explicit text colour still win, and `is-light` becomes inert either way.
 */
:where(.wp-block-cover:not(.has-text-color)) {
	color: var(--wp--preset--color--foreground);
}

/*
 * Palette-aware gradients. theme.json declares every gradient preset on :root,
 * so a `var(--...--bg)` inside one is substituted there and bakes in the page
 * bg (same reason the roles are restated below). Restating the preset on the
 * palette element makes it resolve against that palette's bg. Keep the value
 * identical to the `bg-rich` preset in theme.json.
 *
 *   dark:  L -0.12 → +0.02, chroma +0.01 → +0.03   deep corner lifting past bg
 *   light: L -0.03 →  0,    chroma +0.03 → +0.01   a faint tinted wash
 *
 * Chroma is added, not multiplied, so a near-grey bg still gains colour and a
 * saturated one does not blow out.
 */
[class*="palette--"] {
	--wp--preset--gradient--bg-rich: linear-gradient(135deg,
		light-dark(
			oklch(from var(--wp--preset--color--bg) calc(l - 0.03) calc(c + 0.03) h),
			oklch(from var(--wp--preset--color--bg) calc(l - 0.12) calc(c + 0.01) h)
		) 0%,
		light-dark(
			oklch(from var(--wp--preset--color--bg) l calc(c + 0.01) h),
			oklch(from var(--wp--preset--color--bg) calc(l + 0.02) calc(c + 0.03) h)
		) 100%
	);
}

/* ── Scheme axis ──────────────────────────────────────────────────────────
 * Orthogonal to palette. Alone it flips the page palette; composed with a
 * family it flips that family's dark side. --light is a LOCK, for a subtree
 * sitting inside a dark section whose surface is really an image (a photo
 * panel, a media card) and must stay light.
 */
.color-scheme--dark {
	color-scheme: dark;
}

.color-scheme--light {
	color-scheme: light;
}

/* ── Palette families ─────────────────────────────────────────────────────
 * The uniform surface-role formula, shared by every chromatic family:
 *   raised  L +0.022 / +0.045      a subtle lift above bg (cards, modals)
 *   tint    L -0.045 / +0.075, c x1.4   brand-tinted enclosure (eyebrows, chips)
 *   inset   L -0.035 / +0.090      a recessed well (code, inputs' backdrop)
 * Light recesses below bg, dark lifts above it — elevation reverses so both
 * stay legible.
 */

.palette--primary {
	--wp--preset--color--bg: light-dark(
		oklch(from var(--wp--preset--color--primary) 0.95 calc(c * 0.30) h),
		oklch(from var(--wp--preset--color--primary) 0.18 calc(c * 0.70) h)
	);
	--wp--preset--color--raised: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l + 0.022) c h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.045) c h)
	);
	--wp--preset--color--tint: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l - 0.045) calc(c * 1.4) h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.075) calc(c * 1.4) h)
	);
	--wp--preset--color--inset: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l - 0.035) c h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.090) c h)
	);
}

.palette--secondary {
	--wp--preset--color--bg: light-dark(
		oklch(from var(--wp--preset--color--secondary) 0.95 calc(c * 0.30) h),
		oklch(from var(--wp--preset--color--secondary) 0.18 calc(c * 0.70) h)
	);
	--wp--preset--color--raised: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l + 0.022) c h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.045) c h)
	);
	--wp--preset--color--tint: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l - 0.045) calc(c * 1.4) h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.075) calc(c * 1.4) h)
	);
	--wp--preset--color--inset: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l - 0.035) c h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.090) c h)
	);
}

/* Neutral — the bg lands at near-zero chroma, so its --tint reads as a lift
   rather than a brand tint. That is the expected trade for one shared formula. */
.palette--neutral {
	--wp--preset--color--bg: light-dark(
		oklch(from var(--wp--preset--color--neutral) 0.97 calc(c * 0.60) h),
		oklch(from var(--wp--preset--color--neutral) 0.21 calc(c * 0.60) h)
	);
	--wp--preset--color--raised: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l + 0.022) c h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.045) c h)
	);
	--wp--preset--color--tint: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l - 0.045) calc(c * 1.4) h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.075) calc(c * 1.4) h)
	);
	--wp--preset--color--inset: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l - 0.035) c h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.090) c h)
	);
}

/* White — pure white in light, deep near-black (on the neutral hue) in dark.
   The light side diverges from the uniform formula: bg is already at L 1.0, so
   every role has to recess instead of lift. Both --tint branches also deepen
   further than the uniform -0.045 / +0.075, because white's bg has near-zero
   chroma and the x1.4 boost is a no-op — L alone has to carry the contrast. */
.palette--white {
	--wp--preset--color--bg: light-dark(
		var(--wp--preset--color--white),
		oklch(from var(--wp--preset--color--neutral) 0.13 calc(c * 0.60) h)
	);
	--wp--preset--color--raised: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l - 0.030) c h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.045) c h)
	);
	--wp--preset--color--tint: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l - 0.075) calc(c * 1.4) h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.110) calc(c * 1.4) h)
	);
	/* Deepens past --tint on the dark side (+0.130 vs +0.110) so the two stay
	   distinguishable now that tint has moved. */
	--wp--preset--color--inset: light-dark(
		oklch(from var(--wp--preset--color--bg) calc(l - 0.060) c h),
		oklch(from var(--wp--preset--color--bg) calc(l + 0.130) c h)
	);
}

/* Base-strong — a saturated, lifted dark: warmer than the default base dark
   (L 0.22, chroma x0.75). DARK-ONLY: it bakes color-scheme in and has no light
   sibling, so it neither needs nor composes with color-scheme--dark. The roles
   are the dark branch of the uniform formula, stated without light-dark(). */
.palette--base-strong {
	color-scheme: dark;
	--wp--preset--color--bg: oklch(from var(--wp--preset--color--base) 0.22 calc(c * 0.75) h);
	--wp--preset--color--raised: oklch(from var(--wp--preset--color--bg) calc(l + 0.045) c h);
	--wp--preset--color--tint: oklch(from var(--wp--preset--color--bg) calc(l + 0.075) calc(c * 1.4) h);
	--wp--preset--color--inset: oklch(from var(--wp--preset--color--bg) calc(l + 0.090) c h);
}
