/*
Theme Name: DIGISTARTER
Author: DIGISTALTER GmbH
Author URI: https://www.digistalter.de/
Description: A fast-launching block theme with ready-made patterns and three 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.3
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
   - Mobile menu
   - Pattern layouts (shared)
   - Patterns: Opener, Centered opener, Full-screen 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 pages, 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-contrast-background-color,
.has-primary-gradient-gradient-background,
.is-style-section-primary,
.is-style-section-contrast,
.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. */
.is-style-section-contrast {
	background-color: var(--wp--preset--color--contrast);
}

/* 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 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.
   ========================================================================== */

/* :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;
	}
}

/* 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, .legal-facts) > * {
	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.
   The gap stays only next to a block that isn't a full-width section. */
.wp-block-group.alignfull + .wp-block-group.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 (assets/images/placeholder.svg in the
   middle of the neutral grey, its own ground). 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 grey 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. */
.wp-block-cover:not(:has(> .wp-block-cover__image-background, > .wp-block-cover__video-background)) {
	background: var(--wp--preset--color--neutral) url("assets/images/placeholder.svg") center / clamp(4rem, 25%, 8rem) no-repeat;
}

.wp-block-cover: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(: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;
}

/* 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. 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 100vmax 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. */
.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 {
	border-radius: 0 !important;
}

/* Bold text is bold: the browser's "bolder" only goes one step up from the
   light (300) body text, 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 1024px the header menu collapses into the hamburger (core only does
   this below 600px, where a full menu next to logo and actions no longer
   fits much earlier). One row: logo left, search, contact button and hamburger right. */
@media (max-width: 1023px) {
	.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 1024px up the row never wraps: a menu too long for one line (many
   pages, a long site name) wraps its own items into a second line instead,
   with the logo and the actions staying in place at the sides - rather
   than the actions dropping under the logo. */
@media (min-width: 1024px) {
	.wp-block-group.site-header-row {
		flex-wrap: nowrap;
	}

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

/* 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);
}

/* Form fields follow the style variation's corner radius (theme.json
   custom.radius), like buttons and images do. Checkboxes and radios keep
   their native shape. */
:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="submit"], [type="button"], [type="reset"], [type="image"]), textarea, select),
.wp-block-search__inside-wrapper {
	border-radius: var(--wp--custom--radius);
}

/* 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="submit"], [type="button"], [type="reset"], [type="image"]), 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);
}

/* 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: capped height, flexible width. */
.wp-block-site-logo img {
	max-height: 60px;
	width: auto;
	height: auto;
}

/* In the headers and the footer always 30px tall, its width following the
   logo's proportions - whatever size is set on the block (!important
   against core's default 120px width and a resized logo's inline width).
   Only a logo too wide for its row (a wide logo next to the menu button on
   a phone) shrinks, the whole logo scaled down inside the 30px box
   (object-fit) 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 {
	width: auto !important;
	max-width: 100%;
	height: 30px !important;
	max-height: none;
	object-fit: contain;
	object-position: left center;
}

[dir="rtl"] :is(header, .site-footer) .wp-block-site-logo img {
	object-position: right center;
}

.site-header-landing .wp-block-site-logo img {
	object-position: center;
}

/* ==========================================================================
   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'
   strip runs to the screen edge on a phone (Logo bar).
   ========================================================================== */

.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--preset--color--contrast);
}

.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%;
	}
}

/* ==========================================================================
   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 very large
   letters, 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: clamp(2.5rem, 10vw, 8rem);
	font-weight: 700;
	line-height: 1;
	text-align: center;
	text-transform: uppercase;
}

.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);
	}

	.key-figures__box {
		border-radius: 0;
	}
}

/* ==========================================================================
   Tiles
   The tiles pattern (patterns/tiles.php): text tiles and covers. From 782px
   container width up a 33/33/33 grid of squares, the last text tile two
   columns wide. 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. */
.wp-block-group.tiles > .tiles__text,
.tiles__media,
.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);
	}

	.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, the whole row grows with it, media included. */
	.wp-block-group.tiles > * {
		align-self: stretch;
	}

	.tiles__media,
	.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
   782px container width up, stacked below. 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: 782px) {
	.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: the tabs share the full width in equal parts and
   never wrap - a grid, since core forces the buttons' flex values from the
   list - and each tab as wide as the others, the active one included. Should more tiers not fit, the switch swipes sideways instead. */
@container (max-width: 781px) {
	.price-tiers__card .wp-block-tabs .wp-block-tab-list {
		display: grid;
		grid-auto-columns: 1fr;
		grid-auto-flow: column;
		box-sizing: border-box;
		width: 100%;
		overflow-x: auto;
		scrollbar-width: none;
	}

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

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

/* ==========================================================================
   Certificates
   The certificates pattern (patterns/certificates.php): a grid of seals,
   25/25/25/25 from 782px container width up, 50/50 from 480px, 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: 782px) {
	.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): a row of logos, four to
   a row and justified from 782px container width up. Below that an endless
   strip to the screen 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), and the rail moves by one copy's width (-50%). Without
   the script - and in the editor - a 50/50 grid. From 782px up rail and
   track step aside (display: contents), so the logos are the grid's items
   again.
   ========================================================================== */

.wp-block-group.logo-bar {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--m);
	align-items: center;
}

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

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

	/* 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. */
	.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--m);
		padding-inline-end: var(--wp--preset--spacing--m);
	}

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

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

/* Justified: columns as wide as their widest logo and the free space shared
   out between them, so every row starts at the left edge and ends at the
   right one, with even gaps. */
@container (min-width: 782px) {
	.wp-block-group.logo-bar {
		grid-template-columns: repeat(4, auto);
		justify-content: space-between;
		justify-items: center;
	}

	.logo-bar .wp-block-image:nth-child(4n + 1) {
		justify-self: start;
	}

	.logo-bar .wp-block-image:nth-child(4n) {
		justify-self: end;
	}

	/* One row, however many logos (the full-screen opener's): justified
	   the same way, first to the left edge, last to the right. */
	.wp-block-group.logo-bar--row {
		grid-template-columns: none;
		grid-auto-columns: auto;
		grid-auto-flow: column;
	}

	.logo-bar--row .wp-block-image:is(:nth-child(n), :nth-child(4n)) {
		justify-self: center;
	}

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

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

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

	.logo-bar__track--clone {
		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 782px container width up 25/25/25/25; below that 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 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: 781px) {
	.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;
	}
}

@container (min-width: 782px) {
	.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--preset--color--base);
	--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--preset--color--base);
	--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;
}

/* On a phone the row labels narrower than the versions; more than two
   versions scroll sideways, to the screen edge like the key figures. */
@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(4.5rem, 0.8fr);
		grid-auto-columns: minmax(6.5rem, 1fr);
	}

	/* Narrower cells, so a word of a version's name keeps to one line. */
	.compare-grid__row > * {
		padding-inline: 0.75rem;
	}

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

	.compare-grid__row > :first-child {
		padding-inline-start: 0;
	}
}

/* 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--preset--color--base);
}

.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--preset--color--base);
}

.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 pages
   The page-legal and page-legal-notice patterns: the table of contents in a
   neutral box (its list tight, like any list), and the provider details
   as small heading-and-text groups one under the other, m apart, the text
   right under its heading.
   ========================================================================== */

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

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

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

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

.legal-facts__item > * {
	margin-block: 0;
}

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

/* ==========================================================================
   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. */
.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;
}

.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 DIGISTARTER mark stays exactly one colour, hover included - it's a
   credit, not an invitation to interact with it like a normal link. */
.footer-credit-mark,
.footer-credit-mark:hover {
	display: inline-flex;
	color: var(--wp--custom--color--link) !important;
}

/* 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;
}
