/*
 * Kotlet — base stylesheet.
 *
 * Layer order is declared once, here, and never repeated. A rule in a later layer
 * always wins over an earlier one, no matter how specific the selector is. That is
 * what makes user CSS reliable: it sits in the last layer and simply works.
 */
@layer reset, tokens, base, layout, components, variants, utilities, overrides;

@layer tokens {
	/*
	 * Short aliases for the theme.json presets.
	 *
	 * WordPress generates names like --wp--preset--color--accent. They are correct
	 * but painful to type, so every token gets a --klt-* alias. Write --klt-* in
	 * theme CSS; change values in theme.json or in the Kotlet panel.
	 */
	:root {
		--klt-color-bg: var(--wp--preset--color--bg);
		--klt-color-surface: var(--wp--preset--color--surface);
		--klt-color-text: var(--wp--preset--color--text);
		--klt-color-muted: var(--wp--preset--color--muted);
		--klt-color-accent: var(--wp--preset--color--accent);
		--klt-color-accent-contrast: var(--wp--preset--color--accent-contrast);
		--klt-color-border: var(--wp--preset--color--border);

		/*
		 * The focus ring is two colours, not one, and neither of them is the
		 * accent. A single accent ring disappears twice: over a photograph,
		 * where some part of the picture is always that colour, and on the
		 * call to action, whose background IS the accent. Ink against paper is
		 * the one pair that survives both, and a ring of each means whatever
		 * the ring lands on, one of the two contrasts with it.
		 *
		 * They follow the scheme rather than being fixed: on a dark scheme the
		 * ring turns light and the halo dark, and the pair is still a pair.
		 * A variant that knows better can set either on itself.
		 */
		--klt-color-focus: var(--klt-color-text);
		--klt-color-focus-halo: var(--klt-color-bg);

		/*
		 * Two colours the palette deliberately does not carry.
		 *
		 * The palette is seven slugs wide and every one of them is offered in the
		 * block editor's picker; these two are not choices a writer makes. The
		 * hairline is the rule between one story and the next — a line thin enough
		 * that it reads as a gap, which is why it is written as ink at low opacity
		 * rather than as a grey that would go muddy on a tinted surface. The
		 * rule is shared by separators and status elements. It deliberately follows
		 * the accent rather than carrying a second, editorial-only highlight colour.
		 */
		--klt-color-rule: color-mix(in srgb, var(--klt-color-text) 28%, transparent);
		--klt-color-highlight: var(--klt-color-accent);

		--klt-font-display: var(--wp--preset--font-family--display);
		--klt-font-body: var(--wp--preset--font-family--body);
		--klt-font-meta: var(--wp--preset--font-family--meta);

		--klt-text-xs: var(--wp--preset--font-size--xs);
		--klt-text-s: var(--wp--preset--font-size--s);
		--klt-text-m: var(--wp--preset--font-size--m);
		--klt-text-l: var(--wp--preset--font-size--l);
		--klt-text-xl: var(--wp--preset--font-size--xl);
		--klt-text-xxl: var(--wp--preset--font-size--xxl);

		--klt-space-xs: var(--wp--preset--spacing--xs);
		--klt-space-s: var(--wp--preset--spacing--s);
		--klt-space-m: var(--wp--preset--spacing--m);
		--klt-space-l: var(--wp--preset--spacing--l);
		--klt-space-xl: var(--wp--preset--spacing--xl);

		--klt-radius-s: var(--wp--custom--radius--s);
		--klt-radius-m: var(--wp--custom--radius--m);
		--klt-radius-l: var(--wp--custom--radius--l);
		--klt-border-width: 1px;
		--klt-duration-interactive: 180ms;

		/*
		 * A pill is a shape, not a corner size: the three radius tokens above are a
		 * scale a site can dial down to square, and a category chip or a play
		 * button has to stay a pill when it does.
		 */
		--klt-radius-pill: 999px;

		/*
		 * The gutter between the text and the edge of the window, and the one
		 * number the container is not free to guess. It grows in one step rather
		 * than fluidly: a page whose margin creeps while the reader resizes looks
		 * broken in a way a jump at a breakpoint does not.
		 */
		--klt-gutter: var(--klt-space-s);

		--klt-width-content: var(--wp--style--global--content-size, 44rem);
		--klt-width-wide: var(--wp--style--global--wide-size, 90rem);
	}
}

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

	body {
		margin: 0;
	}

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

	/*
	 * Native progress controls need an explicit WebKit reset or iOS may keep
	 * its platform colour. Keep vendor pseudo-elements in separate rules:
	 * an unknown pseudo-element can invalidate a combined selector list.
	 */
	progress {
		-webkit-appearance: none;
		appearance: none;
	}

	progress::-webkit-progress-bar {
		background: transparent;
	}

	progress::-webkit-progress-value {
		background: currentcolor;
	}

	progress::-moz-progress-bar {
		background: currentcolor;
	}

	/*
	 * A reader who asked their system for less movement asked everything on the
	 * page, not only the parts this theme knows about. Individual components
	 * turn their own transitions off as well, and that is the honest way to do
	 * it; this is the net underneath, and it catches what neither the theme nor
	 * its variants wrote — a block's animation, somebody's own CSS, a plugin's
	 * carousel.
	 *
	 * Not zero: a duration of zero cancels the transitionend event some scripts
	 * wait for, and a script waiting for an event that never arrives leaves the
	 * page half open. A hundredth of a millisecond fires it immediately.
	 *
	 * !important, because the rule has to beat a variant's inline transition
	 * and the user stylesheet layer both. A preference is not a suggestion.
	 */
	@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;
		}
	}
}

@layer base {
	:root.klt-prevent-double-tap-zoom {
		touch-action: manipulation;
	}

	body {
		background: var(--klt-color-bg);
		color: var(--klt-color-text);
		font-family: var(--klt-font-body);
		line-height: var(--klt-body-line-height, 1.6);
	}

	/*
	 * Every keyboard user needs to see where they are. :focus-visible rather than
	 * :focus so a mouse click does not leave a ring behind — the outline is
	 * information, not decoration, and it must never be removed without a
	 * replacement.
	 *
	 * The halo fills the gap the offset leaves, so the ring reads element,
	 * halo, outline — three bands, the outer two in colours that contrast with
	 * each other. WCAG 2.2 asks the indicator to reach 3:1 against what is
	 * next to it (1.4.11); against a photograph nothing can promise that on its
	 * own, and a pair can.
	 */
	:focus-visible {
		outline: 2px solid var(--klt-color-focus);
		outline-offset: 2px;
		box-shadow: 0 0 0 2px var(--klt-color-focus-halo);
	}

	/*
	 * The skip link is hidden by .screen-reader-text, which lives in the
	 * utilities layer, so the rule that reveals it on focus has to live there
	 * too — see assets/css/utilities.css. A copy here would be a dead rule:
	 * later layers win over earlier ones whatever the selector says.
	 */
}

@layer components {
	/*
	 * A heading linked to from elsewhere lands under a header that sticks. The
	 * margin costs nothing when no header sticks, so it is not worth making
	 * conditional on one.
	 */
	:target {
		scroll-margin-block-start: calc(var(--klt-sticky-header-offset, 0px) + var(--klt-space-m));
	}

	.klt-brand {
		margin: 0;
	}

	.klt-nav__list {
		display: flex;
		flex-wrap: wrap;
		gap: var(--klt-space-s);
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.klt-footer-nav__list {
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.klt-meta {
		margin: 0;
	}

	.klt-entry__title {
		margin: 0;
	}

	.klt-entry__figure {
		margin: 0;
	}

	.klt-entry__caption {
		margin-block-start: var(--klt-space-xs);
	}

	.klt-entry__terms {
		display: flex;
		flex-wrap: wrap;
		gap: var(--klt-space-s);
		margin-block-start: var(--klt-space-m);
	}

	.klt-entry__categories,
	.klt-entry__tags {
		display: inline-flex;
		flex-wrap: wrap;
		gap: var(--klt-space-xs);
		align-items: baseline;
	}

	.klt-entry__terms-label {
		font-weight: bolder;
	}

	.klt-post-content-components,
	.klt-post-content-components__actions,
	.klt-post-content-components__author,
	.klt-post-content-components__navigation,
	.klt-post-content-components__comments {
		min-width: 0;
	}

	.klt-post-content-components__actions {
		display: grid;
		gap: var(--klt-space-m);
	}

	/*
	 * The author and adjacent-post navigation describe the article as one closing
	 * region. A profile may divide the region into columns without changing their
	 * semantic order, while the neutral layout remains a simple vertical stack.
	 */
	.klt-entry-footer {
		display: grid;
		gap: var(--klt-space-l);
	}

	/* Vertical rhythm inside running text, where the markup comes from the editor. */
	.klt-flow > * + * {
		margin-block-start: var(--klt-space-s);
	}

	.klt-flow > h2,
	.klt-flow > h3 {
		margin-block-start: var(--klt-space-l);
	}

	.klt-archive-header__title {
		margin: 0;
	}

	.klt-post-navigation {
		padding-block-start: var(--klt-space-l);
	}

	.klt-post-navigation .nav-links {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--klt-space-m);
		justify-content: space-between;
	}

	.klt-post-navigation .nav-next {
		text-align: end;
	}

	.klt-post-navigation a {
		display: grid;
		gap: var(--klt-space-xs);
		min-height: 2.75rem;
	}

	.klt-post-navigation__label {
		display: block;
	}

	.klt-post-navigation__title {
		overflow-wrap: anywhere;
	}

	@media (max-width: 40rem) {
		.klt-post-navigation .nav-links {
			grid-template-columns: minmax(0, 1fr);
		}

		.klt-post-navigation .nav-next {
			text-align: start;
		}
	}

	.klt-comments__list {
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.klt-comments__list .children {
		margin-inline-start: var(--klt-space-m);
		padding-inline-start: var(--klt-space-m);
		list-style: none;
	}

	.klt-comments__list .comment-body {
		padding-block: var(--klt-space-s);
	}

	/*
	 * A comment held for moderation has to say so where the author expects their
	 * comment to be, or they post it again.
	 */
	.klt-comments__list .comment-awaiting-moderation {
		display: block;
	}

	.klt-comment-form input[type="text"],
	.klt-comment-form input[type="email"],
	.klt-comment-form input[type="url"],
	.klt-comment-form textarea,
	.klt-search-form__field {
		width: 100%;
		max-width: 100%;
		padding: var(--klt-space-xs);
		font: inherit;
	}

	.klt-button,
	.klt-comment-form input[type="submit"] {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-height: 40px;
		padding: var(--klt-space-xs) var(--klt-space-s);
		font: inherit;
		cursor: pointer;
	}

	/*
	 * Page navigation as WordPress prints it, for the posts list and for the
	 * comments alike. It lives here rather than in the pagination variant,
	 * because comments.php prints the same markup without going through the
	 * component and would otherwise lose its styling on a page whose loop never
	 * rendered.
	 */
	.klt-pagination__nav {
		margin-block-start: var(--klt-space-xl);
	}

	.klt-pagination__nav .page-numbers {
		padding: var(--klt-space-xs);
	}

	/*
	 * The band a composed section stands in, and the heading over it. Chrome of
	 * the composer rather than of any component: the same heading sits over a
	 * grid, a carousel and a row alike, so a variant must not own it.
	 *
	 * Only a titled section prints this wrapper, which is why the spacing lives
	 * here and not on every section — a hero is a section too, and a gap over a
	 * full-bleed picture reads as a mistake.
	 */
	.klt-section {
		margin-block-start: var(--klt-space-xl);
	}

	.klt-section__header {
		justify-content: space-between;
		align-items: baseline;
		margin-block-end: var(--klt-space-m);
	}

	/*
	 * The name of a department, set like a headline and not like a label. It used
	 * to be small capitals over a heavy rule, which is a magazine's way of saying
	 * "a new part of the paper starts here"; this design says the same thing with
	 * the size of the type and the room around it, and a rule under every heading
	 * would be a third line competing with the ones the lists already draw.
	 *
	 * Nothing here sets a family, a size or a weight, and that is the point: this
	 * is an h2, theme.json prints elements.h2 unlayered, and a size written here
	 * would lose to it exactly the way the card titles did. What the heading
	 * wants *is* the h2 scale, so the rule says only what theme.json leaves open.
	 */
	.klt-section__title {
		margin: 0;
	}

	/* A stored legacy surface still needs structural breathing room. */
	.klt-band {
		padding-block: 3rem;
	}
}
