/*
Theme Name: DIGISTARTER
Author: DIGISTALTER GmbH
Author URI: https://www.digistalter.de/
Description: A fast-launching block theme with ready-made patterns and six style variations - enough to build almost any page straight out of the box, and easy to extend further through a child theme.
Requires at least: 7.0
Tested up to: 7.1
Requires PHP: 7.4
Version: 1.2.8
License: GNU General Public License v3
License URI: https://www.gnu.org/licenses/gpl-3.0.html
Text Domain: digistarter
Tags: full-site-editing, block-patterns, block-styles, style-variations, custom-colors, custom-logo, custom-menu, editor-style, featured-images, one-column, threaded-comments, translation-ready, wide-blocks, rtl-language-support
*/

/* --------------------------------------------------------------------------
   Most of the design lives in theme.json (colours, type, spacing, element
   and block styles) and in the style variations under /styles. This file
   holds what theme.json can't express: colour schemes per surface, the
   pattern layouts and their scroll effects. Breakpoints are container
   queries at 782px, so the editor canvas matches the front end.

   Contents
   - Colour schemes
   - Links and navigation
   - Spacing
   - Long words
   - Blocks
   - Header search
   - Forms
   - Mobile menu
   - Pattern layouts (shared)
   - Patterns: Opener, Centered opener, Full-screen opener, Video opener,
     Opener with tabs, Marquee, Media marquee, Sliding statement, Scroll
     fill, Text with media, Testimonials, Media grid, Video stack, Media
     slider, Key figures, Tiles, Call to action with media, Timeline,
     History, Statement, Staggered text and media, Zigzag, Events, Pricing,
     Price with tiers, Certificates, Logo bar, Steps, Comparison,
     Comparison table
   - Accordions, Quote, Tabs, Legal page, FAQ, Lists
   - Posts
   - Footer
   - Cursor
   -------------------------------------------------------------------------- */

/* ==========================================================================
   Colour schemes
   The values live in theme.json (settings.custom.scheme). Every element reads
   its colour from a role (--wp--custom--color--*); these rules only switch the
   roles to the scheme that stays readable on the block's background.
   ========================================================================== */

/* Light surfaces - also resets the roles inside a dark or accent section.
   A comment's bubble is white (see Posts). */
.has-base-background-color,
.has-neutral-background-color,
.is-style-section-neutral,
.wp-block-cover.is-light,
.wp-block-navigation__responsive-container.is-menu-open:not(.has-background),
.comment-bubble,
.opener-tabs__box,
.opener-tabs.is-style-section-neutral > .opener-tabs__box,
:is(.is-style-section-neutral, .has-neutral-background-color) .section-box.is-style-section-neutral,
:is(.is-style-section-primary, .has-primary-background-color) .section-box.is-style-section-primary,
:is(.is-style-section-accent, .has-accent-background-color) .section-box.is-style-section-accent,
.has-contrast-background-color .section-box.is-style-section-contrast {
	--wp--custom--color--text: var(--wp--custom--scheme--light--text);
	--wp--custom--color--heading: var(--wp--custom--scheme--light--heading);
	--wp--custom--color--link: var(--wp--custom--scheme--light--link);
	--wp--custom--color--link-hover: var(--wp--custom--scheme--light--link-hover);
	--wp--custom--color--link-hover-accent: var(--wp--custom--scheme--light--link-hover-accent);
	--wp--custom--color--link-active: var(--wp--custom--scheme--light--link-active);
	--wp--custom--color--caption: var(--wp--custom--scheme--light--caption);
	--wp--custom--color--focus: var(--wp--custom--scheme--light--focus);
	--wp--custom--color--button-background: var(--wp--custom--scheme--light--button-background);
	--wp--custom--color--button-text: var(--wp--custom--scheme--light--button-text);
	--wp--custom--color--button-hover-background: var(--wp--custom--scheme--light--button-hover-background);
	--wp--custom--color--button-hover-text: var(--wp--custom--scheme--light--button-hover-text);
	--wp--custom--color--outline: var(--wp--custom--scheme--light--outline);
	--wp--custom--color--outline-hover: var(--wp--custom--scheme--light--outline-hover);
	--digistarter-check: var(--wp--preset--color--accent);
	color: var(--wp--custom--color--text);
}

/* Dark surfaces. A cover without .is-light has a dark image or overlay;
   dropdown submenus are primary panels (see Links and navigation); the
   highlight card turns primary on its neutral band, and so does the bubble
   of a reply to a comment (see Posts). */
.has-primary-background-color,
.has-primary-gradient-gradient-background,
.is-style-section-primary,
.opener-tabs.is-style-section-primary > .opener-tabs__box,
.wp-block-cover:not(.is-light),
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container,
.post-band.has-neutral-background-color .post-card,
.wp-block-comment-template li li .comment-bubble {
	--wp--custom--color--text: var(--wp--custom--scheme--dark--text);
	--wp--custom--color--heading: var(--wp--custom--scheme--dark--heading);
	--wp--custom--color--link: var(--wp--custom--scheme--dark--link);
	--wp--custom--color--link-hover: var(--wp--custom--scheme--dark--link-hover);
	--wp--custom--color--link-hover-accent: var(--wp--custom--scheme--dark--link-hover-accent);
	--wp--custom--color--link-active: var(--wp--custom--scheme--dark--link-active);
	--wp--custom--color--caption: var(--wp--custom--scheme--dark--caption);
	--wp--custom--color--focus: var(--wp--custom--scheme--dark--focus);
	--wp--custom--color--button-background: var(--wp--custom--scheme--dark--button-background);
	--wp--custom--color--button-text: var(--wp--custom--scheme--dark--button-text);
	--wp--custom--color--button-hover-background: var(--wp--custom--scheme--dark--button-hover-background);
	--wp--custom--color--button-hover-text: var(--wp--custom--scheme--dark--button-hover-text);
	--wp--custom--color--outline: var(--wp--custom--scheme--dark--outline);
	--wp--custom--color--outline-hover: var(--wp--custom--scheme--dark--outline-hover);
	--digistarter-check: var(--wp--preset--color--accent);
	color: var(--wp--custom--color--text);
}

/* A text-coloured surface, e.g. the key-figures pattern's second box. Kept
   out of the Styles tab on purpose (no styles/*.json), but named like a
   section style so picking one there replaces it. Its own scheme (inverse):
   dark like the dark one in the light style variations, light in the dark
   ones, where the text colour is a light one. */
.is-style-section-contrast {
	background-color: var(--wp--preset--color--contrast);
}

.has-contrast-background-color,
.is-style-section-contrast {
	--wp--custom--color--text: var(--wp--custom--scheme--inverse--text);
	--wp--custom--color--heading: var(--wp--custom--scheme--inverse--heading);
	--wp--custom--color--link: var(--wp--custom--scheme--inverse--link);
	--wp--custom--color--link-hover: var(--wp--custom--scheme--inverse--link-hover);
	--wp--custom--color--link-hover-accent: var(--wp--custom--scheme--inverse--link-hover-accent);
	--wp--custom--color--link-active: var(--wp--custom--scheme--inverse--link-active);
	--wp--custom--color--caption: var(--wp--custom--scheme--inverse--caption);
	--wp--custom--color--focus: var(--wp--custom--scheme--inverse--focus);
	--wp--custom--color--button-background: var(--wp--custom--scheme--inverse--button-background);
	--wp--custom--color--button-text: var(--wp--custom--scheme--inverse--button-text);
	--wp--custom--color--button-hover-background: var(--wp--custom--scheme--inverse--button-hover-background);
	--wp--custom--color--button-hover-text: var(--wp--custom--scheme--inverse--button-hover-text);
	--wp--custom--color--outline: var(--wp--custom--scheme--inverse--outline);
	--wp--custom--color--outline-hover: var(--wp--custom--scheme--inverse--outline-hover);
	--digistarter-check: var(--wp--preset--color--accent);
	color: var(--wp--custom--color--text);
}

/* The dark tint over a cover's image (the patterns' "contrast" overlay) and
   the full-screen opener's ground stay dark in every style variation - a
   role of its own (custom.coverTint), since the dark variations turn the
   contrast colour itself light. */
.wp-block-cover > .wp-block-cover__background.has-contrast-background-color {
	background-color: var(--wp--custom--cover-tint) !important;
}

/* Accent surfaces. The bubble of a reply to a reply is accent (see Posts). */
.has-accent-background-color,
.has-secondary-gradient-gradient-background,
.is-style-section-accent,
.opener-tabs.is-style-section-accent > .opener-tabs__box,
.wp-block-comment-template li li li .comment-bubble {
	--wp--custom--color--text: var(--wp--custom--scheme--accent--text);
	--wp--custom--color--heading: var(--wp--custom--scheme--accent--heading);
	--wp--custom--color--link: var(--wp--custom--scheme--accent--link);
	--wp--custom--color--link-hover: var(--wp--custom--scheme--accent--link-hover);
	--wp--custom--color--link-hover-accent: var(--wp--custom--scheme--accent--link-hover-accent);
	--wp--custom--color--link-active: var(--wp--custom--scheme--accent--link-active);
	--wp--custom--color--caption: var(--wp--custom--scheme--accent--caption);
	--wp--custom--color--focus: var(--wp--custom--scheme--accent--focus);
	--wp--custom--color--button-background: var(--wp--custom--scheme--accent--button-background);
	--wp--custom--color--button-text: var(--wp--custom--scheme--accent--button-text);
	--wp--custom--color--button-hover-background: var(--wp--custom--scheme--accent--button-hover-background);
	--wp--custom--color--button-hover-text: var(--wp--custom--scheme--accent--button-hover-text);
	--wp--custom--color--outline: var(--wp--custom--scheme--accent--outline);
	--wp--custom--color--outline-hover: var(--wp--custom--scheme--accent--outline-hover);
	--digistarter-check: var(--wp--preset--color--primary);
	color: var(--wp--custom--color--text);
}

/* A button colour picked in Styles > Elements > Button is saved as a fixed
   colour for every button and so overrides the roles above - on an accent
   surface a button in, say, the accent colour would vanish into it. There
   the scheme's own button takes over again (dark on the accent, turning
   light on hover); everywhere else the picked colour stays. A button with
   a colour of its own, set on the block, keeps it. */
:is(.has-accent-background-color, .has-secondary-gradient-gradient-background, .is-style-section-accent, .wp-block-comment-template li li li .comment-bubble) .wp-element-button:not(.has-background, .is-style-outline .wp-block-button__link) {
	background-color: var(--wp--custom--color--button-background);
}

:is(.has-accent-background-color, .has-secondary-gradient-gradient-background, .is-style-section-accent, .wp-block-comment-template li li li .comment-bubble) .wp-element-button:not(.has-text-color, .is-style-outline .wp-block-button__link) {
	color: var(--wp--custom--color--button-text);
}

:is(.has-accent-background-color, .has-secondary-gradient-gradient-background, .is-style-section-accent, .wp-block-comment-template li li li .comment-bubble) .wp-element-button:not(.has-background, .is-style-outline .wp-block-button__link):hover {
	background-color: var(--wp--custom--color--button-hover-background);
}

:is(.has-accent-background-color, .has-secondary-gradient-gradient-background, .is-style-section-accent, .wp-block-comment-template li li li .comment-bubble) .wp-element-button:not(.has-text-color, .is-style-outline .wp-block-button__link):hover {
	color: var(--wp--custom--color--button-hover-text);
}

/* A text colour the user picked wins: headings and links follow it. Must stay
   below the scheme rules, which have the same specificity. */
.has-text-color {
	--wp--custom--color--heading: currentColor;
	--wp--custom--color--link: currentColor;
}

/* ==========================================================================
   Links and navigation
   ========================================================================== */

/* Core forces navigation items to inherit the navigation's text colour with a
   doubled class; match that so menus follow the link roles like any text link.
   A text colour set on the navigation block itself still wins. */
.wp-block-navigation:not(.has-text-color) .wp-block-navigation-item__content.wp-block-navigation-item__content {
	color: var(--wp--custom--color--link);
}

.wp-block-navigation:not(.has-text-color) .wp-block-navigation-item__content.wp-block-navigation-item__content:hover {
	color: var(--wp--custom--color--link-hover);
}

/* Hovered links and the current menu item get a 2px underline in the scheme's
   hover accent - accent on light and dark surfaces, where the text keeps its
   colour (accent text on white would be unreadable). Icon-only links have no
   text to underline and take the hover accent as their colour instead.
   Buttons have their own hover. */
a:where(:not(.wp-element-button)):hover,
a[aria-current="page"] {
	text-decoration-line: underline;
	text-decoration-color: var(--wp--custom--color--link-hover-accent);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.2em;
}

/* Menus draw that line under the label instead, so it can slide in from the
   left (text-decoration can't be animated). Links without a label span, such
   as page lists, keep the underline above. */
.wp-block-navigation a.wp-block-navigation-item__content:has(.wp-block-navigation-item__label) {
	text-decoration-line: none;
}

.wp-block-navigation-item__label {
	padding-bottom: 0.1em;
	background: linear-gradient(var(--wp--custom--color--link-hover-accent), var(--wp--custom--color--link-hover-accent)) left bottom / 0 2px no-repeat;
	-webkit-box-decoration-break: clone;
	box-decoration-break: clone;
	transition: background-size 0.3s ease;
}

.wp-block-navigation-item__content:hover .wp-block-navigation-item__label,
.wp-block-navigation-item__content[aria-current="page"] .wp-block-navigation-item__label {
	background-size: 100% 2px;
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-navigation-item__label {
		transition: none;
	}
}

/* WordPress marks the current menu item with aria-current itself but applies
   no colour of its own. The !important here isn't beating core - it's beating
   our own nav-link rule above, which had to out-rank core's own doubled-class
   selector and is therefore specific enough to win over a plain attribute
   selector otherwise. */
a[aria-current="page"] {
	color: var(--wp--custom--color--link-active) !important;
}

/* Dropdown submenus read as a primary panel of their own (dark scheme, see
   Colour schemes) - otherwise they inherit the menu's background and blend
   into the page. Not in the mobile overlay, where submenus are listed inline. */
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container {
	padding: 0.5em 0;
	border: 0;
	border-radius: var(--wp--custom--radius);
	background-color: var(--wp--preset--color--primary);
}

/* Core gives each item the menu's background; square items would stick out
   of the panel's rounded corners. */
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container > .wp-block-navigation-item {
	border-radius: inherit;
}

/* Submenus don't make sense in a footer navigation. */
.site-footer .wp-block-navigation-submenu__toggle,
.site-footer .wp-block-navigation__submenu-container {
	display: none !important;
}

/* Visible keyboard focus on every interactive element. */
:where(a, button, input, select, textarea, summary, .wp-element-button):focus-visible {
	outline: 2px solid var(--wp--custom--color--focus);
	outline-offset: 2px;
}

/* ==========================================================================
   Spacing
   The space between blocks is theme.json's custom.blockGap (spacing m, used
   as styles.spacing.blockGap) - the right amount once there is room for it.
   Below that, halved to s: the same step down the none/s/m/l scale every
   other mobile adjustment in this file uses. Changing the value, not core's
   margin rules, leaves a block's own gap setting (a comment's 0.5em, say) in
   charge of its own children on every screen size. The largest step, l, is
   halved the same way (to m's 48px): section padding and the space between a
   section's head and its content, which would leave a phone mostly blank.
   And m itself (to s's 24px): the page margin and everything lined up with
   it (strips running to the screen edge, the header) - 48px on either side
   left a phone's content barely three quarters of the screen.
   ========================================================================== */

/* :root twice: the editor prints the theme.json values on :root after this
   file, and a tie would let them win there. */
@media (max-width: 781px) {
	:root:root {
		--wp--custom--block-gap: var(--wp--preset--spacing--s);
		--wp--preset--spacing--l: 48px;
		--wp--preset--spacing--m: 24px;
	}
}

/* Every pattern layout below that spaces its parts with a flex/grid gap -
   the block gap's sibling margin on top would double it. .wp-block-group in
   front for enough weight to also beat the editor canvas's own copy of the
   block gap rule. */
.wp-block-group:is(.opener, .opener__media, .opener-tabs, .text-media, .testimonials, .testimonials__cards, .media-grid, .video-stack, .zigzag, .zigzag__row, .events, .events__row, .pricing, .price-tiers, .certificates, .logo-bar, .steps, .statement, .staggered, .staggered__half, .cta-box, .timeline__body, .timeline__steps, .history__card, .media-marquee, .media-marquee__track, .slider, .slider__track, .key-figures, .tiles, .faq, .faq__list) > * {
	margin-block-start: 0;
}

/* Two full-width sections meet without a gap - their own padding (l) already
   spaces their content, so content sits exactly l from any colour edge.
   Covers count as sections too (the full-screen and video opener, a cover
   of the user's own): their picture reaches the next section. The gap
   stays only next to a block that isn't a full-width section. */
:is(.wp-block-group, .wp-block-cover).alignfull + :is(.wp-block-group, .wp-block-cover).alignfull {
	margin-block-start: 0;
}

/* ...except two sections on the same ground - plain after plain, or the same
   section style twice: no colour edge between them, so 2l would read as a
   hole. The second one drops its top padding, so their content is l apart
   like everywhere else. Not after the full-screen patterns, which have no
   padding of their own (video stack, scroll fill, opener with tabs), nor
   for them; the timeline's padding sits on its stage. !important against
   the patterns' inline padding. */
.wp-block-group.alignfull:not([class*="is-style-section-"], .has-background, .video-stack, .scroll-fill, .opener-tabs) + .wp-block-group.alignfull:not([class*="is-style-section-"], .has-background, .video-stack, .scroll-fill, .opener-tabs, .timeline),
.wp-block-group.alignfull.is-style-section-neutral:not(.scroll-fill, .opener-tabs) + .wp-block-group.alignfull.is-style-section-neutral:not(.scroll-fill, .opener-tabs, .timeline),
.wp-block-group.alignfull.is-style-section-primary:not(.scroll-fill, .opener-tabs) + .wp-block-group.alignfull.is-style-section-primary:not(.scroll-fill, .opener-tabs, .timeline),
.wp-block-group.alignfull.is-style-section-accent:not(.scroll-fill, .opener-tabs) + .wp-block-group.alignfull.is-style-section-accent:not(.scroll-fill, .opener-tabs, .timeline),
.wp-block-group.alignfull:not([class*="is-style-section-"], .has-background, .video-stack, .scroll-fill, .opener-tabs) + .timeline:not([class*="is-style-section-"], .has-background) > .timeline__stage,
.wp-block-group.alignfull.is-style-section-neutral:not(.scroll-fill, .opener-tabs) + .timeline.is-style-section-neutral > .timeline__stage,
.wp-block-group.alignfull.is-style-section-primary:not(.scroll-fill, .opener-tabs) + .timeline.is-style-section-primary > .timeline__stage,
.wp-block-group.alignfull.is-style-section-accent:not(.scroll-fill, .opener-tabs) + .timeline.is-style-section-accent > .timeline__stage {
	padding-top: 0 !important;
}

/* ==========================================================================
   Long words
   A long word (German compounds, product names) that doesn't fit its line
   gets hyphenated in the page's language (<html lang>), so it can't push a
   card, tile or column wider; only words of 12 letters or more, split with
   at least 5 on each side, so everyday words stay whole. Anything the
   dictionary can't split - a URL, a code, or a browser without a German
   dictionary - breaks as a last resort (overflow-wrap). In text blocks
   "anywhere", which also lets a flex or grid item (a card in a swipe row,
   say) shrink below the long word instead of being pushed wider; tables
   and buttons keep the gentler break-word. The editor canvas gets the same
   through the body.
   ========================================================================== */

body {
	overflow-wrap: break-word;
	hyphens: auto;
	-webkit-hyphens: auto;
	hyphenate-limit-chars: 12 5 5;
}

:where(h1, h2, h3, h4, h5, h6, p, li, dt, dd, blockquote, figcaption) {
	overflow-wrap: anywhere;
}

/* ==========================================================================
   Blocks
   ========================================================================== */

/* A cover's colour layer sits in its own constrained layout, so core caps it
   at the content width like the cover's text - on a cover wider than that
   (a slider's slide, say) it would no longer fill it. */
.wp-block-cover > .wp-block-cover__background {
	max-width: none;
}

/* A media area the patterns leave empty - a cover with no image or video
   picked yet - shows the theme's placeholder picture where the image would
   be, under the cover's colour layer: the neutral colour as its ground and
   the mark of assets/images/placeholder.svg in the middle, drawn in the text
   colour through the file's shape (a mask), so both follow the palette. A
   tint (the tiles' or the history's, say) lies over it as it would over a
   photo. A full layer would hide it: the neutral one is left out (it only
   repeats the ground), any other colour shown at half strength - as core
   sets it once media is picked. All of it gone as soon as there is media.
   Not behind text or a logo, though: the full-screen opener, the video
   opener and the video stack keep their plain tinted ground. */
.wp-block-cover:not(.opener-cover, .opener-video, .video-stack__panel):not(:has(> .wp-block-cover__image-background, > .wp-block-cover__video-background)) {
	background-color: var(--wp--preset--color--neutral);
}

.wp-block-cover:not(.opener-cover, .opener-video, .video-stack__panel):not(:has(> .wp-block-cover__image-background, > .wp-block-cover__video-background))::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background-color: var(--wp--preset--color--contrast);
	-webkit-mask: url("assets/images/placeholder.svg") center / clamp(4rem, 25%, 8rem) no-repeat;
	mask: url("assets/images/placeholder.svg") center / clamp(4rem, 25%, 8rem) no-repeat;
	pointer-events: none;
}

.wp-block-cover:not(.opener-cover, .opener-video, .video-stack__panel):not(:has(> .wp-block-cover__image-background, > .wp-block-cover__video-background)) > .wp-block-cover__background.has-background-dim.has-neutral-background-color {
	opacity: 0;
}

.wp-block-cover:not(.opener-cover, .opener-video, .video-stack__panel):not(:has(> .wp-block-cover__image-background, > .wp-block-cover__video-background)) > .wp-block-cover__background.has-background-dim-100:not(.has-neutral-background-color) {
	opacity: 0.5;
}

/* The example logos the patterns ship (logo bar, full-screen and video
   opener): drawn in the text colour of the surface they sit on, the file
   only lending its shape (a mask) - dark on the accent logo bar, light on
   a dark cover, following every palette like the placeholder pictures.
   The file's own drawing is moved out of view. An uploaded logo keeps its
   own colours. */
.wp-block-image img[src$="/assets/images/placeholder-logo.svg"] {
	object-position: -99999px 0;
	background-color: var(--wp--custom--color--text);
	-webkit-mask: url("assets/images/placeholder-logo.svg") center / contain no-repeat;
	mask: url("assets/images/placeholder-logo.svg") center / contain no-repeat;
}

/* The placeholder picture in an image block (certificates, testimonials,
   timeline): the file has no ground of its own, the neutral colour gives it
   one, so it follows the palette like the covers above. Its mark keeps the
   file's dark colour - the dark style variations turn the picture over
   (custom.placeholder: an inverted ground under an inverting filter comes
   out as the neutral colour again, the mark light on it). */
.wp-block-image img[src$="/assets/images/placeholder.svg"] {
	background-color: var(--wp--custom--placeholder--ground);
	filter: var(--wp--custom--placeholder--filter);
}

/* TV frame (Extra Rounded variation): custom.frame draws a frame with rounded
   inner corners around the viewport. A fixed overlay paints it via box-shadow,
   so the page keeps its native scrolling. inset/radius are 0 by default,
   which makes the frame invisible - the shadow's spread follows them, so
   without a frame it is 0 too (the admin bar's height aside, which it
   hides behind). With one it reaches just past the screen's corners, no
   further: a full-page screenshot (wordpress.org's pattern and style
   previews take one with a short window) would otherwise show everything
   below the first screen covered in the frame's colour. Not in the editor
   canvas. */
body:not(.editor-styles-wrapper) {
	padding: var(--wp--custom--frame--inset);
}

body:not(.editor-styles-wrapper)::after {
	content: "";
	position: fixed;
	inset: var(--wp--custom--frame--inset);
	top: calc(var(--wp--custom--frame--inset) + var(--wp-admin--admin-bar--height, 0px));
	border-radius: var(--wp--custom--frame--radius);
	box-shadow: 0 0 0 calc(1.5 * (var(--wp--custom--frame--inset) + var(--wp--custom--frame--radius)) + var(--wp-admin--admin-bar--height, 0px)) var(--wp--custom--frame--color);
	pointer-events: none;
	z-index: 9999;
}

/* The admin bar scrolls with the page on small screens. */
@media (max-width: 600px) {
	body:not(.editor-styles-wrapper)::after {
		top: var(--wp--custom--frame--inset);
	}
}

/* Footer at the bottom on short pages: the page fills at least the visible
   area (minus frame and admin bar) and <main> takes up the free space.
   Templates without <main> simply keep the footer below the content. */
.wp-site-blocks {
	display: flex;
	flex-direction: column;
	box-sizing: border-box;
	min-height: calc(100vh - 2 * var(--wp--custom--frame--inset) - var(--wp-admin--admin-bar--height, 0px));
	min-height: calc(100dvh - 2 * var(--wp--custom--frame--inset) - var(--wp-admin--admin-bar--height, 0px));
}

.wp-site-blocks > main {
	flex-grow: 1;
}

/* Header, main and footer meet without the root block gap: the space around
   the content is main's own padding (spacing l, set in every template), the
   same on every page. */
.wp-site-blocks > main,
.wp-site-blocks > main + footer {
	margin-block-start: 0;
}

/* Content that starts or ends with a full-width section (a post band, a cover)
   meets the header or footer directly instead of leaving a white strip. On a
   page the full-width blocks sit one level down, inside the post content. */
.wp-site-blocks > main:has(> .alignfull:first-child:not(.wp-block-post-content)),
.wp-site-blocks > main:has(> .wp-block-post-content:first-child > .alignfull:first-child) {
	padding-block-start: 0 !important;
}

.wp-site-blocks > main:has(> .alignfull:last-child:not(.wp-block-post-content)),
.wp-site-blocks > main:has(> .wp-block-post-content:last-child > .alignfull:last-child) {
	padding-block-end: 0 !important;
}

/* Full-width blocks stay square in every style variation - a rounded corner
   touching the viewport edge looks broken. Sections placed directly in a
   template or template part span the full width even without .alignfull,
   and so do a few groups inside the patterns (the timeline's stage, the
   media marquee's tracks). */
.wp-block-image.alignfull img,
.wp-block-cover.alignfull,
.wp-block-group.alignfull,
.wp-site-blocks > .wp-block-group,
.wp-site-blocks > .wp-block-cover,
.wp-block-template-part > .wp-block-group,
.wp-block-template-part > .wp-block-cover,
.timeline__stage,
.media-marquee__track {
	border-radius: 0 !important;
}

/* The pattern previews (inserter, new-page dialog) drop the alignfull class -
   their frame knows no alignments - so a pattern's full-width section is
   told apart by being its outermost block there. */
.block-editor-block-preview__content-iframe .is-root-container > :is(.wp-block-group, .wp-block-cover),
.block-editor-block-preview__content-iframe .is-root-container > .wp-block-cover > .wp-block-cover__background {
	border-radius: 0 !important;
}

/* A link to a spot on the same page (a table of contents, say) glides there
   instead of jumping - unless the visitor asked for less motion - and the
   spot keeps a little room above it instead of sticking to the screen edge. */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

:target {
	scroll-margin-block-start: var(--wp--preset--spacing--m);
}

/* Bold text is bold: the browser's "bolder" only goes one step up from the
   body text - from the rounded styles' light (300) to 400, barely different
   from the text around it. */
:where(strong, b) {
	font-weight: 700;
}

/* Buttons keep their label on one line - a shrinking flex row should wrap
   the row itself, not break the text inside the button. */
.wp-element-button {
	white-space: nowrap;
}

/* The icon-only search toggle is a plain icon, not a button - strips the
   button background/padding our global button styling would otherwise add. */
.wp-block-search__button.has-icon {
	align-items: center;
	justify-content: center;
	background: transparent !important;
	color: var(--wp--custom--color--link) !important;
	border: none !important;
	padding: 0 !important;
}

.wp-block-search__button.has-icon:hover {
	background: transparent !important;
	color: var(--wp--custom--color--link-hover-accent) !important;
}

/* ==========================================================================
   Header search
   Opening the search hides the menu and the field takes its place between the
   logo and the actions. Core's search block handles open, Escape and
   click-outside itself; only the layout is ours.
   ========================================================================== */

/* The search takes the full height of the actions row, so field and icon line
   up with the contact button whatever the font size. */
.site-header-search {
	align-self: stretch;
	/* Button height without a button next to it (phones): line-height 1.6em plus
	   the 0.667em top/bottom button padding from theme.json. */
	min-height: 2.934em;
}

.site-header-search .wp-block-search__inside-wrapper {
	height: 100%;
	align-items: center;
}

.site-header-search .wp-block-search__button {
	height: 100%;
}

.site-header-row:has(.site-header-search:not(.wp-block-search__searchfield-hidden)) .wp-block-navigation {
	display: none;
}

.site-header-actions:has(.site-header-search:not(.wp-block-search__searchfield-hidden)),
.site-header-search:not(.wp-block-search__searchfield-hidden) {
	flex: 1;
	min-width: 0;
}

.site-header-search:not(.wp-block-search__searchfield-hidden) .wp-block-search__inside-wrapper {
	width: 100% !important;
	box-sizing: border-box;
	flex-direction: row-reverse;
	gap: 0.5em;
	padding: 0 0.75em;
	border: 0;
	background: color-mix(in srgb, var(--wp--custom--color--text) 8%, transparent);
}

.site-header-search:not(.wp-block-search__searchfield-hidden) .wp-block-search__input {
	flex: 1;
	width: auto;
	min-width: 0;
	align-self: stretch;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--wp--custom--color--text);
	font: inherit;
}

/* Below 1200px the header menu collapses into the hamburger. Core only does
   this below 600px, but a menu of five items next to the logo, the search
   and the contact button needs about 1200px to stay on one line. One row:
   logo left, search, contact button and hamburger right. */
@media (max-width: 1199px) {
	.site-header-row .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}

	.site-header-row .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

	.wp-block-group.site-header-row {
		flex-wrap: nowrap;
		column-gap: var(--wp--preset--spacing--s);
	}

	.site-header-row > .wp-block-site-logo {
		margin-inline-end: auto;
	}

	.site-header-row > .wp-block-navigation {
		order: 1;
	}
}

/* From 1200px up the row never wraps, and the menu is centred: its labels
   keep 2.5em apart (48px at the menu's 19-20px), a menu too long for one line
   wraps its own items onto a second, centred line, the logo and the
   actions stay in place at the sides. With the search open the menu steps
   aside and the actions take its place.

   1200-1279px: the menu fills the room between logo and actions and sits
   in its middle - the most room it can get, so it doesn't wrap early.
   From 1280px: three columns, the menu's as wide as it needs and the outer
   two sharing the rest equally, so it sits in the middle of the screen
   itself however wide the logo or the actions are, as long as there's
   room. */
@media (min-width: 1200px) {
	.wp-block-group.site-header-row {
		flex-wrap: nowrap;
	}

	.site-header-row > .wp-block-navigation {
		flex: 1 1 auto;
		justify-content: center;
		min-width: 0;
	}

	.site-header-row > .wp-block-navigation :is(.wp-block-navigation__container, .wp-block-page-list) {
		justify-content: center;
		column-gap: 2.5em;
		row-gap: 0.5em;
	}

	/* Core pads every item of a navigation with a background (the header's
	   is base, for its overlay) by 1em at each side; here the gap alone sets
	   the space between two labels, so it is exactly what it says. */
	.site-header-row > .wp-block-navigation :is(.wp-block-navigation__container, .wp-block-page-list) > li > .wp-block-navigation-item__content {
		padding-inline: 0;
	}
}

@media (min-width: 1280px) {
	.wp-block-group.site-header-row {
		display: grid;
		grid-template-columns: 1fr auto 1fr;
		align-items: center;
		column-gap: var(--wp--preset--spacing--m);
	}

	.site-header-row > .wp-block-site-logo {
		justify-self: start;
	}

	.site-header-row > .site-header-actions {
		justify-self: end;
	}

	.site-header-row > .wp-block-navigation {
		justify-self: center;
	}

	.site-header-row:has(.site-header-search:not(.wp-block-search__searchfield-hidden)) > .site-header-actions {
		grid-column: 2 / -1;
		justify-self: stretch;
	}
}

/* Phones: no contact button, and the open search takes the logo's place too -
   next to a wide logo the field would be left with next to no room. */
@media (max-width: 599px) {
	.site-header-actions .wp-block-buttons {
		display: none;
	}

	.site-header-row:has(.site-header-search:not(.wp-block-search__searchfield-hidden)) > .wp-block-site-logo {
		display: none;
	}
}

/* Focus ring drawn inside the field, so it keeps the contact button height. */
.site-header-search .wp-block-search__input:focus-visible {
	outline: none;
}

.site-header-search:not(.wp-block-search__searchfield-hidden) .wp-block-search__inside-wrapper:focus-within {
	box-shadow: inset 0 0 0 2px var(--wp--custom--color--focus);
}

/* --------------------------------------------------------------------------
   Forms
   Every form field on the site - the comment form, a search block, a
   plugin's contact or newsletter form - looks the same and follows the
   surface it sits on: the section's text and outline colours on its own
   ground, the style variation's corner radius, and the height of a button,
   so a field and its button line up. All in :where(), weightless: a plugin
   that styles its own fields keeps its look.
   -------------------------------------------------------------------------- */

/* Text fields, text areas and drop-downs. Padding a pixel under the
   button's own (0.667em), which has no border - the same height. */
:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="submit"], [type="button"], [type="reset"], [type="image"], [type="hidden"]), textarea, select),
.wp-block-search__inside-wrapper {
	border-radius: var(--wp--custom--radius);
}

:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="submit"], [type="button"], [type="reset"], [type="image"], [type="hidden"]), textarea, select) {
	box-sizing: border-box;
	max-width: 100%;
	padding: calc(0.667em - 1px) 1em;
	border: 1px solid var(--wp--custom--color--outline);
	background-color: transparent;
	color: var(--wp--custom--color--text);
	font: inherit;
	line-height: 1.6;
}

:where(textarea) {
	min-height: 8em;
	resize: vertical;
}

:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="submit"], [type="button"], [type="reset"], [type="image"], [type="hidden"]), textarea, select):hover {
	border-color: var(--wp--custom--color--outline-hover);
}

/* Focus ring flush with the field, same technique as the header search below
   - an inset box-shadow instead of the site-wide offset outline above, which
   would otherwise leave a visible gap around a rounded field. Excludes the
   header search specifically: that field already gets its ring from its
   wrapper (:focus-within, below), and this rule matching it too stacked a
   second, smaller ring just inside it. A search field anywhere else on the
   site still gets this same flush ring directly. */
:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="submit"], [type="button"], [type="reset"], [type="image"], [type="hidden"]), textarea, select):focus-visible:not(.site-header-search .wp-block-search__input) {
	outline: none;
	box-shadow: inset 0 0 0 2px var(--wp--custom--color--focus);
}

:where(input, textarea)::placeholder {
	color: var(--wp--custom--color--caption);
	opacity: 1;
}

/* A drop-down's own arrow, drawn in the text colour (two gradient halves
   of a chevron - an SVG couldn't take the colour of the surface). Its open
   list keeps readable colours: the browser draws it on its own ground. */
:where(select:not([multiple], [size])) {
	-webkit-appearance: none;
	appearance: none;
	padding-inline-end: 2.5em;
	background-image:
		linear-gradient(45deg, transparent 50%, currentColor 50%),
		linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position:
		calc(100% - 1.25em) 50%,
		calc(100% - 1.25em + 0.3em) 50%;
	background-size: 0.3em 0.3em;
	background-repeat: no-repeat;
}

[dir="rtl"] :where(select:not([multiple], [size])) {
	background-position:
		1.25em 50%,
		calc(1.25em + 0.3em) 50%;
}

:where(select) option {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
}

/* Checkboxes and radio buttons: a box in the outline colour, filled with
   the button colour when checked - its mark in the button's text colour.
   The box takes a third of the style variation's radius (square, slightly
   rounded, soft), the radio stays round. */
:where(input[type="checkbox"], input[type="radio"]) {
	-webkit-appearance: none;
	appearance: none;
	position: relative;
	flex: none;
	width: 1.1em;
	height: 1.1em;
	margin: 0;
	margin-inline-end: 0.5em;
	border: 1px solid var(--wp--custom--color--outline);
	border-radius: calc(var(--wp--custom--radius) / 3);
	background-color: transparent;
	vertical-align: -0.15em;
	cursor: pointer;
}

:where(input[type="radio"]) {
	border-radius: 50%;
}

:where(input[type="checkbox"], input[type="radio"]):hover {
	border-color: var(--wp--custom--color--outline-hover);
}

:where(input[type="checkbox"], input[type="radio"]):checked {
	border-color: var(--wp--custom--color--button-background);
	background-color: var(--wp--custom--color--button-background);
}

:where(input[type="checkbox"]):checked::before {
	content: "";
	position: absolute;
	inset: 0;
	background-color: var(--wp--custom--color--button-text);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M6.4 11.2 3.2 8l-1.2 1.2L6.4 13.6 14 6l-1.2-1.2z'/%3E%3C/svg%3E") center / 80% no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M6.4 11.2 3.2 8l-1.2 1.2L6.4 13.6 14 6l-1.2-1.2z'/%3E%3C/svg%3E") center / 80% no-repeat;
}

:where(input[type="radio"]):checked {
	box-shadow: inset 0 0 0 0.25em var(--wp--custom--color--button-text);
}

:where(input[type="checkbox"], input[type="radio"]):focus-visible {
	outline: 2px solid var(--wp--custom--color--focus);
	outline-offset: 2px;
}

/* Sliders, progress bars and meters keep their native shape, in the button
   colour. */
:where(input[type="range"], progress, meter) {
	accent-color: var(--wp--custom--color--button-background);
}

/* Submit buttons of a form - a plugin's plain <button> or <input> - look
   like the theme's buttons (theme.json, elements.button). A button with a
   class of its own (the search block's, the comment form's) keeps its
   styles; this only fills in what nothing else set. The file field's own
   button follows along. */
:where(form) :where(button[type="submit"], button:not([type]), input[type="submit"], input[type="button"], input[type="reset"]),
:where(input[type="file"])::file-selector-button {
	padding: 0.667em 1.333em;
	border: 0;
	border-radius: var(--wp--custom--radius);
	background-color: var(--wp--custom--color--button-background);
	color: var(--wp--custom--color--button-text);
	font: inherit;
	font-weight: 700;
	line-height: 1.6;
	cursor: pointer;
}

:where(form) :where(button[type="submit"], button:not([type]), input[type="submit"], input[type="button"], input[type="reset"]):hover,
:where(input[type="file"])::file-selector-button:hover {
	background-color: var(--wp--custom--color--button-hover-background);
	color: var(--wp--custom--color--button-hover-text);
}

:where(input[type="file"]) {
	max-width: 100%;
	color: var(--wp--custom--color--text);
	font: inherit;
}

:where(input[type="file"])::file-selector-button {
	margin-inline-end: 1em;
}

/* States: a field the visitor has left wrong gets the error colour (only
   after they touched it - :user-invalid - not on an untouched form), a
   disabled one fades like a disabled button. */
:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="submit"], [type="button"], [type="reset"], [type="image"], [type="hidden"]), textarea, select):user-invalid,
:where(input[type="checkbox"], input[type="radio"]):user-invalid {
	border-color: var(--wp--preset--color--error);
}

:where(input, textarea, select, button):disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

/* Labels and groups. */
:where(form label) {
	cursor: pointer;
}

:where(fieldset) {
	margin: 0;
	padding: var(--wp--preset--spacing--s);
	border: 1px solid var(--wp--custom--color--outline);
	border-radius: var(--wp--custom--radius);
}

:where(legend) {
	padding-inline: 0.5em;
	font-weight: 700;
}

/* Chromium and Safari draw their own clear-"x" with a gradient in search
   fields; it clashes with the theme and only empties the field. */
.wp-block-search__input::-webkit-search-cancel-button,
.wp-block-search__input::-webkit-search-decoration {
	-webkit-appearance: none;
	appearance: none;
	display: none;
}

/* Site Logo: at its default size a capped height and a flexible width. A
   width set on the block reaches the image only as its width attribute
   (core), so no width here for a resized logo - it keeps the size chosen. */
.wp-block-site-logo img {
	height: auto;
}

.wp-block-site-logo.is-default-size img {
	max-height: 60px;
	width: auto;
}

/* In the headers and the footers at most 50px tall by default, its width
   following the logo's proportions (core's default size would be 120px
   wide, whatever the height). A width set on the block (a resized logo,
   core drops is-default-size then) wins: the logo takes that width and
   its own height, uncapped. Either way a logo too wide for its row (a
   wide logo next to the menu button on a phone) shrinks as a whole
   instead of pushing the page wider. */
:is(header, .site-footer) .wp-block-site-logo,
:is(header, .site-footer) .wp-block-site-logo a {
	min-width: 0;
	max-width: 100%;
}

:is(header, .site-footer) .wp-block-site-logo img {
	max-width: 100%;
	height: auto;
}

:is(header, .site-footer) .wp-block-site-logo.is-default-size img {
	width: auto;
	max-height: 50px;
}

:is(header, .site-footer) .wp-block-site-logo:not(.is-default-size) img {
	max-height: none;
}

/* ==========================================================================
   Mobile menu
   The header navigation opens parts/navigation-overlay.html (the navigation
   overlay template part area needs WordPress 7.0). The template part's
   blocks carry colours and spacing - these rules only stretch it to the full
   height and give the menu its list look.
   ========================================================================== */

/* The overlay fills the TV frame's opening. It reaches 1px under the frame,
   so no page edge shows through the anti-aliased corners. */
.wp-block-navigation__responsive-container.disable-default-overlay.is-menu-open {
	inset: calc(var(--wp--custom--frame--inset) - 1px);
	top: calc(var(--wp--custom--frame--inset) - 1px + var(--wp-admin--admin-bar--height, 0px));
	border-radius: calc(var(--wp--custom--frame--radius) + 1px);
}

/* The admin bar scrolls with the page on small screens. */
@media (max-width: 600px) {
	.wp-block-navigation__responsive-container.disable-default-overlay.is-menu-open {
		top: calc(var(--wp--custom--frame--inset) - 1px);
	}
}

/* Stretch core's wrappers so the template part fills the overlay and its
   button sits at the bottom. */
.disable-default-overlay.is-menu-open :is(.wp-block-navigation__responsive-close, .wp-block-navigation__responsive-dialog, .wp-block-navigation__responsive-container-content) {
	display: flex;
	flex-direction: column;
	flex-grow: 1;
}

.disable-default-overlay.is-menu-open .wp-block-navigation__overlay-container {
	flex-grow: 1;
}

/* The close button follows the link colours like the hamburger does. */
.wp-block-navigation-overlay-close {
	color: var(--wp--custom--color--link);
}

.wp-block-navigation-overlay-close:hover {
	color: var(--wp--custom--color--link-hover-accent);
}

/* Main items as a full-width list with hairlines between them. */
.site-overlay-menu .wp-block-navigation__container {
	align-self: stretch;
	align-items: stretch;
	gap: 0;
}

/* The header navigation has a background, so core pads every link inside it -
   including this nested menu. */
.site-overlay-menu .wp-block-navigation-item a.wp-block-navigation-item__content {
	padding: 0;
}

/* Submenus are always open here, the toggle has nothing to do. */
.site-overlay-menu .wp-block-navigation-submenu__toggle {
	display: none;
}

.site-overlay-menu .wp-block-navigation__container > .wp-block-navigation-item.wp-block-navigation-item {
	padding: 0.5em 0;
	border-bottom: 1px solid color-mix(in srgb, var(--wp--custom--color--text) 15%, transparent);
}

/* Submenus listed below their parent, smaller and indented, grouped by an
   accent bar. */
.site-overlay-menu .has-child.open-always.wp-block-navigation-submenu {
	gap: 0;
}

.site-overlay-menu .has-child.open-always .wp-block-navigation__submenu-container {
	gap: 0.25em;
	margin-top: 0.75em;
	padding: 0;
	padding-inline-start: 1em;
	border-inline-start: 2px solid var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--medium);
}

/* ==========================================================================
   Pattern layouts
   What the pattern sections below share.

   Each switches from stacked to side by side at 782px of the width it is
   actually rendered at - a container query on the pattern's parent (the
   plain outer group), not a viewport media query: the editor canvas is
   rarely as wide as the browser window, and a media query would go on
   reading that as desktop-wide and show the row layout there regardless.
   The parent, not the pattern block itself, because a block can't query
   its own size for a property that changes it.

   Media and boxes (.bleed in the patterns) keep the page margin on a phone
   in every style variation, their corners following its radius (0 when
   square). Only swipe rows (key figures, history) run to the screen edge
   there, by rules of their own; from 782px up they get a normal width back
   (auto for a wide block, which core centres that way). !important,
   because core centres wide blocks with an !important auto margin.

   A coloured box - .section-box, its colour a section style of its own - in
   the same colour as the section around it would vanish into it, so it
   turns white instead (its text switches back in Colour schemes).

   A section head - pill, headline, intro, a button - is centred on a
   desktop (.section-head, a constrained group) and left-aligned on a phone,
   like the content below it there. !important against the constrained
   layout's auto margins, which centre the pill.
   ========================================================================== */

:has(> :is(.opener, .opener-centered__media, .opener-tabs, .marquee, .text-media, .testimonials, .media-grid, .slider, .key-figures, .tiles, .cta-box, .timeline__body, .timeline__steps--alternate, .statement, .staggered, .zigzag, .events, .pricing, .price-tiers, .certificates, .logo-bar, .steps, .faq)),
:has(> .section-head) {
	container-type: inline-size;
}

.wp-block-cover.bleed,
.wp-block-cover.bleed > .wp-block-cover__background {
	border-radius: var(--wp--custom--radius);
}

:is(.is-style-section-neutral, .has-neutral-background-color) .section-box.is-style-section-neutral,
:is(.is-style-section-primary, .has-primary-background-color) .section-box.is-style-section-primary,
:is(.is-style-section-accent, .has-accent-background-color) .section-box.is-style-section-accent,
.has-contrast-background-color .section-box.is-style-section-contrast {
	background-color: var(--wp--preset--color--base);
}

@container (min-width: 782px) {
	:is(.wp-block-group, .wp-block-cover).bleed {
		margin-inline: 0 !important;
	}

	.alignwide.bleed {
		margin-inline: auto !important;
	}
}

@container (max-width: 781px) {
	.section-head > .has-text-align-center {
		text-align: start;
	}

	/* Every child, not just the pill: in a flex column (the scroll fill's
	   stage) a short paragraph shrinks to its text and the auto margins
	   centre it too. */
	.section-head > * {
		margin-inline-start: 0 !important;
	}

	.section-head > .wp-block-buttons {
		justify-content: flex-start;
	}

	.section-head > .scroll-fill__hint::before {
		margin-inline: 0;
	}

	/* Boxes and cards take half their side padding on a phone (s, not the m
	   or l the patterns give them): inside the page margin a full one left
	   their text a column of a few words a line. */
	.wp-block-group:is(.compare__box, .pricing__card, .price-tiers__card, .tiles__text, .testimonials__card, .key-figures__box, .cta-box__content, .opener-tabs__box, .legal-toc) {
		padding-inline: var(--wp--preset--spacing--s) !important;
	}

	/* Except where the text stands alone on a full screen - the video
	   stack's panels and the scroll fill's stage: centred there on a phone
	   too. */
	:is(.video-stack__panel .section-head, .scroll-fill__stage.section-head) > .has-text-align-center {
		text-align: center;
	}

	:is(.video-stack__panel .section-head, .scroll-fill__stage.section-head) > * {
		margin-inline: auto !important;
	}

	:is(.video-stack__panel .section-head, .scroll-fill__stage.section-head) > .wp-block-buttons {
		justify-content: center;
	}

	.scroll-fill__stage.section-head > .scroll-fill__hint::before {
		margin-inline: auto;
	}
}

/* ==========================================================================
   Opener
   The split opener pattern (patterns/opener-split.php): text on one side,
   two covers on the other. Stacked with the covers full width below 782px
   container width; a 50/50 row with the covers offset from there up.
   ========================================================================== */

.opener {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--m);
}

.opener__content,
.opener__media {
	flex: 1 1 0;
	min-width: 0;
}

/* A grid, not flex: two equal tracks size both covers alike regardless of
   their own aspect-ratio, which flex's basis/grow alone does not guarantee.
   The same thin 0.5em seam between the two as between the media grid's
   tiles on a phone. */
.opener__media {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0.5em;
}

.opener__media-item {
	aspect-ratio: 3 / 4;
}

.opener__media-item,
.opener__media-item .wp-block-cover__background {
	border-radius: var(--wp--custom--radius);
}

@container (min-width: 782px) {
	.opener {
		flex-direction: row;
		align-items: center;
	}

	/* A fixed box the two covers can be placed and overlapped inside. */
	.opener__media {
		display: block;
		/* !important: the editor forces every block wrapper (including
		   these two covers) to position: relative for its own selection
		   UI, at a specificity/layer plain CSS can't out-rank - confirmed
		   by testing, the exact rule doesn't show up in an inspection of
		   its own stylesheets. Without it, the covers stay in normal flow
		   here (stacked) instead of overlapping. */
		position: relative !important;
		aspect-ratio: 4 / 5;
	}

	.opener__media-item {
		position: absolute !important;
		aspect-ratio: 3 / 4;
		overflow: hidden;
	}

	.opener__media-item--primary {
		inset-block-start: 0;
		inset-inline-end: 0;
		width: 76%;
	}

	.opener__media-item--secondary {
		inset-block-end: 0;
		inset-inline-start: 0;
		width: 48%;
	}
}

/* ==========================================================================
   Centered opener
   The opener-centered pattern (patterns/opener-centered.php): a centred head
   over a wide cover, 4:3 on a phone and 21:9 from 782px container width up.
   ========================================================================== */

.wp-block-cover.opener-centered__media {
	min-height: 0;
	aspect-ratio: 4 / 3;
}

@container (min-width: 782px) {
	.wp-block-cover.opener-centered__media {
		aspect-ratio: 21 / 9;
	}
}

/* ==========================================================================
   Full-screen opener
   The opener-cover pattern (patterns/opener-cover.php): a cover filling the
   screen below the admin bar and the site header (its height measured by
   assets/js/opener-cover.js; a full screen without it), its content a
   column from top to bottom - the text at the top, the logos at the bottom
   edge. The text takes the left half from 782px container width up, the
   right stays free for the picture. The cover's own 1em side padding becomes the page
   margin (m), so the text lines up with every other section's. The logos
   are for wider screens only: below 782px the row is hidden and the text
   has the whole cover to itself.
   ========================================================================== */

.wp-block-cover.opener-cover {
	align-items: stretch;
	min-height: calc(100svh - var(--wp-admin--admin-bar--height, 0px) - var(--digistarter-header-height, 0px));
	padding-inline: var(--wp--preset--spacing--m);
	background-color: var(--wp--custom--cover-tint);
}

.opener-cover > .wp-block-cover__inner-container {
	display: flex;
	flex-direction: column;
}

.wp-block-group.opener-cover__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: var(--wp--preset--spacing--l);
	justify-content: space-between;
	width: 100%;
}

.wp-block-group.opener-cover__body > * {
	margin-block: 0;
}

@container (min-width: 782px) {
	.opener-cover__content {
		max-width: 50%;
	}
}

/* On a phone the text sits in the middle of the cover, the same space above
   and below it - the auto margins share out what is left. */
@container (max-width: 781px) {
	.wp-block-group.opener-cover__body > .opener-cover__content {
		margin-block: auto;
	}

	.opener-cover .wp-block-group.logo-bar.logo-bar--row {
		display: none;
	}
}

/* ==========================================================================
   Video opener
   The opener-video pattern (patterns/opener-video.php): a cover as tall as
   the full-screen opener - the screen below the site header - with a logo
   exactly in its middle (the cover centres its content). Its ground before
   a video is picked: the cover tint, like the full-screen opener's. The logo
   keeps its own shape (no radius), never grows wider than the page and
   fades out as the cover scrolls away.
   ========================================================================== */

.wp-block-cover.opener-video {
	min-height: calc(100svh - var(--wp-admin--admin-bar--height, 0px) - var(--digistarter-header-height, 0px));
	padding-inline: var(--wp--preset--spacing--m);
	background-color: var(--wp--custom--cover-tint);
}

/* In the editor and the pattern previews the screen height is no measure:
   a preview is only as tall as its content, and the cover would shrink to a
   strip around the logo. A 16:9 frame there reads as the full screen it is. */
.editor-styles-wrapper .wp-block-cover.opener-video {
	min-height: max(calc(100svh - var(--wp-admin--admin-bar--height, 0px) - var(--digistarter-header-height, 0px)), 56.25vw);
}

.opener-video .opener-video__logo {
	margin-block: 0;
	/* Fades out while visitors scroll (assets/js/opener-cover.js sets
	   --opener-fade from 0 to 1); fully visible without the script. */
	opacity: calc(1 - var(--opener-fade, 0));
}

.opener-video .opener-video__logo img {
	max-width: 100%;
	border-radius: 0;
}

/* ==========================================================================
   Opener with tabs
   The opener-tabs pattern (patterns/opener-tabs.php): a full-width cover
   with a text box of tabs on top of it. From 782px container width up both
   share one grid cell, the box on the left edge of the wide width, half of
   it wide - a third once there is room (50/50, then 33/33/33), the cover as
   tall as the box plus l above and below. Below that the cover comes first,
   4:3 and full width, the box under it.
   ========================================================================== */

/* minmax(0, 1fr): a tab row too long for the box swipes (Tabs, below)
   instead of widening the grid's one column past the screen. */
.wp-block-group.opener-tabs {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
}

/* The box is white on Standard. A style picked for the whole section
   colours only the box (the text follows in Colour schemes); the section
   itself keeps no colour or padding of its own, so the cover still runs edge
   to edge. */
.opener-tabs__box {
	background-color: var(--wp--preset--color--base);
	border-radius: 0;
}

.wp-block-group.opener-tabs[class*="is-style-section-"] {
	padding: 0;
	background: none;
}

.opener-tabs.is-style-section-neutral > .opener-tabs__box {
	background-color: var(--wp--preset--color--neutral);
}

.opener-tabs.is-style-section-primary > .opener-tabs__box {
	background-color: var(--wp--preset--color--primary);
}

.opener-tabs.is-style-section-accent > .opener-tabs__box {
	background-color: var(--wp--preset--color--accent);
}

.wp-block-cover.opener-tabs__media {
	min-height: 0;
	aspect-ratio: 4 / 3;
}

.wp-block-cover.opener-tabs__media,
.opener-tabs__media .wp-block-cover__background {
	border-radius: 0;
}

/* On a phone the cover and the box below it read as one card inside the
   page margin, rounded at the card's outer corners only. */
@container (max-width: 781px) {
	.wp-block-group.opener-tabs,
	.wp-block-group.opener-tabs[class*="is-style-section-"] {
		padding: var(--wp--preset--spacing--m);
	}

	.wp-block-cover.opener-tabs__media,
	.opener-tabs__media .wp-block-cover__background {
		border-radius: var(--wp--custom--radius) var(--wp--custom--radius) 0 0;
	}

	.opener-tabs > .opener-tabs__box {
		border-radius: 0 0 var(--wp--custom--radius) var(--wp--custom--radius);
	}
}

@container (min-width: 782px) {
	.wp-block-group.opener-tabs > * {
		grid-area: 1 / 1;
	}

	.wp-block-cover.opener-tabs__media {
		aspect-ratio: auto;
	}

	.opener-tabs > .opener-tabs__box {
		--opener-tabs-wide: min(100% - 2 * var(--wp--preset--spacing--m), var(--wp--style--global--wide-size));
		/* Above the cover's overlay and content, which core stacks at 1. */
		position: relative;
		z-index: 2;
		justify-self: start;
		width: calc((var(--opener-tabs-wide) - var(--wp--preset--spacing--m)) / 2);
		margin-block: var(--wp--preset--spacing--l);
		margin-inline-start: calc((100% - var(--opener-tabs-wide)) / 2);
		border-radius: var(--wp--custom--radius);
	}
}

@container (min-width: 1200px) {
	.opener-tabs > .opener-tabs__box {
		width: calc((var(--opener-tabs-wide) - 2 * var(--wp--preset--spacing--m)) / 3);
	}
}

/* ==========================================================================
   Marquee
   The marquee-words pattern (patterns/marquee-words.php): a row of words,
   evenly spread below spacing l wide; endlessly scrolling once there is not
   room for that. assets/js/marquee.js wraps .marquee__track in a rail and
   appends a second, aria-hidden copy of the track to it - the rail is what
   actually scrolls (.marquee only clips it), and translating it by exactly
   one copy's width (-50%, the rail is exactly two copies wide) loops it with
   no visible seam. Without that script, .marquee__track sits in .marquee
   directly and reads fine as a plain (wrapping, if it must) static row - the
   same one this switches back to from container width 782px up.
   ========================================================================== */

.marquee {
	overflow: hidden;
}

.marquee__track,
.marquee__track--clone {
	display: flex;
	flex-wrap: nowrap;
	gap: var(--wp--preset--spacing--m);
	margin-block-start: 0;
}

/* The words in the heading colour - except on a dark surface, where they
   take the accent, the pattern's intended look (it starts on Primary). The
   accent on a light or accent surface is unreadable, so the scheme's roles
   decide, not the words themselves; a colour picked on a word still wins,
   being inline. */
.marquee__track :where(h1, h2, h3, h4, h5, h6) {
	margin: 0;
	color: var(--wp--custom--color--heading);
	white-space: nowrap;
}

:is(.is-style-section-primary, .has-primary-background-color, .has-contrast-background-color) .marquee__track :where(h1, h2, h3, h4, h5, h6) {
	color: var(--wp--custom--color--link-hover-accent);
}

.marquee__rail {
	display: flex;
	flex-wrap: nowrap;
	gap: var(--wp--preset--spacing--m);
	width: max-content;
	animation: digistarter-marquee 24s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
	.marquee__rail {
		animation-play-state: paused;
	}
}

@container (min-width: 782px) {
	.marquee__rail {
		width: 100%;
		animation: none;
	}

	.marquee__track {
		width: 100%;
	}

	.marquee__rail .marquee__track--clone {
		display: none;
	}
}

@keyframes digistarter-marquee {
	to {
		transform: translateX(-50%);
	}
}

/* Right-to-left: the rail overflows to the left, so it travels the other
   way (the media marquee's reversed row still reverses this). */
[dir="rtl"] :is(.marquee__rail, .media-marquee__rail, .logo-bar__rail) {
	animation-name: digistarter-marquee-rtl;
}

@keyframes digistarter-marquee-rtl {
	to {
		transform: translateX(50%);
	}
}

/* ==========================================================================
   Media marquee
   The media-marquee pattern (patterns/media-marquee.php): two rows of
   covers, edge to edge, looped by the same assets/js/marquee.js rail as
   above - on every screen size here, the top row running left, the bottom
   one (--reverse) right. Hovering pauses both. Without the script, and in
   the editor, each row is a plain strip; the editor's scrolls, so every
   item stays reachable.
   ========================================================================== */

.wp-block-group.media-marquee {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--s);
	overflow: hidden;
}

/* The space after the last item is the track's own padding, not a gap on
   the rail: the rail is then exactly two tracks wide, and -50% one track. */
.media-marquee__track,
.media-marquee__rail {
	display: flex;
	flex-wrap: nowrap;
}

.media-marquee__track {
	gap: var(--wp--preset--spacing--s);
	padding-inline-end: var(--wp--preset--spacing--s);
}

.media-marquee__rail {
	width: max-content;
	animation: digistarter-marquee 60s linear infinite;
}

.media-marquee__rail:has(> .media-marquee__track--reverse) {
	animation-direction: reverse;
}

.media-marquee:hover .media-marquee__rail {
	animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
	.media-marquee__rail {
		animation-play-state: paused;
	}
}

.wp-block-cover.media-marquee__item {
	flex: none;
	width: clamp(240px, 30vw, 480px);
	min-height: 0;
	aspect-ratio: 16 / 10;
}

.wp-block-cover.media-marquee__item,
.media-marquee__item .wp-block-cover__background {
	border-radius: var(--wp--custom--radius);
}

.wp-block-group.media-marquee__track.block-editor-block-list__layout {
	overflow-x: auto;
	scrollbar-width: thin;
}

/* ==========================================================================
   Sliding statement
   The slide-in pattern (patterns/slide-in.php): a statement in capitals,
   centred, a paragraph per line. assets/js/slide-in.js sets
   --slide-in from 0 (the statement around the middle of the screen) to 1
   (entering at the bottom, leaving at the top); the lines slide out by that
   share of the screen width - odd ones to the left, even ones to the
   right - and fade. The section clips them, so the page never scrolls
   sideways. Without the script (and in the editor) they stand still.
   ========================================================================== */

.wp-block-group:has(> .slide-in) {
	overflow-x: clip;
}

.slide-in__line {
	margin: 0;
	color: var(--wp--custom--color--heading);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 700;
	line-height: 1;
	text-align: center;
	text-transform: uppercase;
}

/* The first line as large as a section headline (h2), the ones after it
   as large as an h3. */
.slide-in__line:first-child {
	font-size: var(--wp--preset--font-size--x-large);
}

.slide-in.is-ready .slide-in__line {
	opacity: calc(1 - var(--slide-in, 0));
	will-change: transform, opacity;
}

.slide-in.is-ready .slide-in__line:nth-child(odd) {
	transform: translateX(calc(var(--slide-in, 0) * -100vw));
}

.slide-in.is-ready .slide-in__line:nth-child(even) {
	transform: translateX(calc(var(--slide-in, 0) * 100vw));
}

/* ==========================================================================
   Scroll fill
   The scroll-fill pattern (patterns/scroll-fill.php): a statement on a
   stage exactly one screen tall. Once assets/js/scroll-fill.js has wrapped
   its letters (.is-ready), the section grows to 2.5 screens and the stage
   stays pinned while the letters fill in, faded until then; the last screen
   of it releases the stage and the page scrolls on. Without the script -
   and in the editor - the text shows in full on a one-screen stage.
   ========================================================================== */

.scroll-fill__stage {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: var(--wp--preset--spacing--l);
	min-height: 100svh;
}

.wp-block-group.scroll-fill__stage > * {
	margin-block: 0;
}

.scroll-fill.is-ready {
	height: 250svh;
}

.scroll-fill.is-ready .scroll-fill__stage {
	position: sticky;
	inset-block-start: 0;
}

.scroll-fill.is-ready .scroll-fill__text span {
	color: color-mix(in srgb, currentColor 25%, transparent);
	transition: color 0.2s;
}

.scroll-fill.is-ready .scroll-fill__text span.is-filled {
	color: inherit;
}

@media (prefers-reduced-motion: reduce) {
	.scroll-fill.is-ready .scroll-fill__text span {
		transition: none;
	}
}

/* "Scroll" under a thin line, pointing down to what follows. */
.scroll-fill__hint {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: 0.15em;
	text-transform: uppercase;
}

.scroll-fill__hint::before {
	content: "";
	display: block;
	width: 1px;
	height: 3em;
	margin: 0 auto 1em;
	background-color: currentColor;
}

/* ==========================================================================
   Text with media
   The text-media pattern (patterns/text-media.php): a cover (image or video)
   beside a paragraph, a checklist and two buttons. Stacked, image first,
   below 782px container width; side by side from there up.
   ========================================================================== */

.text-media {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--m);
}

.text-media__image {
	aspect-ratio: 4 / 5;
}

.text-media__content {
	flex: 1 1 0;
	min-width: 0;
}

.text-media__content .wp-block-buttons {
	gap: 0.5em;
}

@container (min-width: 782px) {
	.text-media {
		flex-direction: row;
		align-items: center;
	}

	/* 50/50 - one of the theme's column splits (100, 75/25, 25/75, 50/50,
	   33/33/33, 25/25/25/25). */
	.text-media__image {
		flex: 1 1 0;
	}
}

/* ==========================================================================
   Testimonials
   The testimonials pattern (patterns/testimonials.php): a headline and a
   button beside two quote cards. Stacked below 782px container width; from
   there up side by side, the first card set lower than the second.
   ========================================================================== */

.testimonials,
.testimonials__cards {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--m);
}

@container (min-width: 782px) {
	/* 33/33/33 - one of the theme's column splits: the intro takes exactly
	   one of three equal columns (width minus both gaps, by three), the two
	   cards share the rest with the same gap between them. */
	.testimonials {
		display: grid;
		grid-template-columns: calc((100% - 2 * var(--wp--preset--spacing--m)) / 3) minmax(0, 1fr);
		align-items: center;
	}

	.testimonials__cards {
		flex-direction: row;
		align-items: flex-start;
	}

	.testimonials__card {
		flex: 1 1 0;
	}

	.testimonials__cards > .testimonials__card:first-child {
		margin-block-start: var(--wp--preset--spacing--l);
	}
}

/* ==========================================================================
   Media grid
   The media-grid pattern (patterns/media-grid.php): one large cover and
   four small ones, all square. From 782px container width up: 50/50, the
   right half a 2x2 grid of the small ones - the large one spans two columns
   and two rows, so it's exactly as tall as both rows plus the gap between
   them. Below that: full width, the large one on its own row, the small
   ones 50/50 two by two.
   ========================================================================== */

.wp-block-group.media-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	/* A thin seam between the tiles, like puzzle pieces - finer than the
	   spacing scale's smallest step (s), which reads too heavy between tiles
	   this small; the same 0.5em as the theme's other fine gaps. */
	gap: 0.5em;
}

.media-grid__item {
	aspect-ratio: 1;
}

.media-grid__item,
.media-grid__item .wp-block-cover__background {
	border-radius: var(--wp--custom--radius);
}

.media-grid__item--large {
	grid-column: span 2;
}

@container (min-width: 782px) {
	.wp-block-group.media-grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: var(--wp--preset--spacing--s);
	}

	.media-grid__item--large {
		grid-row: span 2;
	}
}

/* ==========================================================================
   Video stack
   The video-stack pattern (patterns/video-stack.php): covers one screen
   tall, each pinned to the top of the screen (below the admin bar, when
   there is one) so the next slides over it; the last one scrolls away
   with the page. The browser does it all - no script.
   ========================================================================== */

/* An opaque ground under the overlay: without a picture the overlay alone
   is see-through, and the panel below - text and all - would show through
   the one sliding over it. */
.wp-block-cover.video-stack__panel {
	background-color: var(--wp--preset--color--base);
	position: sticky;
	inset-block-start: var(--wp-admin--admin-bar--height, 0px);
	min-height: calc(100svh - var(--wp-admin--admin-bar--height, 0px));
	/* The root padding's m at the sides, not core's 1em cover padding, so
	   the text lines up with every other section's on a phone. */
	padding-inline: var(--wp--preset--spacing--m);
	border-radius: 0;
}

.wp-block-cover.video-stack__panel:last-child {
	position: relative;
}

/* ==========================================================================
   Media slider
   The media-slider pattern (patterns/media-slider.php): covers in a track
   that scrolls and snaps one slide at a time, any number of them. The arrows
   and dots are added by assets/js/slider.js. Below 782px full width like
   the other patterns' media, swiped rather than clicked (no arrows).
   ========================================================================== */

.wp-block-group.slider {
	position: relative;
}

.wp-block-group.slider__track {
	display: flex;
	gap: 0.5em;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
}

.wp-block-group.slider__track::-webkit-scrollbar {
	display: none;
}

.slider__slide {
	flex: 0 0 100%;
	scroll-snap-align: start;
}

.slider__slide,
.slider__slide .wp-block-cover__background {
	border-radius: var(--wp--custom--radius);
}

/* In the editor (the track is its block list there) the scrollbar stays, as
   the only hint - there are no arrows or dots - that more slides follow. */
.wp-block-group.slider__track.block-editor-block-list__layout {
	scrollbar-width: thin;
}

.slider__arrow {
	display: none;
	position: absolute;
	inset-block-start: 50%;
	width: 2.5em;
	height: 2.5em;
	padding: 0;
	border: 0;
	border-radius: var(--wp--custom--radius);
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
	translate: 0 -50%;
}

/* A chevron: two borders of a small square, turned. */
.slider__arrow::before {
	content: "";
	display: block;
	width: 0.5em;
	height: 0.5em;
	border-block-start: 2px solid;
	border-inline-start: 2px solid;
	rotate: -45deg;
	translate: 0.1em 0;
}

.slider__arrow--prev {
	inset-inline-start: var(--wp--preset--spacing--s);
}

.slider__arrow--next {
	inset-inline-end: var(--wp--preset--spacing--s);
}

.slider__arrow--next::before {
	rotate: 135deg;
	translate: -0.1em 0;
}

.wp-block-group > .slider__dots {
	display: flex;
	justify-content: center;
	gap: 0.5em;
	margin-block-start: var(--wp--preset--spacing--s);
}

.slider__dot {
	width: 0.5em;
	height: 0.5em;
	padding: 0;
	border: 0;
	border-radius: calc(var(--wp--custom--radius) / 3);
	/* A button's colour is the browser's black, not the section's - inherit,
	   so the dots follow the colour scheme; 40%, not the 25% of the other
	   faded marks: at 0.5em a dot needs more to still show. */
	color: inherit;
	background-color: color-mix(in srgb, currentColor 40%, transparent);
	cursor: pointer;
}

.slider__dot[aria-current] {
	background-color: var(--wp--custom--color--link-hover-accent);
}

@container (min-width: 782px) {
	.slider__arrow {
		display: grid;
		place-items: center;
	}
}

/* ==========================================================================
   Key figures
   The key-figures pattern (patterns/key-figures.php): four coloured boxes.
   From 782px container width up a 25/25/25/25 row, the boxes flush against
   each other and only the row's outer corners rounded. Below that a row of
   index cards to swipe sideways: to the screen edge (unlike the other
   patterns' media), the next card peeking in, each snapping to the content's edge.
   ========================================================================== */

.wp-block-group.key-figures {
	display: flex;
	gap: 0.5em;
	padding-inline: var(--wp--preset--spacing--m);
	scroll-padding-inline: var(--wp--preset--spacing--m);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
}

.wp-block-group.key-figures::-webkit-scrollbar {
	display: none;
}

.key-figures__box {
	/* As wide as the content column: the next card peeks in at the right
	   edge, in the root padding the row bleeds into. */
	flex: 0 0 100%;
	scroll-snap-align: start;
	border-radius: var(--wp--custom--radius);
}

/* A swipe row runs to the screen edge in every style variation - its cards
   are rounded and inset by its own padding already. */
@container (max-width: 781px) {
	.wp-block-group.key-figures.bleed {
		margin-inline: calc(-1 * var(--wp--preset--spacing--m)) !important;
	}
}

@container (min-width: 782px) {
	.wp-block-group.key-figures {
		display: grid;
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: 0;
		padding-inline: 0;
		overflow: hidden;
		border-radius: var(--wp--custom--radius);
	}

	/* Weighted up: in the editor a group's own radius (theme.json) comes
	   later and would win against a single class. */
	.wp-block-group.key-figures > .wp-block-group.key-figures__box {
		border-radius: 0;
	}
}

/* ==========================================================================
   Tiles
   The tiles pattern (patterns/tiles.php): text tiles and covers taking
   turns. From 782px container width up a 33/33/33 grid of squares - two
   rows, a checkerboard of text and media. Below that one below the other,
   full width and with no gap, so text and media read as one block.
   ========================================================================== */

.wp-block-group.tiles {
	display: grid;
	gap: 0;
	overflow: hidden;
	border-radius: var(--wp--custom--radius);
}

/* One block on a phone, rounded as a whole (above): no corners of their
   own where text and media meet. Weighted up for the editor, where a
   cover's own radius (theme.json) comes later. */
.wp-block-group.tiles > .tiles__text,
.wp-block-group.tiles > .wp-block-cover.tiles__media,
.wp-block-group.tiles > .tiles__media > .wp-block-cover__background {
	border-radius: 0;
}

@container (min-width: 782px) {
	.wp-block-group.tiles {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: var(--wp--preset--spacing--s);
	}

	.wp-block-group.tiles > .tiles__text {
		aspect-ratio: 1;
		border-radius: var(--wp--custom--radius);
	}

	/* A text tile two columns wide - the pattern's last tile before 1.2.3,
	   kept for pages built with it. */
	.wp-block-group.tiles > .tiles__text--wide {
		grid-column: span 2;
		aspect-ratio: auto;
	}

	/* Squares as long as the text fits; should a text tile grow taller on
	   a narrower screen (a tablet), the whole row grows with it, media
	   included. Stretched sideways too: a square tile would otherwise take
	   its width from the taller row and grow out of its column, over the
	   tile next to it. */
	.wp-block-group.tiles > * {
		align-self: stretch;
		justify-self: stretch;
	}

	.wp-block-group.tiles > .wp-block-cover.tiles__media,
	.wp-block-group.tiles > .tiles__media > .wp-block-cover__background {
		border-radius: var(--wp--custom--radius);
	}
}

/* ==========================================================================
   Call to action with media
   The cta-media pattern (patterns/cta-media.php): a coloured box, its text
   on the left and a cover on the right - 50/50 from 782px container width
   up, the cover filling its half from top to bottom, the text centred.
   Below that the box runs full width, the cover full width above the
   text.
   ========================================================================== */

.wp-block-group.cta-box {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border-radius: var(--wp--custom--radius);
}

/* On a phone the media comes first, the text below it. */
.wp-block-cover.cta-box__media {
	order: -1;
	min-height: 0;
	aspect-ratio: 4 / 3;
}

.wp-block-cover.cta-box__media,
.cta-box__media .wp-block-cover__background {
	border-radius: 0;
}

@container (min-width: 782px) {
	.wp-block-group.cta-box {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	/* The whole right half, top to bottom - the box clips its corners. */
	.wp-block-cover.cta-box__media {
		order: 0;
		aspect-ratio: auto;
	}

	/* Centred between the box's top and bottom, should the media ever be
	   the taller half. */
	.cta-box__content {
		align-self: center;
	}
}

/* ==========================================================================
   Timeline
   The timeline pattern (patterns/timeline.php): a quote and a column of
   steps, 50/50 from 782px container width up (the quote centred beside the
   steps), stacked below - the steps first. A line runs down the steps'
   left edge, filled to --timeline-progress (set by assets/js/timeline.js,
   full without it); each step has a small square on it that turns solid
   once the fill reaches it (.is-reached). The script also pins the stage
   (.is-pinned, its sticky top set inline) while the line fills, if it fits
   the screen.
   ========================================================================== */

.timeline.is-pinned .timeline__stage {
	position: sticky;
}

.wp-block-group.timeline__body {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--l);
}

.wp-block-group.timeline__steps {
	--timeline-progress: 1;
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--m);
	padding-inline-start: var(--wp--preset--spacing--m);
}

.timeline__steps::before,
.timeline__steps::after {
	content: "";
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: 0;
	width: 2px;
	height: 100%;
	background-color: color-mix(in srgb, currentColor 15%, transparent);
}

.timeline__steps::after {
	height: calc(var(--timeline-progress) * 100%);
	background-color: var(--wp--custom--color--heading);
}

.timeline__step {
	position: relative;
}

/* The square on the line, level with the step's heading. */
.timeline__step::before {
	content: "";
	position: absolute;
	z-index: 1;
	inset-block-start: 0.5em;
	inset-inline-start: calc(-1 * var(--wp--preset--spacing--m) - 0.3em + 1px);
	width: 0.6em;
	height: 0.6em;
	background-color: color-mix(in srgb, currentColor 30%, transparent);
	transition: background-color 0.2s;
}

.timeline__step.is-reached::before {
	background-color: var(--wp--custom--color--heading);
}

/* On a phone the steps come first, right under the headline, the quote
   after them. */
@container (max-width: 781px) {
	.timeline__body > .timeline__steps {
		order: -1;
	}
}

@container (min-width: 782px) {
	.wp-block-group.timeline__body {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		align-items: center;
		gap: var(--wp--preset--spacing--m);
	}
}

/* ==========================================================================
   History
   The history pattern (patterns/history.php): the timeline's line and
   squares (above) with entries of a date and a card - a 4:3 cover over a
   text box, rounded as one. From 782px container width up (--alternate)
   the line runs down the middle, each entry a 50/50 row with its date on
   one side of the line and its card on the other, alternating; below that
   a row swiped sideways, the line along its top, the date above the card.
   ========================================================================== */

.wp-block-group.history__card {
	overflow: hidden;
	border-radius: var(--wp--custom--radius);
}

/* The card clips its corners - cover and text box get none of their own,
   so they meet in a straight line. */
.history__card > .history__media,
.history__card > .history__media > .wp-block-cover__background,
.wp-block-group.history__card > .history__text {
	border-radius: 0;
}

.wp-block-cover.history__media {
	min-height: 0;
	aspect-ratio: 4 / 3;
}

/* On a phone a row swiped sideways, to the screen edge like the key
   figures: the line runs along the top, a square above each entry. The
   line spans the whole row - assets/js/timeline.js sets its length
   (--timeline-track) and fills it as the row is swiped. */
@container (max-width: 781px) {
	.wp-block-group.timeline__steps--alternate {
		flex-direction: row;
		gap: var(--wp--preset--spacing--m);
		margin-inline: calc(-1 * var(--wp--preset--spacing--m)) !important;
		padding-block-start: var(--wp--preset--spacing--m);
		padding-inline: var(--wp--preset--spacing--m);
		scroll-padding-inline: var(--wp--preset--spacing--m);
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scrollbar-width: none;
	}

	.wp-block-group.timeline__steps--alternate::-webkit-scrollbar {
		display: none;
	}

	.timeline__steps--alternate::before,
	.timeline__steps--alternate::after {
		inset-block-start: calc(var(--wp--preset--spacing--m) / 2 - 1px);
		width: var(--timeline-track, 100%);
		height: 2px;
	}

	.timeline__steps--alternate::after {
		width: calc(var(--timeline-progress) * var(--timeline-track, 100%));
	}

	/* Every card as tall as the tallest: the entries stretch in the row,
	   the card fills its entry below the date and the text box the card. */
	.timeline__steps--alternate > .timeline__step {
		display: flex;
		flex: 0 0 80%;
		flex-direction: column;
		scroll-snap-align: start;
	}

	.timeline__steps--alternate > .timeline__step > .history__card {
		display: flex;
		flex: 1;
		flex-direction: column;
	}

	.history__card > .history__text {
		flex: 1;
	}

	.timeline__steps--alternate > .timeline__step::before {
		inset-block-start: calc(-1 * var(--wp--preset--spacing--m) / 2 - 0.3em);
		inset-inline-start: 0;
	}
}

@container (min-width: 782px) {
	.wp-block-group.timeline__steps--alternate {
		padding-inline-start: 0;
	}

	.timeline__steps--alternate::before,
	.timeline__steps--alternate::after {
		inset-inline-start: calc(50% - 1px);
	}

	.timeline__steps--alternate > .timeline__step {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: var(--wp--preset--spacing--l);
		align-items: start;
	}

	.timeline__steps--alternate > .timeline__step::before {
		inset-inline-start: calc(50% - 0.3em);
	}

	.timeline__steps--alternate > .timeline__step > * {
		grid-row: 1;
	}

	/* Side by side now, so without the space the date keeps above its card
	   on a phone. */
	.timeline__steps--alternate > .wp-block-group.timeline__step > * {
		margin-block: 0;
	}

	.timeline__steps--alternate > .timeline__step:nth-child(odd) > .history__date {
		grid-column: 2;
	}

	.timeline__steps--alternate > .timeline__step:nth-child(even) > .history__date {
		grid-column: 1;
		text-align: end;
	}

	.timeline__steps--alternate > .timeline__step:nth-child(odd) > .history__card {
		grid-column: 1;
	}

	.timeline__steps--alternate > .timeline__step:nth-child(even) > .history__card {
		grid-column: 2;
	}
}

/* ==========================================================================
   Statement
   The statement pattern (patterns/statement.php): two paragraphs under the
   statement, 50/50 from 782px container width up, stacked below.
   ========================================================================== */

.wp-block-group.statement {
	display: grid;
	gap: var(--wp--preset--spacing--s);
}

@container (min-width: 782px) {
	.wp-block-group.statement {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--wp--preset--spacing--m);
	}

	/* The text-split pattern (patterns/text-split.php): a headline and a
	   paragraph, centred on each other. (The compare pattern's boxes use the
	   plain split, so they stretch to the same height.) */
	.wp-block-group.statement--centered {
		align-items: center;
	}
}

/* ==========================================================================
   Staggered text and media
   The staggered pattern (patterns/staggered.php): two halves of a text and
   a 3:4 cover, 50/50 from 782px container width up - the first text above
   its cover, the second cover above its text, so the halves sit offset.
   Below that one below the other, each text before its cover (order).
   ========================================================================== */

.wp-block-group.staggered,
.wp-block-group.staggered__half {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--m);
}

.wp-block-cover.staggered__media {
	order: 1;
	min-height: 0;
	aspect-ratio: 3 / 4;
}

@container (min-width: 782px) {
	.wp-block-group.staggered {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		align-items: start;
	}

	.staggered__half--media-first > .staggered__media {
		order: 0;
	}
}

/* ==========================================================================
   Zigzag
   The zigzag pattern (patterns/zigzag.php): rows of a text and a 4:3 cover,
   50/50 and vertically centred from 782px container width up - the cover
   on the right in odd rows, on the left in even ones. Below that each cover
   comes first (order).
   ========================================================================== */

.wp-block-group.zigzag {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--l);
}

.wp-block-group.zigzag__row {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--m);
}

.wp-block-cover.zigzag__media {
	order: -1;
	min-height: 0;
	aspect-ratio: 4 / 3;
}

@container (min-width: 782px) {
	.wp-block-group.zigzag__row {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		align-items: center;
	}

	.wp-block-cover.zigzag__media {
		order: 0;
	}

	.zigzag__row:nth-child(even) > .zigzag__media {
		order: -1;
	}
}

/* ==========================================================================
   Events
   The events pattern (patterns/events.php): rows between thin lines (the
   text colour, faded, like the FAQ's). From 782px container width up the
   name and place fill the left, the date and the button sit on the right,
   all vertically centred; below that everything follows one below the
   other.
   ========================================================================== */

.wp-block-group.events__row {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--s);
	padding-block: var(--wp--preset--spacing--m);
	border-block-end: 1px solid color-mix(in srgb, currentColor 15%, transparent);
}

.wp-block-group.events__row:first-child {
	padding-block-start: 0;
}

.wp-block-group.events__row:last-child {
	padding-block-end: 0;
	border-block-end: 0;
}

@container (min-width: 782px) {
	.wp-block-group.events__row {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto auto;
		align-items: center;
		column-gap: var(--wp--preset--spacing--l);
	}
}

/* ==========================================================================
   Pricing
   The pricing pattern (patterns/pricing.php): three cards, 33/33/33 from
   1024px container width up, stacked below - on a tablet three cards side
   by side left each a narrow strip of text. Each card is a column whose
   feature list takes up the spare height, so the buttons line up whatever
   the lists' lengths.
   ========================================================================== */

.wp-block-group.pricing {
	display: grid;
	gap: var(--wp--preset--spacing--s);
}

.wp-block-group.pricing__card {
	display: flex;
	flex-direction: column;
	border-radius: var(--wp--custom--radius);
}

.pricing__card > .pricing__features {
	flex-grow: 1;
}

@container (min-width: 1024px) {
	.wp-block-group.pricing {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* ==========================================================================
   Price with tiers
   The price-tiers pattern (patterns/price-tiers.php): the text and a card,
   50/50 and vertically centred from 782px container width up; below that
   the card runs full width under the text. The card's tiers are core's
   Tabs block, shown here as a switch below the price (order): the tab
   buttons side by side on a faint track, the active one white.
   ========================================================================== */

.wp-block-group.price-tiers {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--l);
}

.price-tiers__card .wp-block-tabs {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--s);
}

.price-tiers__card .wp-block-tabs > * {
	margin-block: 0;
}

.price-tiers__card .wp-block-tabs .wp-block-tab-list {
	order: 1;
	gap: 0;
	width: fit-content;
	padding: 0.25em;
	background-color: color-mix(in srgb, currentColor 15%, transparent);
}

.price-tiers__card .wp-block-tab-list button {
	padding: 0.5em 1em;
	color: inherit;
}

.price-tiers__card .wp-block-tab-list button[aria-selected="true"] {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
}

.price-tiers__card .wp-block-tab-list button[aria-selected="true"]::before {
	display: none;
}

@container (min-width: 782px) {
	.wp-block-group.price-tiers {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		align-items: center;
		gap: var(--wp--preset--spacing--m);
	}
}

.wp-block-group.price-tiers__card {
	border-radius: var(--wp--custom--radius);
}

/* On a phone (the card's padding halved in Pattern layouts) the tier
   switch becomes a segmented control: two tiers share the full width in
   equal parts - a grid, since core forces the buttons' flex values from
   the list - each tab as wide as the other, the active one included; a
   label too long for its half wraps instead of the switch swiping. Three
   tiers or more stand one below the other, each the full width: three
   labels such as "36 months" side by side don't fit a phone. */
@container (max-width: 781px) {
	.price-tiers__card .wp-block-tabs .wp-block-tab-list {
		display: grid;
		grid-auto-columns: minmax(0, 1fr);
		grid-auto-flow: column;
		box-sizing: border-box;
		width: 100%;
		overflow-x: visible;
	}

	.price-tiers__card .wp-block-tabs .wp-block-tab-list:has(> :nth-child(3)) {
		grid-auto-flow: row;
	}

	/* Each tab fills its cell, so the active one is as wide as the others
	   (core sizes the buttons to their text). */
	.price-tiers__card .wp-block-tab-list button {
		width: 100%;
		padding-inline: 0.75em;
		text-align: center;
		text-wrap: balance;
		white-space: normal;
	}
}

/* ==========================================================================
   Certificates
   The certificates pattern (patterns/certificates.php): a grid of seals,
   25/25/25/25 from 1024px container width up, 50/50 from 480px (a tablet
   included), one below the other below that.
   ========================================================================== */

.wp-block-group.certificates {
	display: grid;
	gap: var(--wp--preset--spacing--m);
}

.certificates .wp-block-image {
	margin-block-end: 0;
}

@container (min-width: 480px) {
	.wp-block-group.certificates {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@container (min-width: 1024px) {
	.wp-block-group.certificates {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		row-gap: var(--wp--preset--spacing--l);
	}
}

/* ==========================================================================
   Logo bar
   The logo-bar pattern (patterns/logo-bar.php): an endless strip of logos
   on every screen size, edge to edge, like the marquees: assets/js/marquee.js
   wraps the logos in a track and a rail with a second, aria-hidden copy
   (.is-marquee), tops a short track up with repeats and sets the rail's
   duration by its length; the rail moves by one copy's width (-50%).
   Without the script - in the editor and the pattern previews - the same
   strip standing still: one row cut off at the edge, scrolled sideways,
   so it reads as the strip it becomes and every logo stays in reach.

   The full-screen opener's row of logos (.logo-bar--row) never runs: from
   782px up it is one calm row, justified - rail and track step aside there
   (display: contents), so the logos are its items again - and below that
   it is hidden (Full-screen opener).
   ========================================================================== */

.wp-block-group.logo-bar {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	gap: var(--wp--preset--spacing--l);
	overflow-x: auto;
	scrollbar-width: thin;
}

.logo-bar > .wp-block-image {
	flex: none;
}

.logo-bar .wp-block-image {
	margin-block: 0;
}

/* A logo keeps its own shape: no corners from the style variation's radius,
   which would clip a logo with a ground of its own. */
.logo-bar .wp-block-image img {
	border-radius: 0;
}

/* The strip. The space after the last logo is the track's own padding, not
   a gap on the rail: the rail is then exactly two tracks wide. A logo bar
   inserted before the strip ran on desktops too is only wide, not full -
   it reaches the screen edge on phones through the page margin. */
.wp-block-group.logo-bar.is-marquee {
	display: block;
	overflow: hidden;
}

.logo-bar__rail {
	display: flex;
	width: max-content;
	animation: digistarter-marquee 30s linear infinite;
}

.logo-bar__track {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--l);
	padding-inline-end: var(--wp--preset--spacing--l);
}

.logo-bar__track > .wp-block-image {
	flex: none;
}

@media (prefers-reduced-motion: reduce) {
	.logo-bar__rail {
		animation-play-state: paused;
	}
}

@container (max-width: 781px) {
	.wp-block-group.logo-bar.is-marquee:not(.alignfull) {
		margin-inline: calc(-1 * var(--wp--preset--spacing--m)) !important;
	}

	.wp-block-group.logo-bar {
		gap: var(--wp--preset--spacing--m);
	}

	.logo-bar__track {
		gap: var(--wp--preset--spacing--m);
		padding-inline-end: var(--wp--preset--spacing--m);
	}
}

@container (min-width: 782px) {
	/* The full-screen opener's row: one row, however many logos, justified -
	   the free space shared out between them, the first logo at the left
	   edge, the last at the right. */
	.wp-block-group.logo-bar--row,
	.wp-block-group.logo-bar--row.is-marquee {
		display: grid;
		grid-template-columns: none;
		grid-auto-columns: auto;
		grid-auto-flow: column;
		justify-content: space-between;
		overflow: visible;
	}

	.logo-bar--row .wp-block-image {
		justify-self: center;
	}

	.logo-bar--row .wp-block-image:first-child {
		justify-self: start;
	}

	.logo-bar--row .wp-block-image:last-of-type {
		justify-self: end;
	}

	.logo-bar--row .logo-bar__rail,
	.logo-bar--row .logo-bar__track {
		display: contents;
	}

	.logo-bar--row .logo-bar__track--clone,
	.logo-bar--row .logo-bar__repeat {
		display: none;
	}
}

/* ==========================================================================
   Steps
   The steps pattern (patterns/steps.php): paragraphs numbered by a CSS
   counter, each number in a circle - so rearranged or duplicated steps stay
   in order, a line running from each circle to the next (not after the
   last). From 1024px container width up 25/25/25/25; below that - a
   tablet included, where four steps side by side were too narrow - a row
   swiped sideways.
   ========================================================================== */

/* The circle in rem, not em: an em resolves against each element's own font
   size - the number's (large) for the circle, the text's for the line - and
   the line would start inside the circle. border-box, so its border doesn't
   widen it either. */
.wp-block-group.steps {
	--steps-circle: 4rem;
	display: grid;
	gap: var(--wp--preset--spacing--m);
	counter-reset: step;
}

.steps__step {
	position: relative;
	counter-increment: step;
}

.steps__step::before {
	content: counter(step);
	display: grid;
	place-items: center;
	box-sizing: border-box;
	width: var(--steps-circle);
	height: var(--steps-circle);
	margin-block-end: var(--wp--preset--spacing--s);
	border: 2px solid currentColor;
	border-radius: 50%;
	font-size: var(--wp--preset--font-size--large);
	font-weight: 400;
	line-height: 1;
}

/* The line from each circle to the next, across the gap (not after the
   last) - in the row on a desktop and in the swipe row on a phone alike. */
.steps__step:not(:last-child)::after {
	content: "";
	position: absolute;
	inset-block-start: calc(var(--steps-circle) / 2 - 1px);
	inset-inline-start: var(--steps-circle);
	width: calc(100% - var(--steps-circle) + var(--wp--preset--spacing--m));
	height: 2px;
	background-color: currentColor;
}

/* On a phone and a tablet a row swiped sideways, to the screen edge like
   the key figures: each step snaps to the content's edge, the next one
   peeking in with the line running on into it - a hint that there is
   more. */
@container (max-width: 1023px) {
	.wp-block-group.steps {
		display: flex;
		margin-inline: calc(-1 * var(--wp--preset--spacing--m)) !important;
		padding-inline: var(--wp--preset--spacing--m);
		scroll-padding-inline: var(--wp--preset--spacing--m);
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scrollbar-width: none;
	}

	.wp-block-group.steps::-webkit-scrollbar {
		display: none;
	}

	.wp-block-group.steps > .steps__step {
		flex: 0 0 70%;
		margin-block: 0;
		scroll-snap-align: start;
	}
}

/* On a tablet two and a bit steps at a time. */
@container (min-width: 782px) and (max-width: 1023px) {
	.wp-block-group.steps > .steps__step {
		flex-basis: 40%;
	}
}

@container (min-width: 1024px) {
	.wp-block-group.steps {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/* ==========================================================================
   Comparison
   The compare pattern (patterns/compare.php): two boxes on the statement
   pattern's 50/50 split above, stretched to the same height.
   ========================================================================== */

.compare__box {
	border-radius: var(--wp--custom--radius);
}

/* ==========================================================================
   Comparison table
   The compare-table pattern (patterns/compare-table.php): a table built from
   groups - one per row, one block per cell - so a cell can be a list item
   that picks check, cross or the plain square under Styles (Lists, below).
   Every row is a grid with one column per cell, so a column added to each
   row simply adds a column. Thin lines between the rows (the text colour,
   faded, like the FAQ's), the header row on a faint ground, and the column
   of the version recommended - its name in the header row picks the
   paragraph style Recommended (inc/blocks.php) - highlighted: its header in
   the primary colour, its cells in the accent. On a primary section the
   header turns accent, on an accent section the cells turn white, so the
   column never vanishes into the section.
   ========================================================================== */

.compare-grid__row {
	display: grid;
	grid-auto-columns: minmax(0, 1fr);
	grid-auto-flow: column;
}

.compare-grid > *,
.compare-grid__row > * {
	margin-block: 0 !important;
}

/* The corner cell stays empty - in the editor without the empty paragraph's
   long "type / to choose a block" hint stretching the header row. */
.compare-grid__head > :first-child [data-rich-text-placeholder] {
	display: none;
}

/* The editor's "add block" button of a selected row is no column of its own. */
.compare-grid__row > .block-list-appender {
	position: absolute;
}

.compare-grid__row > * {
	box-sizing: border-box;
	padding: var(--wp--preset--spacing--s);
	border-block-end: 1px solid color-mix(in srgb, currentColor 15%, transparent);
}

/* A cell's mark (a one-item list) sits in the line of a cell's text, drawn
   larger so it reads on its own - scaled, so the line keeps its height. */
.compare-grid__row > ul.wp-block-list {
	padding-inline-start: var(--wp--preset--spacing--s);
}

.compare-grid .compare-grid__row > ul.wp-block-list li::before {
	scale: 1.5;
}

.compare-grid__head > :not(:first-child) {
	background-color: color-mix(in srgb, currentColor 6%, transparent);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 700;
}

/* The highlight's colours, per section style. */
.compare-grid {
	--compare-head-bg: var(--wp--preset--color--primary);
	--compare-head-text: var(--wp--custom--scheme--dark--text);
	--compare-cell-bg: var(--wp--preset--color--accent);
	--compare-cell-check: var(--wp--preset--color--primary);
}

:is(.is-style-section-primary, .has-primary-background-color) .compare-grid {
	--compare-head-bg: var(--wp--preset--color--accent);
	--compare-head-text: var(--wp--preset--color--primary);
}

:is(.is-style-section-accent, .has-accent-background-color) .compare-grid {
	--compare-cell-bg: var(--wp--custom--scheme--dark--text);
	--compare-cell-check: var(--wp--preset--color--accent);
}

.compare-grid__head > .is-style-recommended {
	background-color: var(--compare-head-bg);
	color: var(--compare-head-text);
}

/* The cells below a recommended name, in up to six versions' columns (the
   row labels are the first). They re-colour the marks too: the check turns
   primary on the accent (it would vanish), the square takes the cell's
   text colour. */
:is(
	.compare-grid:has(> .compare-grid__head > .is-style-recommended:nth-child(2)) > .compare-grid__row:not(.compare-grid__head) > :nth-child(2),
	.compare-grid:has(> .compare-grid__head > .is-style-recommended:nth-child(3)) > .compare-grid__row:not(.compare-grid__head) > :nth-child(3),
	.compare-grid:has(> .compare-grid__head > .is-style-recommended:nth-child(4)) > .compare-grid__row:not(.compare-grid__head) > :nth-child(4),
	.compare-grid:has(> .compare-grid__head > .is-style-recommended:nth-child(5)) > .compare-grid__row:not(.compare-grid__head) > :nth-child(5),
	.compare-grid:has(> .compare-grid__head > .is-style-recommended:nth-child(6)) > .compare-grid__row:not(.compare-grid__head) > :nth-child(6),
	.compare-grid:has(> .compare-grid__head > .is-style-recommended:nth-child(7)) > .compare-grid__row:not(.compare-grid__head) > :nth-child(7)
) {
	--digistarter-check: var(--compare-cell-check);
	--wp--custom--color--text: var(--wp--preset--color--primary);
	background-color: var(--compare-cell-bg);
	color: var(--wp--preset--color--primary);
}

/* The old price faded in whatever colour its cell has. */
.compare-grid s {
	opacity: 0.6;
}

/* The ground the table sits on - the section's colour - for the row labels
   held in place on a phone while the versions slide under them. */
.compare-grid {
	--compare-surface: var(--wp--preset--color--base);
}

:is(.is-style-section-neutral, .has-neutral-background-color) .compare-grid {
	--compare-surface: var(--wp--preset--color--neutral);
}

:is(.is-style-section-primary, .has-primary-background-color) .compare-grid {
	--compare-surface: var(--wp--preset--color--primary);
}

:is(.is-style-section-accent, .has-accent-background-color) .compare-grid {
	--compare-surface: var(--wp--preset--color--accent);
}

.has-contrast-background-color .compare-grid {
	--compare-surface: var(--wp--preset--color--contrast);
}

/* On a phone the columns keep a readable width - 10rem each - and the table swipes sideways once they no
   longer fit, to the screen edge like the key figures, the row labels
   staying put (their line opaque, so no version shows through it). Words wrap whole (hyphenated where the language allows),
   never split anywhere; the versions' names a size smaller. */
@container (max-width: 781px) {
	.wp-block-group.compare-grid {
		margin-inline: calc(-1 * var(--wp--preset--spacing--m)) !important;
		padding-inline: var(--wp--preset--spacing--m);
		overflow-x: auto;
		scrollbar-width: none;
	}

	.wp-block-group.compare-grid::-webkit-scrollbar {
		display: none;
	}

	.compare-grid__row {
		grid-template-columns: minmax(10rem, 1fr);
		grid-auto-columns: minmax(10rem, 1fr);
		min-width: min-content;
	}

	.compare-grid__row > * {
		padding-inline: 0.75rem;
		overflow-wrap: break-word;
	}

	.compare-grid__row > ul.wp-block-list {
		padding-inline-start: 0.75rem;
	}

	.compare-grid__head > :not(:first-child) {
		font-size: var(--wp--preset--font-size--medium);
	}

	/* The row labels: in line with the page margin at the start, then held
	   at the screen edge on the section's colour. */
	.compare-grid__row > :first-child {
		position: sticky;
		/* The table's own padding counts off the sticky edge - minus it for the
		   screen edge itself. */
		inset-inline-start: calc(-1 * var(--wp--preset--spacing--m));
		z-index: 1;
		margin-inline-start: calc(-1 * var(--wp--preset--spacing--m)) !important;
		padding-inline-start: var(--wp--preset--spacing--m);
		border-block-end-color: color-mix(in srgb, currentColor 15%, var(--compare-surface));
		background-color: var(--compare-surface);
		/* A pixel past its bottom edge: a row ending on a fraction of a pixel
		   let the line of the version under it flash through. */
		box-shadow: 0 1px 0 var(--compare-surface);
	}
}

/* The comparison table as the pattern inserted it before (core's Table block,
   class "compare-table", the fourth column highlighted) - kept so pages
   built with it look the same after an update. On a phone a swipe row with
   the row labels held in place. */
.wp-block-table.compare-table table {
	min-width: 640px;
	border-collapse: collapse;
}

.compare-table :is(th, td) {
	padding: var(--wp--preset--spacing--s);
	border: 0;
	border-block-end: 1px solid color-mix(in srgb, currentColor 15%, transparent);
	text-align: start;
	vertical-align: middle;
}

.compare-table thead {
	border: 0;
}

.compare-table thead th:not(:first-child) {
	background-color: color-mix(in srgb, currentColor 6%, transparent);
	font-size: var(--wp--preset--font-size--large);
}

.compare-table thead th:nth-child(4) {
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--custom--scheme--dark--text);
}

.compare-table tbody td:nth-child(4) {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--primary);
}

:is(.is-style-section-primary, .has-primary-background-color) .compare-table thead th:nth-child(4) {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--primary);
}

:is(.is-style-section-accent, .has-accent-background-color) .compare-table tbody td:nth-child(4) {
	background-color: var(--wp--custom--scheme--dark--text);
}

.compare-table s {
	opacity: 0.6;
}

/* The section's colour, for the row labels covering the columns sliding
   under them on a phone. */
.compare-table {
	--compare-surface: var(--wp--preset--color--base);
}

:is(.is-style-section-neutral, .has-neutral-background-color) .compare-table {
	--compare-surface: var(--wp--preset--color--neutral);
}

:is(.is-style-section-primary, .has-primary-background-color) .compare-table {
	--compare-surface: var(--wp--preset--color--primary);
}

:is(.is-style-section-accent, .has-accent-background-color) .compare-table {
	--compare-surface: var(--wp--preset--color--accent);
}

.has-contrast-background-color .compare-table {
	--compare-surface: var(--wp--preset--color--contrast);
}

@container (max-width: 781px) {
	.wp-block-table.compare-table {
		margin-inline: calc(-1 * var(--wp--preset--spacing--m)) !important;
		padding-inline-end: var(--wp--preset--spacing--m);
		overflow-x: auto;
		scrollbar-width: none;
	}

	.wp-block-table.compare-table::-webkit-scrollbar {
		display: none;
	}

	/* Separate borders: with collapsed ones the other columns' lines would
	   show through the row labels held on top of them. */
	.wp-block-table.compare-table table {
		width: max-content;
		min-width: 0;
		table-layout: auto;
		border-collapse: separate;
		border-spacing: 0;
	}

	.compare-table :is(th, td) {
		width: 6.5rem;
	}

	.compare-table :is(th, td):first-child {
		position: sticky;
		inset-inline-start: 0;
		z-index: 1;
		width: 4.5rem;
		padding-inline-start: var(--wp--preset--spacing--m);
		background-color: var(--compare-surface);
	}
}

/* ==========================================================================
   Accordions
   The Accordion block and the faq pattern's Details blocks look alike: each
   item sits between thin lines, the question bold at h3 size with a plus at
   its end that turns into a cross when open (core's own icon and rotation
   for the Accordion). The lines take the text colour, faded, so they stay
   visible on every section style.
   ========================================================================== */

:is(.wp-block-accordion-item, .faq__list .wp-block-details) {
	border-block-end: 1px solid color-mix(in srgb, currentColor 15%, transparent);
}

:is(.wp-block-accordion-item, .faq__list .wp-block-details):first-child {
	border-block-start: 1px solid color-mix(in srgb, currentColor 15%, transparent);
}

/* Named children, not "> *": that would tie with core's block gap rule,
   which the editor loads after this file. */
:is(.wp-block-accordion, .wp-block-accordion-item) > :is(.wp-block-accordion-item, .wp-block-accordion-heading, .wp-block-accordion-panel) {
	margin-block: 0;
}

.wp-block-accordion-heading,
.faq__list summary {
	color: var(--wp--custom--color--heading);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 700;
	line-height: 1.2;
}

.wp-block-accordion-heading .wp-block-accordion-heading__toggle,
.faq__list summary {
	gap: var(--wp--preset--spacing--s);
	padding-block: var(--wp--preset--spacing--s);
}

.wp-block-accordion-heading .wp-block-accordion-heading__toggle:hover .wp-block-accordion-heading__toggle-title {
	text-decoration: none;
}

/* Core centres the icon in a 1.2em box; flush with the edge, like the
   Details blocks' plus. */
.wp-block-accordion-heading .wp-block-accordion-heading__toggle-icon {
	width: auto;
}

/* The question's own padding already spaces the answer from it. */
.wp-block-accordion-panel > :first-child,
.faq__list summary + * {
	margin-block-start: 0;
}

.wp-block-accordion-panel {
	padding-block-end: var(--wp--preset--spacing--s);
}

.wp-block-accordion-panel > :last-child {
	margin-block-end: 0;
}

.faq__list .wp-block-details > :last-child {
	margin-block-end: 0;
	padding-block-end: var(--wp--preset--spacing--s);
}

/* Details blocks bring no icon of their own: the same plus as the
   Accordion's, turned the same way. */
.faq__list summary {
	display: flex;
	justify-content: space-between;
	align-items: center;
	list-style: none;
	cursor: pointer;
}

.faq__list summary::-webkit-details-marker {
	display: none;
}

.faq__list summary::after {
	content: "+";
	flex: none;
	transition: transform 0.2s;
}

.faq__list details[open] > summary::after {
	transform: rotate(45deg);
}

@media (prefers-reduced-motion: reduce) {
	.faq__list summary::after {
		transition: none;
	}
}

/* ==========================================================================
   Quote
   Core's Quote block, wherever it is used: the quote itself bold at x-large,
   the citation below it in the caption colour (both theme.json, so the
   Styles panel can change them), and a quotation mark in the accent role
   above it - s above the quote, which sits m above its citation.
   ========================================================================== */

.wp-block-quote::before {
	content: "\201C";
	display: block;
	margin-block-end: var(--wp--preset--spacing--s);
	color: var(--wp--custom--color--link-hover-accent);
	font-size: var(--wp--preset--font-size--xx-large);
	line-height: 0.5;
}

.wp-block-quote cite {
	display: block;
	margin-block-start: var(--wp--preset--spacing--m);
}

/* ==========================================================================
   Tabs
   Core's Tabs block, wherever it is used: bold labels, the inactive ones in
   the caption colour, the active one in the heading colour and underlined
   a little heavier than core's 2px.
   ========================================================================== */

/* The tabs stay on one line: more than fit are swiped sideways (the next one
   peeking in at the edge) instead of wrapping into a stack of rows. */
.wp-block-tabs .wp-block-tab-list {
	flex-wrap: nowrap;
	gap: var(--wp--preset--spacing--s);
	overflow-x: auto;
	scrollbar-width: none;
}

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

.wp-block-tab-list button {
	flex-shrink: 0;
	white-space: nowrap;
	padding: 0 0 0.5em;
	color: var(--wp--custom--color--caption);
	font-weight: 700;
}

.wp-block-tab-list button[aria-selected="true"] {
	color: var(--wp--custom--color--heading);
}

.wp-block-tab-list button[aria-selected="true"]::before {
	border-bottom-width: 3px;
}

/* ==========================================================================
   Legal page
   The page-legal pattern: the table of contents in a neutral box, its list
   tight like any list.
   ========================================================================== */

/* The head (headline, date) and what follows l apart, like a section head
   and its content. */
.wp-block-group.legal-toc {
	margin-block-start: var(--wp--preset--spacing--l);
}

.legal-toc > * + * {
	margin-block-start: 0.5em;
}

.legal-toc ol {
	margin-block-end: 0;
}


/* ==========================================================================
   FAQ
   The faq pattern (patterns/faq.php): the headline and the list of
   questions (styled under Accordions), 50/50 from 782px container width up,
   stacked below.
   ========================================================================== */

.wp-block-group.faq {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--m);
}

@container (min-width: 782px) {
	.wp-block-group.faq {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* ==========================================================================
   Lists
   A list item's own Styles tab offers two markers in place of its default
   bullet - Check and Cross (inc/blocks.php registers them; core/list-item's
   own save() gives the <li> only the is-style-* class itself, no base
   "wp-block-list-item" class to also key off). The default, with neither
   picked, is a plain square in the text colour. All three share one box
   (size, position, the gap above and the text's indent) so switching
   between them never shifts anything else - only the mark inside changes.
   ========================================================================== */

/* Bulleted lists only - a numbered list (ol) keeps its numbers and its
   indent, except for an item there that picks Check or Cross itself. */
ul.wp-block-list {
	/* Core's own default left padding on the list itself, not just each
	   item's marker/text gap below - without this the whole list sits
	   indented from the paragraphs and buttons around it instead of sharing
	   their edge. */
	padding-inline-start: 0;
}

/* list-style stays "none" (not display:none, and not on the item itself)
   so a screen reader still announces list/item count. */
:is(ul.wp-block-list li, .wp-block-list li.is-style-check, .wp-block-list li.is-style-cross) {
	position: relative;
	list-style: none;
	padding-inline-start: 1.75em;
	/* Tighter than the spacing scale's own smallest step (s) allows - same
	   idea as the comment thread's own 0.5em/0.3em/0.25em gaps elsewhere in
	   this file, for a list read as one connected group rather than
	   individually spaced-out lines. */
	margin-block-start: 0.5em;
}

:is(ul.wp-block-list li, .wp-block-list li.is-style-check, .wp-block-list li.is-style-cross):first-child {
	margin-block-start: 0;
}

/* Centred on the item's first line (1lh = one line of its own text), not
   the whole item - a point that wraps onto a second line keeps its mark
   beside the first. */
:is(ul.wp-block-list li, .wp-block-list li.is-style-check, .wp-block-list li.is-style-cross)::before {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	inset-block-start: calc((1lh - 1.1em) / 2);
	width: 1.1em;
	height: 1.1em;
	border-radius: var(--wp--custom--radius);
}

/* Smaller than the shared 1.1em slot, centred inside it - full size next to
   the check/cross icons' own small, open shapes reads as a much heavier
   mark. */
ul.wp-block-list li:not(.is-style-check, .is-style-cross)::before {
	inset-inline-start: 0.275em;
	inset-block-start: calc((1lh - 0.55em) / 2);
	width: 0.55em;
	height: 0.55em;
	background-color: var(--wp--custom--color--text);
}

/* The accent, or primary on an accent surface, where the accent would
   vanish - --digistarter-check is set per surface in Colour schemes. */
.wp-block-list li.is-style-check::before {
	background-color: var(--digistarter-check, var(--wp--preset--color--accent));
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M6.4 11.2 3.2 8l-1.2 1.2L6.4 13.6 14 6l-1.2-1.2z'/%3E%3C/svg%3E") center / 70% no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M6.4 11.2 3.2 8l-1.2 1.2L6.4 13.6 14 6l-1.2-1.2z'/%3E%3C/svg%3E") center / 70% no-repeat;
}

.wp-block-list li.is-style-cross::before {
	background-color: var(--wp--preset--color--error);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' d='M4 4l8 8M12 4l-8 8'/%3E%3C/svg%3E") center / 70% no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' d='M4 4l8 8M12 4l-8 8'/%3E%3C/svg%3E") center / 70% no-repeat;
}

/* ==========================================================================
   Posts
   Cards, pills and bands of the blog templates (patterns/post-card.php,
   post-grid.php, blog-*.php, single-post.php).
   ========================================================================== */

/* Pills: categories and tags look like buttons, meta such as the date like a
   hovered button - so both follow every colour scheme and the corner radius.
   Every pill - these and a section's label above its headline - in capitals. */
.pills {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5em;
	padding: 0;
	list-style: none;
}

.pills .wp-block-post-terms__separator {
	display: none;
}

.pills a,
.meta-pill {
	display: inline-block;
	width: fit-content;
	padding: 0.2em 0.8em;
	border-radius: var(--wp--custom--radius);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	line-height: 1.6;
	text-transform: uppercase;
}

.pills a {
	background-color: var(--wp--custom--color--button-background);
	color: var(--wp--custom--color--button-text);
	text-decoration: none;
}

.pills a:hover {
	background-color: var(--wp--custom--color--button-hover-background);
	color: var(--wp--custom--color--button-hover-text);
	text-decoration: none;
}

.meta-pill {
	background-color: var(--wp--custom--color--button-hover-background);
	color: var(--wp--custom--color--button-hover-text);
}

.meta-pill > * {
	margin: 0;
}

/* A pill above a section's headline sits the same s above it in every
   pattern, whatever block gap its group has. */
.wp-block-group.meta-pill + .wp-block-heading {
	margin-block-start: var(--wp--preset--spacing--s);
}

/* core/query-no-results and a comment's text have no layout of their own, so
   their content would keep the browser's 1em paragraph margins on top of the
   theme's spacing (in a comment bubble: under the meta line and above the
   bubble's own bottom padding). */
:is(.wp-block-query-no-results, .wp-block-comment-content) > :first-child {
	margin-block-start: 0;
}

:is(.wp-block-query-no-results, .wp-block-comment-content) > :last-child {
	margin-block-end: 0;
}

/* Cards in a grid: three columns, two on tablets, one on phones. Core spaces
   a post template with margins - the grid gap does that here. */
.post-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--s);
}

.wp-block-post-template.post-grid > * {
	margin-block: 0;
}

@media (max-width: 1023px) {
	.post-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 599px) {
	.post-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* The card clips its image to its own rounded corners. */
.post-card {
	overflow: hidden;
}

.post-card .wp-block-post-featured-image,
.post-card .wp-block-post-featured-image img {
	border-radius: 0;
}

/* The first category sits on the image - inc/query.php caps the term list at
   two pills (the category and a "+N" for the rest); the post itself lists
   every one. */
.post-card__media {
	position: relative;
}

.post-card__media .pills {
	margin: 0;
}

.post-card__media:has(img) .pills {
	position: absolute;
	top: var(--wp--preset--spacing--s);
	inset-inline-start: var(--wp--preset--spacing--s);
}

.post-card__media:not(:has(img)) .pills {
	padding: var(--wp--preset--spacing--s) var(--wp--preset--spacing--s) 0;
}

/* Title size in CSS, not as a block setting: core's font size classes are
   !important and the wide card below couldn't enlarge it. */
.post-card .wp-block-post-title {
	font-size: var(--wp--preset--font-size--large);
}

/* The date closes the card, however long title and excerpt run. */
.post-card__body > .wp-block-post-date {
	margin-top: auto;
}

/* Wide cards: the newest post on the blog page (.has-lead) and the highlight
   band. Image beside the text from tablet width up, mirrored in the band. */
.post-grid.has-lead > :first-child {
	grid-column: 1 / -1;
}

@media (min-width: 782px) {
	:is(.post-grid.has-lead > :first-child, .post-feature) .post-card {
		flex-direction: row;
	}

	/* Four classes, to out-rank the shared rule above. */
	.wp-block-post-template.post-feature.is-reversed .post-card {
		flex-direction: row-reverse;
	}

	/* 50/50 image and text - one of the theme's column splits. */
	:is(.post-grid.has-lead > :first-child, .post-feature) .post-card__media {
		display: flex;
		flex: 0 0 50%;
		flex-direction: column;
	}

	:is(.post-grid.has-lead > :first-child, .post-feature) .wp-block-post-featured-image {
		flex-grow: 1;
	}

	:is(.post-grid.has-lead > :first-child, .post-feature) .wp-block-post-featured-image :is(a, img) {
		height: 100%;
	}

	:is(.post-grid.has-lead > :first-child, .post-feature) .wp-block-post-featured-image img {
		aspect-ratio: 4 / 3 !important; /* Beats the 16/9 core writes inline. */
	}

	:is(.post-grid.has-lead > :first-child, .post-feature) .post-card__body {
		justify-content: center;
		padding: var(--wp--preset--spacing--m) !important; /* Beats the block's inline padding. */
	}

	:is(.post-grid.has-lead > :first-child, .post-feature) .wp-block-post-title {
		font-size: var(--wp--preset--font-size--x-large);
	}

	:is(.post-grid.has-lead > :first-child, .post-feature) .post-card__body > .wp-block-post-date {
		margin-top: 0;
	}
}

/* Full-width bands at the end of a page: the highlight on the blog and the
   related posts below a post. Hidden while their query finds nothing. */
.post-band {
	margin-block-start: var(--wp--preset--spacing--l);
}

.post-band:not(:has(.post-card)) {
	display: none;
}

/* Such a band closes its page (the templates give <main> no bottom padding
   of their own there); while it is hidden, <main> takes over the space, so
   the last content - "no posts found", say - keeps l above the footer.
   !important against the template's inline padding. Written without a
   :has() inside :has(), which CSS doesn't allow. */
main.wp-block-group:has(> .post-band):not(:has(> .post-band .post-card)) {
	padding-bottom: var(--wp--preset--spacing--l) !important;
}

/* Without posts the category filter has nothing to offer - core would print
   "No categories" as a bare line. */
.pills:has(> .cat-item-none) {
	display: none;
}

/* On a neutral post band (the blog's highlight, a post's related posts) the
   card turns primary instead (!important beats core's own preset-colour
   rule), so it still stands out from the band behind it - the same
   light-on-light problem a section style solves with its own card colour.
   Listed among the dark surfaces above, so its text, pills and links switch
   to the dark scheme along with the background. */
.post-band.has-neutral-background-color .post-card {
	background-color: var(--wp--preset--color--primary) !important;
}

/* Comments on a neutral band, the form to write one on a primary band right
   below it - two bands, not two colours in one, so each is hidden on its own
   once its block renders empty (comments closed with none left). */
.comments-band,
.comment-form-band {
	margin-block-start: var(--wp--preset--spacing--l);
}

.comments-band:not(:has(.wp-block-comments)) {
	display: none;
}

.comment-form-band:not(:has(.wp-block-post-comments-form)) {
	display: none;
}

/* Each of these already carries the gap as its own padding - stacking a
   margin on top of that would double it. The :has() guard on the left side
   skips a band that rendered empty and is hidden above. */
.comments-band:has(.wp-block-comments) + .comment-form-band,
.comments-band:has(.wp-block-comments) + .post-band,
.comment-form-band:has(.wp-block-post-comments-form) + .post-band {
	margin-block-start: 0;
}

.wp-block-comment-template li {
	margin-top: var(--wp--preset--spacing--m);
}

/* Messenger thread: a comment sits on the left, a reply to it on the right,
   mirrored - avatar on the outside, the bubble's tip pointing at it. Replies
   are core's nested list; the mirroring takes the place of core's indent. */
.wp-block-comment-template ol {
	padding-inline-start: 0;
}

.wp-block-comment-template li li .comment-row {
	flex-direction: row-reverse;
}

/* Every bubble fills the row beside its avatar - a fixed size reads calmer
   than each one shrinking to its own text. Its colour comes from the scheme
   lists at the top: light for a comment, dark for a reply, accent for a
   reply to a reply. Logical properties, so the tips follow a right-to-left
   language. */
.comment-bubble {
	--comment-bubble-background: var(--wp--preset--color--base);
	position: relative;
	padding: var(--wp--preset--spacing--s);
	border-radius: var(--wp--custom--radius);
	background-color: var(--comment-bubble-background);
}

.wp-block-comment-template li li .comment-bubble {
	--comment-bubble-background: var(--wp--preset--color--primary);
}

/* A reply to a reply (and deeper) stays on the right, in accent. */
.wp-block-comment-template li li li .comment-bubble {
	--comment-bubble-background: var(--wp--preset--color--accent);
}

/* max() keeps the tip below the rounded corner - at a small top offset alone
   it would sit inside the curve itself once the radius grows past it (Extra
   Rounded), floating off the bubble's actual, still-curving edge. The base
   of the triangle reaches 1px into the bubble (-9px, not -10px) rather than
   sitting exactly flush - flush left a hairline seam where the curve's own
   antialiasing met the triangle's hard edge; the 1px overlap hides it under
   the bubble's own background, which is the same solid colour either way. */
.comment-bubble::before {
	content: "";
	position: absolute;
	inset-block-start: max(0.75em, var(--wp--custom--radius));
	inset-inline-start: -9px;
	border-block: 8px solid transparent;
	border-inline-end: 10px solid var(--comment-bubble-background);
}

.wp-block-comment-template li li .comment-bubble::before {
	inset-inline-start: auto;
	inset-inline-end: -9px;
	border-inline-end: 0;
	border-inline-start: 10px solid var(--comment-bubble-background);
}

.comment-bubble > :first-child {
	margin-top: 0;
}

.comment-bubble > :last-child {
	margin-bottom: 0;
}

/* "Name wrote on date:" above the comment text, in the scheme's dimmed
   caption colour. Core wraps name and date in a <div> each, so all three
   parts are set inline to read as one sentence; the colon is punctuation,
   not text to translate. */
.comment-meta-line {
	color: var(--wp--custom--color--caption);
}

.comment-meta-line > * {
	display: inline;
	margin: 0;
}

.comment-meta-line .wp-block-comment-date::after {
	content: ":";
}

/* "Reply" and "Edit" (edit only shows for users who may edit the comment) as
   one line under the bubble, on the bubble's side, separated by a rule
   instead of a pipe character in the markup. */
.comment-actions {
	gap: 0;
}

.wp-block-comment-template li li .comment-actions {
	justify-content: flex-end;
}

.comment-actions .wp-block-comment-edit-link::before {
	content: "|";
	margin: 0 0.5em;
	opacity: 0.4;
}

/* ==========================================================================
   Footer
   ========================================================================== */

/* Footer links are layout, not running text - no underline except on hover
   and for the current page. Outranks the paragraph/list underline from
   theme.json (:root :where(p a)). */
.site-footer a:where(:not(.wp-element-button, :hover, [aria-current="page"])) {
	text-decoration: none;
}

/* The DIGISTALTER mark stays exactly one colour, hover included - it's a
   credit, not an invitation to interact with it like a normal link. Its
   four squares are DIGISTALTER's own green, whatever accent the site
   picks in its Styles - set here on --digistarter-check, which the
   squares' fill reads (footer.php, footer-landing.php; so footers saved
   before this follow too). On an accent surface, where the green has no
   contrast, they turn white. */
.footer-credit-mark,
.footer-credit-mark:hover {
	--digistarter-check: #7cf45f;
	display: inline-flex;
	color: var(--wp--custom--color--link) !important;
}

:is(.has-accent-background-color, .has-secondary-gradient-gradient-background, .is-style-section-accent) .footer-credit-mark {
	--digistarter-check: #ffffff;
}

/* is-style-logos-only paints each icon in its brand colour; the footer icons
   follow the link roles instead, like the credit mark next to them. */
.footer-bottom-bar__social .wp-block-social-link {
	color: var(--wp--custom--color--link);
}

.footer-bottom-bar__social .wp-block-social-link:hover {
	color: var(--wp--custom--color--link-hover-accent);
}

/* No hover scaling - overrides core's .wp-block-social-link:hover. */
.footer-credit-mark:hover,
.wp-block-social-link:hover {
	transform: none;
}

/* Once columns stack (core's column breakpoint), the social links sit above
   the credit line and align left. */
@media (max-width: 781px) {
	.footer-bottom-bar__social {
		order: 1;
	}

	.footer-bottom-bar__credit {
		order: 2;
	}

	.footer-bottom-bar__social .wp-block-social-links {
		justify-content: flex-start;
	}
}

/* ==========================================================================
   Cursor
   An accent shape trails the mouse (assets/js/cursor.js sets its translate)
   and grows into a translucent spot over links and buttons. The system
   cursor stays.
   ========================================================================== */

.digistarter-cursor {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 100001; /* Above the mobile menu overlay. */
	width: 16px;
	height: 16px;
	/* Rests just below and right of the pointer tip, next to the arrow. */
	margin: 12px 0 0 12px;
	/* A third of the style variation's radius: 0 / 8px / 24px make the 16px
	   shape a square, a slightly rounded square or a dot. */
	border-radius: calc(var(--wp--custom--radius) / 3);
	background: var(--wp--preset--color--accent);
	opacity: 0;
	pointer-events: none;
	transition: scale 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28), margin 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28), opacity 0.3s ease;
}

.digistarter-cursor.is-visible {
	opacity: 1;
}

/* The spot centres on the pointer, so the link sits in its middle. */
.digistarter-cursor.is-spot {
	margin: -8px 0 0 -8px;
	scale: 4;
	opacity: 0.3;
}

/* Hidden while the mouse is outside the window. */
html:not(:hover) .digistarter-cursor {
	opacity: 0;
}
