/**
 * Tab layouts — front end and editor canvas.
 *
 * Two block styles on core/tabs, beside core's own underlined tabs:
 *
 *   is-style-tab-buttons  every tab a button, in a Campweb button style
 *   is-style-tab-folder   the tabs sit on the panel's top edge like folder
 *                         tabs, the active one in the panel's own colours
 *
 * Both read their colours from custom properties on the Tabs wrapper: a
 * background and a text colour for each state, --campweb--tab-background and
 * -text, --campweb--tab-hover-* and --campweb--tab-active-*. Each layout sets
 * all six below as its defaults. Colours picked under Tab colors arrive inline
 * on the same wrapper (features/tabs/render.php, src/tabs/ in the canvas) and
 * win by being inline. A default may be worked out from another property, so
 * that it follows a picked colour: Active follows Hover in Buttons, for one.
 *
 * --campweb--tab-background-opacity, Tab colors' Background opacity, arrives
 * the same way. Only the resting tabs are mixed with it, so hovering a tab or
 * making it active shows that state's colour as picked.
 *
 * Every Buttons or Folder wrapper sets all seven, so a Tabs block nested in a
 * panel starts from its own layout rather than inheriting its parent's
 * colours. Child combinators keep the rules on the block's own tabs for the
 * same reason.
 *
 * The Tab List block's own colour, border and padding settings are written
 * onto every tab by core — inline, or as classes with !important — so they
 * still win over all of this, in every state.
 */

.wp-block-tabs.is-style-tab-buttons > .wp-block-tab-list > button::before,
.wp-block-tabs.is-style-tab-folder > .wp-block-tab-list > button::before {
	content: none;
}

/* Buttons
--------------------------------------------- */

/*
 * Brand, unless a has-tab-buttons-<key> class picks another Campweb button
 * style. Each copies its colours from the theme's styles/blocks/button/ and
 * its hover from theme.json, so they assume the Campweb palette. The active
 * tab keeps the hover colours, which is why there is no Fill: its hover is its
 * resting colours, and its active tab would not show.
 */
.wp-block-tabs.is-style-tab-buttons {
	--campweb--tab-background: var(--wp--preset--color--primary, CanvasText);
	--campweb--tab-background-opacity: 100%;
	--campweb--tab-text: var(--wp--preset--color--base, Canvas);
	--campweb--tab-ring: transparent;
	--campweb--tab-hover-background: color-mix(in srgb, var(--campweb--tab-background) 88%, #fff);
	--campweb--tab-hover-text: var(--campweb--tab-text);
	--campweb--tab-active-background: var(--campweb--tab-hover-background);
	--campweb--tab-active-text: var(--campweb--tab-hover-text);
}

.wp-block-tabs.is-style-tab-buttons > .wp-block-tab-list {
	font-size: var(--wp--preset--font-size--small, inherit);
	font-weight: 500;
}

/*
 * The Campweb button element's shape (theme.json styles.elements.button). The
 * outline styles draw their ring as an inset shadow rather than the buttons'
 * `outline`, so a keyboard-focused tab keeps the browser's focus outline.
 */
.wp-block-tabs.is-style-tab-buttons > .wp-block-tab-list > button {
	padding: 0.6em 1em;
	border-radius: 40px;
	background-color: color-mix(in srgb, var(--campweb--tab-background) var(--campweb--tab-background-opacity), transparent);
	color: var(--campweb--tab-text);
	box-shadow: inset 0 0 0 2px var(--campweb--tab-ring);
	transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}

.wp-block-tabs.is-style-tab-buttons > .wp-block-tab-list > button:hover {
	background-color: var(--campweb--tab-hover-background);
	color: var(--campweb--tab-hover-text);
	box-shadow: none;
}

.wp-block-tabs.is-style-tab-buttons > .wp-block-tab-list > button[aria-selected=true] {
	background-color: var(--campweb--tab-active-background);
	color: var(--campweb--tab-active-text);
	box-shadow: none;
}

/*
 * The other button styles. More specific than the Brand defaults, and scoped
 * to Buttons, so a style left behind after switching to Folder does nothing.
 */
/*
 * on-primary-alt and primary-alt-on-dark are the theme's colours derived from
 * Brand Alt, readable on it and on dark panels whatever Brand Alt is set to.
 * The fallbacks are the pairing used before they existed.
 */
.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-brand-alt {
	--campweb--tab-background: var(--wp--preset--color--primary-alt);
	--campweb--tab-text: var(--wp--preset--color--on-primary-alt, var(--wp--preset--color--primary-alt-accent));
	--campweb--tab-hover-background: var(--wp--preset--color--primary-alt-accent);
	--campweb--tab-hover-text: var(--wp--preset--color--primary-alt-on-dark, var(--wp--preset--color--primary-alt));
}

.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-dark {
	--campweb--tab-background: var(--wp--preset--color--main);
	--campweb--tab-text: var(--wp--preset--color--base);
	--campweb--tab-hover-background: var(--wp--preset--color--primary-alt-accent);
}

.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-light {
	--campweb--tab-background: var(--wp--preset--color--base);
	--campweb--tab-text: var(--wp--preset--color--main);
	--campweb--tab-hover-background: var(--wp--preset--color--main);
	--campweb--tab-hover-text: var(--wp--preset--color--base);
}

.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-tint {
	--campweb--tab-background: var(--wp--preset--color--tertiary);
	--campweb--tab-text: var(--wp--preset--color--main);
	--campweb--tab-hover-background: var(--wp--preset--color--border-light);
}

/* The outline buttons: a ring in the text colour, filled in on hover. */
.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-outline,
.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-outline-brand,
.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-outline-light {
	--campweb--tab-background: transparent;
	--campweb--tab-ring: currentColor;
}

.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-outline {
	--campweb--tab-text: var(--wp--preset--color--main);
	--campweb--tab-hover-background: var(--wp--preset--color--main);
	--campweb--tab-hover-text: var(--wp--preset--color--base);
}

.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-outline-brand {
	--campweb--tab-text: var(--wp--preset--color--primary);
	--campweb--tab-hover-background: var(--wp--preset--color--primary);
	--campweb--tab-hover-text: var(--wp--preset--color--base);
}

.wp-block-tabs.is-style-tab-buttons.has-tab-buttons-outline-light {
	--campweb--tab-text: var(--wp--preset--color--base);
	--campweb--tab-hover-background: var(--wp--preset--color--base);
	--campweb--tab-hover-text: var(--wp--preset--color--main);
}

/* Folder
--------------------------------------------- */

/*
 * The inactive tabs make a strip in the tab background; the active tab and
 * the panel below it share the active colours, so the two read as one card.
 * Hover lightens a tab by mixing in its text colour, so it follows whatever
 * colours are picked.
 */
.wp-block-tabs.is-style-tab-folder {
	--campweb--tab-background: var(--wp--preset--color--main, CanvasText);
	--campweb--tab-background-opacity: 100%;
	--campweb--tab-text: var(--wp--preset--color--base, Canvas);
	--campweb--tab-hover-background: color-mix(in srgb, var(--campweb--tab-text) 12%, transparent);
	--campweb--tab-hover-text: var(--campweb--tab-text);
	--campweb--tab-active-background: var(--wp--preset--color--base, Canvas);
	--campweb--tab-active-text: var(--wp--preset--color--main, CanvasText);
	--campweb--tab-folder-radius: var(--wp--preset--border-radius--md, 10px);
}

/*
 * Only as wide as its tabs, with no gap between them — the Tab List's Block
 * spacing has no effect here — and flush with the panel. The strip's rounded
 * corners are the Tab List's own: it scrolls when the tabs do not fit (see
 * Swipe row), which clips the tabs to its corners as they move under them.
 */
.wp-block-tabs.is-style-tab-folder > .wp-block-tab-list {
	width: fit-content;
	max-width: 100%;
	gap: 0;
	margin-block: 0;
	border-start-start-radius: var(--campweb--tab-folder-radius);
	border-start-end-radius: var(--campweb--tab-folder-radius);
}

/*
 * Each tab paints its own piece of the strip, rather than the Tab List
 * painting it behind them: a strip underneath would show as a hairline around
 * the active tab's rounded corner. Hover is a layer over that background — an
 * inset shadow, which fills the tab inside its corners and, unlike a gradient,
 * fades in — so a see-through hover colour lightens or darkens the strip.
 */
.wp-block-tabs.is-style-tab-folder > .wp-block-tab-list > button {
	padding: 1em 1.75em;
	background-color: color-mix(in srgb, var(--campweb--tab-background) var(--campweb--tab-background-opacity), transparent);
	color: var(--campweb--tab-text);
	box-shadow: inset 0 0 0 100vmax transparent;
	transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}

/* Tighter on phones, so a few short tabs fit without scrolling. */
@media (max-width: 600px) {
	.wp-block-tabs.is-style-tab-folder > .wp-block-tab-list > button {
		padding: 0.85em 1.15em;
	}
}

.wp-block-tabs.is-style-tab-folder > .wp-block-tab-list > button:hover {
	color: var(--campweb--tab-hover-text);
	box-shadow: inset 0 0 0 100vmax var(--campweb--tab-hover-background);
}

.wp-block-tabs.is-style-tab-folder > .wp-block-tab-list > button[aria-selected=true] {
	background-color: var(--campweb--tab-active-background);
	color: var(--campweb--tab-active-text);
	box-shadow: inset 0 0 0 100vmax transparent;
}

/*
 * The panel takes the active tab's colours, and squares the corner the tabs
 * start from. The Tab Panels block's own colour, padding and radius settings
 * win over these.
 */
.wp-block-tabs.is-style-tab-folder > .wp-block-tab-panels {
	margin-block-start: 0;
	padding: var(--wp--preset--spacing--large, 2rem);
	background-color: var(--campweb--tab-active-background);
	color: var(--campweb--tab-active-text);
	border-start-start-radius: 0;
	border-start-end-radius: var(--campweb--tab-folder-radius);
	border-end-end-radius: var(--campweb--tab-folder-radius);
	border-end-start-radius: var(--campweb--tab-folder-radius);
}

/* Swipe row
--------------------------------------------- */

/*
 * In every layout, core's underlined tabs included, the tabs stay on one row.
 * Core wraps them onto more, which in Folder lifts the active tab off the
 * panel. Tabs that do not fit scroll sideways instead: by swipe, by trackpad,
 * by dragging with a mouse (src/tabs/view.js), or with the arrow keys, which
 * move focus and so scroll the focused tab into view. The scrollbar is hidden
 * — in Folder it would sit between the tabs and the panel — and the fade below
 * shows where there is more.
 *
 * A scrolling row clips whatever leaves it, focus outlines included, so a
 * focused tab draws its outline inside itself.
 */
.wp-block-tabs > .wp-block-tab-list {
	flex-wrap: nowrap;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	scrollbar-width: none;
}

.wp-block-tabs > .wp-block-tab-list::-webkit-scrollbar {
	display: none;
}

.wp-block-tabs > .wp-block-tab-list > button {
	flex-shrink: 0;
}

.wp-block-tabs > .wp-block-tab-list > button:focus-visible {
	outline-offset: -2px;
}

/* While a mouse drags the row (src/tabs/view.js). */
.wp-block-tabs > .wp-block-tab-list.is-dragging,
.wp-block-tabs > .wp-block-tab-list.is-dragging > button {
	cursor: grabbing;
	-webkit-user-select: none;
	user-select: none;
}

/*
 * Centred or right-aligned tabs that overflow would push the first tabs past
 * the start of the row, where no scrolling reaches them. `safe` falls back to
 * the start instead.
 */
.wp-block-tabs > .wp-block-tab-list.is-content-justification-center {
	justify-content: safe center;
}

.wp-block-tabs > .wp-block-tab-list.is-content-justification-right {
	justify-content: safe flex-end;
}

/*
 * A row that scrolls fades out towards each edge it can still scroll to, so a
 * tab cut off there reads as "more this way". The fades follow the scroll
 * position through a scroll-driven animation, which only runs while the row
 * can scroll: a row whose tabs fit is left alone. Browsers without scroll
 * timelines get no fade.
 */
@property --campweb--tab-fade-start {
	syntax: "<length>";
	inherits: false;
	initial-value: 0px;
}

@property --campweb--tab-fade-end {
	syntax: "<length>";
	inherits: false;
	initial-value: 0px;
}

@keyframes campweb-tab-fade {
	from {
		--campweb--tab-fade-start: 0px;
		--campweb--tab-fade-end: 2rem;
	}

	5% {
		--campweb--tab-fade-start: 2rem;
	}

	95% {
		--campweb--tab-fade-end: 2rem;
	}

	to {
		--campweb--tab-fade-start: 2rem;
		--campweb--tab-fade-end: 0px;
	}
}

@supports (animation-timeline: scroll()) {
	.wp-block-tabs > .wp-block-tab-list {
		animation: campweb-tab-fade linear both;
		animation-timeline: scroll(self inline);
		-webkit-mask-image: linear-gradient(to right, transparent, #000 var(--campweb--tab-fade-start), #000 calc(100% - var(--campweb--tab-fade-end)), transparent);
		mask-image: linear-gradient(to right, transparent, #000 var(--campweb--tab-fade-start), #000 calc(100% - var(--campweb--tab-fade-end)), transparent);
	}

	/* Gradients have no logical directions; right to left starts on the right. */
	.wp-block-tabs > .wp-block-tab-list:dir(rtl) {
		-webkit-mask-image: linear-gradient(to left, transparent, #000 var(--campweb--tab-fade-start), #000 calc(100% - var(--campweb--tab-fade-end)), transparent);
		mask-image: linear-gradient(to left, transparent, #000 var(--campweb--tab-fade-start), #000 calc(100% - var(--campweb--tab-fade-end)), transparent);
	}
}

/* Stacking
--------------------------------------------- */

/*
 * Core makes every tab `position: relative`, for its underline, so the tabs
 * paint above a positioned block they overlap — a Cover the Tabs block is
 * pulled up over with a negative top margin, say — while the panels, not
 * being positioned, paint beneath it. Positioning the panels as well keeps
 * the tabs and the panel card on one layer.
 */
.wp-block-tabs > .wp-block-tab-panels {
	position: relative;
}

/* Panel fade
--------------------------------------------- */

/*
 * Switching tabs fades the old panel out, then the new one in, each over
 * --campweb--tab-panel-fade, eased in and out. The new panel waits out the
 * old one's fade, so the two are never both half visible.
 *
 * Core hides an inactive panel with the hidden attribute and
 * `display: none !important`. A running transition outranks even that, so
 * `allow-discrete` keeps the old panel displayed until its fade ends, and
 * @starting-style gives the new one an opacity to fade in from. For that
 * moment the two share one grid cell rather than stacking, so the content
 * below the tabs stays put. Browsers without either feature switch at once,
 * as core does.
 *
 * Small and set off by the visitor, like the tab hover transitions, so it is
 * not gated on reduced motion. Every layout, and the editor canvas too.
 */
.wp-block-tabs {
	--campweb--tab-panel-fade: 0.15s;
}

.wp-block-tabs > .wp-block-tab-panels {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
}

.wp-block-tabs > .wp-block-tab-panels > .wp-block-tab-panel {
	grid-area: 1 / 1;
	transition: opacity var(--campweb--tab-panel-fade) ease-in-out var(--campweb--tab-panel-fade);
}

@starting-style {
	.wp-block-tabs > .wp-block-tab-panels > .wp-block-tab-panel {
		opacity: 0;
	}
}

.wp-block-tabs > .wp-block-tab-panels > .wp-block-tab-panel[hidden] {
	opacity: 0;
	transition:
		opacity var(--campweb--tab-panel-fade) ease-in-out,
		display var(--campweb--tab-panel-fade) allow-discrete;
}

/* Tab icons
--------------------------------------------- */

/*
 * Core draws the tab buttons itself, in the editor as well, so a single tab
 * cannot be given a class or a style of its own. Each icon arrives on the Tab
 * List instead, as --campweb--tab-icon-<n> with a campweb-tab-icon-<n> class,
 * and the n-th tab picks it up. Up to MAX_ICONS (12) tabs; render.php and
 * src/tabs/output.js stop there too.
 *
 * Works in every layout, underlined tabs included. The icon sits before the
 * label, painted like the button icons: a mask over currentColor, so it takes
 * the tab's text colour in every state. It is drawn on ::after and moved to
 * the front, since core's underline uses ::before.
 */
.wp-block-tab-list > button:nth-child(1) { --campweb--tab-icon: var(--campweb--tab-icon-1); }
.wp-block-tab-list > button:nth-child(2) { --campweb--tab-icon: var(--campweb--tab-icon-2); }
.wp-block-tab-list > button:nth-child(3) { --campweb--tab-icon: var(--campweb--tab-icon-3); }
.wp-block-tab-list > button:nth-child(4) { --campweb--tab-icon: var(--campweb--tab-icon-4); }
.wp-block-tab-list > button:nth-child(5) { --campweb--tab-icon: var(--campweb--tab-icon-5); }
.wp-block-tab-list > button:nth-child(6) { --campweb--tab-icon: var(--campweb--tab-icon-6); }
.wp-block-tab-list > button:nth-child(7) { --campweb--tab-icon: var(--campweb--tab-icon-7); }
.wp-block-tab-list > button:nth-child(8) { --campweb--tab-icon: var(--campweb--tab-icon-8); }
.wp-block-tab-list > button:nth-child(9) { --campweb--tab-icon: var(--campweb--tab-icon-9); }
.wp-block-tab-list > button:nth-child(10) { --campweb--tab-icon: var(--campweb--tab-icon-10); }
.wp-block-tab-list > button:nth-child(11) { --campweb--tab-icon: var(--campweb--tab-icon-11); }
.wp-block-tab-list > button:nth-child(12) { --campweb--tab-icon: var(--campweb--tab-icon-12); }

.wp-block-tab-list.campweb-tab-icon-1 > button:nth-child(1),
.wp-block-tab-list.campweb-tab-icon-2 > button:nth-child(2),
.wp-block-tab-list.campweb-tab-icon-3 > button:nth-child(3),
.wp-block-tab-list.campweb-tab-icon-4 > button:nth-child(4),
.wp-block-tab-list.campweb-tab-icon-5 > button:nth-child(5),
.wp-block-tab-list.campweb-tab-icon-6 > button:nth-child(6),
.wp-block-tab-list.campweb-tab-icon-7 > button:nth-child(7),
.wp-block-tab-list.campweb-tab-icon-8 > button:nth-child(8),
.wp-block-tab-list.campweb-tab-icon-9 > button:nth-child(9),
.wp-block-tab-list.campweb-tab-icon-10 > button:nth-child(10),
.wp-block-tab-list.campweb-tab-icon-11 > button:nth-child(11),
.wp-block-tab-list.campweb-tab-icon-12 > button:nth-child(12) {
	display: flex;
	align-items: center;
	gap: 0.6em;
}

.wp-block-tab-list.campweb-tab-icon-1 > button:nth-child(1)::after,
.wp-block-tab-list.campweb-tab-icon-2 > button:nth-child(2)::after,
.wp-block-tab-list.campweb-tab-icon-3 > button:nth-child(3)::after,
.wp-block-tab-list.campweb-tab-icon-4 > button:nth-child(4)::after,
.wp-block-tab-list.campweb-tab-icon-5 > button:nth-child(5)::after,
.wp-block-tab-list.campweb-tab-icon-6 > button:nth-child(6)::after,
.wp-block-tab-list.campweb-tab-icon-7 > button:nth-child(7)::after,
.wp-block-tab-list.campweb-tab-icon-8 > button:nth-child(8)::after,
.wp-block-tab-list.campweb-tab-icon-9 > button:nth-child(9)::after,
.wp-block-tab-list.campweb-tab-icon-10 > button:nth-child(10)::after,
.wp-block-tab-list.campweb-tab-icon-11 > button:nth-child(11)::after,
.wp-block-tab-list.campweb-tab-icon-12 > button:nth-child(12)::after {
	content: "";
	order: -1;
	flex-shrink: 0;
	width: 1.25em;
	height: 1.25em;
	background-color: currentColor;
	-webkit-mask-image: var(--campweb--tab-icon);
	mask-image: var(--campweb--tab-icon);
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
}
