/**
 * JSCodex reset (front end + editor iframe).
 *
 * Everything lives in the `jsc-reset` cascade layer. Layered styles always lose
 * to unlayered ones, so theme.json global styles, core block styles, base.css
 * and child theme/block CSS win without specificity fights. Only defaults that
 * WordPress does not already provide are set here; typography, colours and
 * element spacing stay in theme.json.
 *
 * Opt out: add_filter( 'jscodex_base_load_reset', '__return_false' );
 * Decision: docs/decisions/0001-css-reset-layer.md
 */

@layer jsc-reset {

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

	html {
		-webkit-text-size-adjust: 100%;
		text-size-adjust: 100%;
	}

	body {
		min-height: 100vh;
		min-height: 100dvh;
		margin: 0;
		-webkit-font-smoothing: antialiased;
	}

	/* Media never overflows its container (no display:block: inline images in rich text keep working). */
	img,
	video {
		max-width: 100%;
		height: auto;
	}

	canvas,
	svg {
		max-width: 100%;
	}

	/* Form controls use the surrounding typography. */
	input,
	button,
	textarea,
	select {
		font: inherit;
		color: inherit;
		letter-spacing: inherit;
	}

	/* Long words and URLs wrap instead of overflowing. */
	p,
	li,
	figcaption,
	blockquote,
	h1,
	h2,
	h3,
	h4,
	h5,
	h6 {
		overflow-wrap: break-word;
	}

	h1,
	h2,
	h3,
	h4 {
		text-wrap: balance;
	}

	p {
		text-wrap: pretty;
	}

	/* Unstyled list that keeps list semantics: <ul role="list">. */
	:where(ul, ol)[role="list"] {
		padding-inline-start: 0;
		list-style: none;
	}

	/* Anchor targets are not hidden under a sticky header. */
	:target {
		scroll-margin-block-start: var(--jsc-reset--scroll-offset, 5rem);
	}

	[hidden]:not([hidden="until-found"]) {
		display: none !important;
	}

	@media (prefers-reduced-motion: reduce) {

		*,
		*::before,
		*::after {
			scroll-behavior: auto !important;
			transition-duration: 0.01ms !important;
			animation-duration: 0.01ms !important;
			animation-iteration-count: 1 !important;
		}
	}
}
