﻿/*
 * Innoverto 2026 - component styles.
 * Colors/typography verified directly against the Figma file via the
 * Figma MCP connector (file IRl6PZrZiUFErRnfqC3Ecs, frames 421:189 home,
 * 380:221 course page, 374:399 booking modal) - these are the exact hex
 * values used in the design, not estimated from screenshots.
 * Mirrors the tokens in theme.json (kept as literal hex here too since
 * Events Manager's own markup can't read CSS custom properties registered
 * only in Global Styles output). Update both places together if the
 * palette changes.
 */

:root {
	--color-navy-900: #0B1D2E;
	--color-navy-800: #16293D;
	--color-gold-500: #F6B426;
	--color-gold-600: #DDA015;
	--color-teal-600: #007DA5;
	--color-teal-700: #00637F;
	--color-heading-brown: #3D2413;
	--color-heading-slate: #303A4C;
	--color-neutral-900: #20272E;
	--color-neutral-600: #696969;
	--color-neutral-100: #F0F0F0;
	--color-neutral-200: #E4E7E9;
	--color-border-dark: #303A4C;
	--color-white: #FFFFFF;
	--color-danger: #C8102E;
	/* Width system: Full (100%, edge-to-edge) vs. Large/Small, both a flat
	   1300px - matches contentSize/wideSize in theme.json (settings.layout),
	   which drive the same Full/Wide/None options WordPress's native
	   block-alignment toolbar already offers on any block nested in a
	   "constrained" layout (most page content). Large and Small are
	   intentionally the same value: the header/footer bars align "wide"
	   while ordinary content sections are unaligned/"None", and both need
	   to land on the exact same width for them to visually line up (see the
	   MIGRATION.md note on the 2026-09 pass that fixed a header/content
	   width mismatch caused by Large and Small previously resolving to
	   different viewport-relative widths). These CSS custom properties +
	   the .width-full/-large/-small classes below are a manual fallback
	   with the same widths, for any spot that ends up outside a
	   constrained-layout ancestor (native alignment silently hides its
	   Wide/Full options there - WordPress only shows them when there's a
	   constrained parent to align against). The header/footer content rows
	   (site-header__top-inner, __nav-inner, footer-main, footer-side) used
	   to need this for exactly that reason, but now use real
	   "align":"wide"/"full" instead - their immediate bar wrapper was
	   changed to a "constrained" layout specifically so the native control
	   would show up in the toolbar (see MIGRATION.md v1.13). Add
	   "width-full", "width-large" or "width-small" as an Additional CSS
	   Class in the block editor only if you hit that same
	   non-constrained-parent case somewhere else. */
	--width-full: 100%;
	--width-large: 1300px;
	--width-small: 1300px;
	--radius-s: 10px;
	--radius-l: 14px;
	/* Minimal radius for buttons - a slight softening of the corner, not
	   a rounded/pill look. Matches the 6px already used to tone down the
	   wp-block-tab-list tabs' default 30px pill radius (see theme.json's
	   core/tabs block CSS + the .tab-row-start/-end overrides below). */
	--radius-btn: 6px;
}

/* Border-radius is opt-in only: nothing is rounded by default (except the
   home hero block below, which is hard-coded). Add "rounded-s" (10px) or
   "rounded-l" (14px) as an Additional CSS Class in the block editor to
   round any specific element - form fields and images typically want
   rounded-s, larger containers rounded-l. */
.rounded-s { border-radius: var(--radius-s); }
.rounded-l { border-radius: var(--radius-l); }

.width-full { max-width: var(--width-full); margin-left: 0; margin-right: 0; }
.width-large { max-width: var(--width-large); margin-left: auto; margin-right: auto; }
.width-small { max-width: var(--width-small); margin-left: auto; margin-right: auto; }

/* Added via the "Bold title" toggle on the Post Title block inside a Query
   Loop's post template - see assets/js/editor-query-loop.js. */
.bold-title { font-weight: 700; }

* { box-sizing: border-box; }
body { color: var(--color-neutral-900); }
h1, h2, h3, h4, h5, h6 { font-weight: 400; }
/* Headings never carry top spacing; only their bottom margin/padding applies.
   !important is needed to beat WordPress's flow-layout block-gap rules
   (":root :where(.is-layout-flow) > * + *") and per-block inline margins. */
h1, h2, h3, h4, h5, h6 { margin-top: 0 !important; padding-top: 0 !important; }
h1 { font-size: 2.5rem; line-height: 1.1; }
h2 { font-size: 2rem; line-height: 1.1; }
h3 { font-size: 1.5rem; }
h4 { font-size: 1.25rem; }
h5 { font-size: 1.125rem; }
h6 { font-size: 1rem; }
img { max-width: 100%; height: auto; display: block; }
a { transition: color .15s ease-out; }

.button, a.button, .wp-element-button {
	display: inline-block;
	background: var(--color-teal-600);
	color: var(--color-white) !important;
	padding: 0.85em 1.6em;
	font-weight: 700;
	text-decoration: none;
	border: 0;
	border-radius: var(--radius-btn);
	cursor: pointer;
}
.button:hover, a.button:hover, .wp-element-button:hover { background: var(--color-teal-700); }
.button--secondary { background: var(--color-gold-500); color: var(--color-navy-900) !important; }
.button--secondary:hover { background: var(--color-gold-600); }
/* a.button--block, not just .button--block: "a.button" above (0,1,1)
   out-specifies a bare class (0,1,0) and kept these inline-block, so each
   button shrink-wrapped to its own label instead of filling the sidebar. */
.button--block, a.button--block, .wp-element-button.button--block {
	display: block; width: 100%; box-sizing: border-box; text-align: center; margin-bottom: 1.5rem;
}

/* Outline variant - blue (teal-600) border/text on a transparent
   background, filling gold on hover. Used for the "Download the
   Brochure" CTA where it's paired with a solid "Book Now" button, so it
   reads as the secondary action of the pair. Padding is reduced by the
   border width so the button doesn't grow relative to solid buttons. */
.button--outline, a.button--outline, .wp-element-button.button--outline {
	background: transparent;
	color: var(--color-teal-600) !important;
	border: 2px solid var(--color-teal-600);
	padding: calc(0.85em - 2px) calc(1.6em - 2px);
}
.button--outline:hover, a.button--outline:hover, .wp-element-button.button--outline:hover {
	background: var(--color-gold-500);
	border-color: var(--color-gold-500);
	color: var(--color-navy-900) !important;
}

/* ---------- Header ----------
   Matches Figma component 328:83 exactly: one navy header block, two
   rows. Row 1: logo (left) / rating badge + phone + email (right).
   Row 2 (slightly lighter navy): nav links (left-of-center) / a
   search ICON that toggles a hidden input (right) - not a permanently
   visible search box.

   Full-bleed width: the header/footer template-parts use "align":"full"
   in every templates/*.html file, which is the correct WordPress-native
   way to opt a top-level block out of the site's default content-width
   constraint - these two specifically are meant to stay edge-to-edge
   (their navy background is the full-bleed "bar"; their own -inner
   children carry "alignwide" to box the actual logo/nav/etc content back
   to the normal 1300px, same "full-bleed bar, boxed content" pattern as
   the footer further down). This rule is a hard guarantee on top of
   that "align":"full" - if any other plugin/global-style CSS re-applies
   max-width to the header (e.g. via the generic ".is-layout-constrained
   > *" selector WordPress generates for constrained containers), this
   wins regardless, since it targets the element directly rather than
   relying on alignment classes alone.

   margin:calc(50% - 50vw) rather than a flat width:100%/margin:0: a flat
   0 margin only reaches the viewport edge if this element's own
   containing block happens to already start at x=0 - true here, since
   both are direct children of the body-level root. calc(50% - 50vw) is
   used anyway, matching .sticky-booking-bar further down (which does
   need it - that element sits one "constrained" layout deeper, inside
   <main class="course-page">), so both hard-guarantee rules use the same
   formula rather than two different techniques for the same job.

   .course-page (templates/single-event.html's <main>) is deliberately
   NOT in this list, unlike an earlier version of this rule: it has no
   background of its own (unlike the header/footer bars above), so unlike
   those two there's nothing visible to bleed - the only reason it was
   forced full-bleed was so .sticky-booking-bar could measure "100%" off
   of it, which .sticky-booking-bar's own calc(50% - 50vw) now does
   without needing its parent forced wide too (see that rule's comment).
   Leaving .course-page alone means it gets WordPress's normal max-width/
   centered behaviour for its own box, exactly like a general page's
   <main> - only its alignfull children (this bar, the booking modal)
   still bleed past that. */
.site-header, .site-footer {
	width: auto !important;
	max-width: none !important;
	margin-left: calc(50% - 50vw) !important;
	margin-right: calc(50% - 50vw) !important;
}
.site-header__top {
	background: var(--color-navy-900);
	min-height: 136px;
	display: flex;
	align-items: center;
}
/* Full-bleed navy bar, boxed content: the logo/rating/contact group stays
   centered at the site's normal content width. Width comes from
   WordPress's own None/Wide/Full block alignment now (this group is
   "align":"wide" by default in parts/header.html, and its parent
   .site-header__top is a "constrained" layout so that control actually
   shows up in its toolbar - a plain "default"-layout parent hides the
   Wide/Full options entirely, which is why this used to need the
   .width-large workaround class instead; see MIGRATION.md v1.13). Same
   "full-bleed bar, boxed content" pattern used by the nav bar and footer
   below. */
.site-header__top-inner {
	width: 100%;
	padding: 1rem 2rem;
	display: flex;
	align-items: center;
	justify-content: space-between;
}
.site-header__brand { display: flex; gap: 0.75rem; align-items: center; }
/* Once a real Site Logo image is set (Site Editor -> Design -> Logo),
   hide the text fallback so it doesn't double up with a logo that
   already contains the wordmark. The Figma logo asset is a full lockup
   (mark + "INNOVERTO" + tagline), so it's sized fairly large/tall. */
.site-header__brand:has(.wp-block-site-logo img) .site-header__title { display: none; }
.site-header__brand .wp-block-site-logo img { max-height: 100px; width: auto; }
.site-header__title,
.site-header__title a {
	color: var(--color-white) !important;
	font-weight: 700;
	font-size: 1.4rem;
	text-decoration: none;
}

.site-header__meta { display: flex; gap: 1.75rem; align-items: center; }
.header-rating { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; }
.header-rating__stars { color: var(--color-gold-500); font-size: 1rem; letter-spacing: 1px; }
.header-rating__text { color: var(--color-white); font-size: 0.75rem; text-align: center; line-height: 1.4; }
.site-header__contact { display: flex; flex-direction: column; gap: 0.35rem; align-items: flex-end; }
.header-contact-link { margin: 0; }
.header-contact-link a { color: var(--color-white) !important; font-size: 0.9rem; }
.header-contact-link a:hover { color: var(--color-gold-500) !important; }

.site-header__nav {
	background: var(--color-navy-800);
	/* <header>'s layout is "default" (flow), so WordPress's own block-gap
	   spacing applies between its two children (.site-header__top, then
	   this) via a generated ".site-header.is-layout-flow > * + *" rule -
	   that's the unwanted top margin, overridden back to 0 here.
	   padding-bottom is deliberate breathing room, not a reset: pages that
	   use the ".content-container" class (set via the block's own Advanced
	   panel in the editor, not in this theme's files) pull that content up
	   with a negative top margin so it slightly overlaps this bar - the
	   30px keeps the nav's own visible content clear of that overlap
	   instead of feeling cramped against it. */
	margin-top: 0 !important;
	padding-bottom: 25px;
}
/* The nav bar's background spans full width (.site-header__nav above),
   but its actual content - the menu + search icon - stays boxed at the
   site's normal content width (native "align":"wide", same mechanism/
   reasoning as .site-header__top-inner above) and centered, same
   "full-bleed bar, boxed content" pattern used in the footer. */
.site-header__nav-inner {
	width: 100%;
	min-height: 60px;
	padding: 0 2rem;
	display: flex;
	align-items: center;
	justify-content: space-between;
}
.site-header__nav .wp-block-navigation { min-height: 60px; align-items: center; }
.site-header__navigation,
.wp-block-navigation {
	--wp--custom--nav-link-color: var(--color-gold-500);
}
/* Core's default item gap (~2em, from .wp-block-navigation__container) is
   on top of each item's own link padding below, which is what made the
   menu feel far more spread out than the padding alone suggests. */
.site-header__navigation .wp-block-navigation__container {
	gap: 2rem;
}
.site-header__nav .wp-block-navigation-item > a,
.site-header__nav .wp-block-navigation-item > .wp-block-navigation-item__content {
	color: var(--color-gold-500) !important;
	font-weight: 500;
	padding: 0.85rem 0.75rem !important;
}
.site-header__nav .wp-block-navigation-item > a:hover { color: var(--color-white) !important; }

/* Submenu (dropdown) panel - same background as the navy nav bar it opens
   from, rather than core's default white panel, with tighter but still
   comfortable item padding than the top-level menu (that one has extra
   room since it doubles as the click target on a single horizontal bar;
   a vertical dropdown list doesn't need as much horizontal padding). */
.site-header__nav .wp-block-navigation__submenu-container {
	background: var(--color-navy-800) !important;
	min-width: 260px;
	padding-top: 12px !important;
}
.site-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item > a,
.site-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item > .wp-block-navigation-item__content {
	padding: 0.9rem 1.4rem !important;
}

/* No dropdown chevrons on the desktop bar - submenus open on hover/focus
   there anyway. Below 980px the chevron is the mobile menu's
   click-to-expand toggle, so it stays. */
@media (min-width: 980px) {
	.site-header__nav .wp-block-navigation-submenu__toggle,
	.site-header__nav .wp-block-navigation__submenu-icon { display: none !important; }
}

/* Mobile menu toggle (Figma frame 380:363 shows this at the LEFT of the
   nav row, with the search icon at the right, which is already the
   natural result of the header markup's flex order + justify-content).
   This is a hand-rolled button (parts/header.html) rather than core/
   navigation's own built-in "overlayMenu" dialog - that dialog had CSS
   bugs (missing close icon, misaligned close-button margin) that were
   hard to pin down without a live WP install to inspect, and it was
   fighting its own per-block inline breakpoint styles (see the removed
   max-width:979px/min-width:980px rules that used to override it with
   !important). The block's overlayMenu attribute is now "never" - see
   the .site-header__nav-toggle / .site-header__navigation rules below,
   grouped with the other max-width:979px mobile styles further down. */
.site-header__nav-toggle {
	display: none;
	background: none; border: 0; color: var(--color-gold-500); cursor: pointer;
	align-items: center; padding: 0.5rem;
}
.site-header__nav-toggle:hover { color: var(--color-white); }

/* Dimmed backdrop behind the mobile nav drawer (see the max-width:979px
   block below for the drawer itself). Rendered as a plain sibling <div>
   right after </nav> in parts/header.html - deliberately NOT a child of
   .site-header__nav, so the existing "click outside .site-header__nav
   closes the menu" listener in main.js already treats a click on this
   backdrop as an outside click and closes the drawer, with no extra JS
   needed. Base rule here keeps it fully inert (invisible, unclickable) at
   any width; only the max-width:979px block's sibling-combinator rule
   ever makes it visible, and only while the drawer is open. */
.site-header__nav-backdrop {
	position: fixed; inset: 0; z-index: 150;
	background: rgba(0,0,0,.5);
	opacity: 0; visibility: hidden; pointer-events: none;
	transition: opacity .3s ease, visibility 0s linear .3s;
}

/* Search icon + toggled input (form is hidden until the icon is clicked -
   see the .is-open toggle in assets/js/main.js) */
.header-search-toggle { position: relative; display: flex; align-items: center; }
.header-search-toggle__button {
	background: none; border: 0; color: var(--color-gold-500); cursor: pointer;
	display: flex; align-items: center; padding: 0.5rem;
}
.header-search-toggle__button:hover { color: var(--color-white); }
.header-search-toggle__field {
	position: absolute; top: 100%; right: 0; margin-top: 0.5rem;
	background: var(--color-white); box-shadow: 0 8px 24px rgba(0,0,0,.2);
	padding: 0.5rem; display: none;
	/* Without an explicit z-index this and the home banner (Cover block /
	   MetaSlider, both position:relative with z-index:auto) are painted in
	   DOM order within the same stacking context, so the banner - being
	   later in the markup - draws on top of this dropdown. A positive
	   z-index moves it into its own stacking layer, above the banner
	   regardless of source order. */
	z-index: 100;
}
.header-search-toggle.is-open .header-search-toggle__field { display: block; }
.header-search-toggle__field input[type="search"] {
	border: 1px solid var(--color-neutral-200); padding: 0.6em 1em; min-width: 220px;
}
.screen-reader-text {
	position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ---------- Home hero ----------
   The only element with a hard-coded radius; everything else uses the
   rounded-s/rounded-l utility classes above, added manually where needed. */
.home-hero { background: var(--color-gold-500); border-radius: var(--radius-l); overflow: hidden; }
.home-hero__copy h1 { color: var(--color-white); font-size: clamp(2rem, 4vw, 2.75rem); font-weight: 400; }
.home-hero__copy p { color: var(--color-heading-brown); font-size: 1.1rem; }
.home-hero__cta a { background: var(--color-white); color: var(--color-teal-600) !important; }
.home-hero__cta a:hover { background: var(--color-neutral-100); }
.home-hero__image { border-radius: var(--radius-l); overflow: hidden; }

/* MetaSlider ([metaslider id="3426"]) - the homepage slider, embedded
   directly in page content via the Site Editor rather than through the
   .home-hero Cover block above. Rounded at the same 14px used everywhere
   else, plus a shadow since it sits slightly above/overlapping the nav
   panel below it and needs the extra depth to read as its own layer
   rather than looking like it's colliding with the nav. */
.metaslider {
	border-radius: var(--radius-l);
	overflow: hidden;
	box-shadow: 0 12px 32px rgba(11, 29, 46, 0.25);
}

/* ---------- Sections ---------- */
/* Width comes from WordPress's own None/Wide/Full block alignment now
   (both .section and its parent <main> use layout:"constrained", so an
   unaligned .section already gets theme.json's contentSize/wideSize
   automatically) - no fixed max-width needed here any more. Use the
   block's alignment toolbar (or the width-full/-large/-small classes,
   see :root above) to change an individual section's width. */
.section { padding: 3rem 1rem; }
.section--grey { max-width: none; background: var(--color-neutral-100); }
.section h2 { color: var(--color-heading-brown); font-weight: 400; }
.section--grey h3 { color: var(--color-heading-slate); font-weight: 400; }

/* ---------- Upcoming courses / course cards ---------- */
.upcoming-courses__nav { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; }
.upcoming-courses__nav button {
	background: var(--color-neutral-100);
	border: 1px solid var(--color-neutral-200);
	width: 2.25rem;
	height: 2.25rem;
	cursor: pointer;
	font-size: 1.25rem;
}

.course-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--card-gap, 24px);
}
.course-grid--carousel { grid-template-columns: none; } /* JS turns this into a Slick track */
/* Once Slick initializes, the actual cards move inside .slick-track as
   floated .slick-slide items - CSS Grid's own "gap" on .course-grid no
   longer has any effect on them (the grid then has a single child, the
   .slick-list wrapper), so the same --card-gap value is applied as
   half-margin on each slide instead, with a matching negative margin on
   .slick-list so the first/last card still line up with the container
   edges (the standard Slick "gutter" technique). */
.course-grid--carousel .slick-list {
	margin: 0 calc(var(--card-gap, 24px) / -2);
}
.course-grid--carousel .slick-slide {
	margin: 0 calc(var(--card-gap, 24px) / 2);
}

/* Plain image + text card, no box/border/shadow chrome around it - just
   a rounded thumbnail with the title/dates/location stacked underneath. */
.course-card__link { color: inherit; display: block; }
.course-card__thumb {
	position: relative; aspect-ratio: var(--card-aspect, 3/2); overflow: hidden;
	border-radius: var(--radius-s); background: var(--color-neutral-100);
	transition: opacity .15s ease-out;
}
.course-card:hover .course-card__thumb { opacity: .85; }
.course-card__thumb img { width: 100%; height: 100%; object-fit: cover; }
.course-card__badge {
	position: absolute; top: .5rem; left: .5rem;
	font-size: .7rem; font-weight: 700; text-transform: uppercase;
	padding: .3em .6em; color: var(--color-white);
	background: var(--color-danger);
	border-radius: var(--radius-s);
}
/* The Query Loop-based card (see the "Course Card" pattern in inc/blocks.php)
   renders this via a Paragraph bound to innoverto/event-badge, which is
   empty when the event isn't sold-out/limited - hide it entirely rather
   than showing an empty pill. The legacy PHP-rendered card
   (innoverto_course_card()) never emits the tag at all when there's no
   badge, so this is a no-op there. */
.course-card__badge:empty { display: none; }
.course-card__body { padding: .85rem 0 0; }
.course-card__title { font-size: 1rem; margin: 0 0 .5rem; color: var(--color-teal-600); font-weight: 700; line-height: 1.35; }
.course-card__meta { font-size: .85rem; color: var(--color-neutral-900); font-weight: 400; display: flex; flex-direction: column; gap: .3rem; }
.course-card__excerpt { font-size: .85rem; color: var(--color-neutral-600); margin: .5rem 0 0; }
/* Badge with no thumbnail to overlay (innoverto_course_card()'s show_image
   off) - an inline pill above the title instead. */
.course-card__body > .course-card__badge { position: static; display: inline-block; margin-bottom: .5rem; }

.important-links { text-align: center; background: var(--color-gold-500); padding: 1rem; margin-top: 2rem; display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem 1.5rem; }
.important-links a { color: var(--color-white); font-weight: 700; text-decoration: none; white-space: nowrap; }
.important-links a:hover { color: var(--color-navy-900); }

/* ---------- Filterable course grid ---------- */
/* Desktop/mobile column counts are per-block controls (see "Columns" in
   assets/js/editor-blocks.js -> --grid-columns-desktop/-mobile custom
   properties set inline by innoverto_render_filterable_courses() in
   inc/course-cards.php, and the same controls on the Course Catalogue
   (card layout) and Past Courses blocks, which both render
   .course-catalogue--cards) - scoped to those wrappers so this doesn't
   affect the other .course-grid usages (carousel, All Courses Grid,
   category archives), which keep their fixed column counts below. */
.course-filter-block .course-grid,
.course-catalogue--cards .course-grid { grid-template-columns: repeat(var(--grid-columns-desktop, 4), 1fr); }
@media (max-width: 600px) {
	/* :not(.course-grid--carousel) is only there for specificity - it has
	   to beat the generic ".course-grid:not(.course-grid--carousel)" 1fr
	   rule in the 600px block further down, which otherwise wins by
	   coming later and silently ignores the "Columns (mobile)" setting. */
	.course-filter-block .course-grid:not(.course-grid--carousel),
	.course-catalogue--cards .course-grid:not(.course-grid--carousel) { grid-template-columns: repeat(var(--grid-columns-mobile, 1), 1fr); }
}
.course-filter {
	display: flex; flex-wrap: wrap; align-items: flex-end; gap: 1rem 1.5rem;
	margin-bottom: 2rem;
}
.course-filter__field { display: flex; flex-direction: column; gap: .35rem; flex: 1 1 200px; min-width: 160px; }
.course-filter__field label { font-weight: 700; font-size: .85rem; color: var(--color-neutral-900); }
.course-filter__field select {
	width: 100%; padding: .6em .75em; border: 1px solid var(--color-neutral-200);
	background: var(--color-white); font-size: .95rem; font-family: inherit;
	color: var(--color-neutral-900);
}
.course-filter__reset { flex: 0 0 auto; }
.js-course-filter-results[aria-busy="true"] { opacity: .5; pointer-events: none; }
.course-filter__empty { color: var(--color-neutral-600); font-style: italic; }

/* ---------- Course catalogue ---------- */
/* innoverto_render_course_catalogue() in inc/course-cards.php - one
   section per event category, as either a title list or a .course-grid. */
.course-catalogue__filter { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .35rem 1rem; margin-bottom: 2rem; }
.course-catalogue__filter-label { flex: 0 0 100%; font-weight: 700; font-size: .85rem; color: var(--color-neutral-900); }
.course-catalogue__reset { flex: 0 0 auto; }
/* .button sets display:inline-block, which would otherwise beat [hidden]. */
.course-catalogue__reset[hidden] { display: none; }

/* Multi-select dropdown (initCourseCatalogueFilter() in assets/js/main.js):
   styled to match the .course-filter__field select boxes, with the chosen
   options shown as removable tags inside the field. */
.multi-select { position: relative; flex: 0 1 420px; min-width: 240px; }
.multi-select__control {
	display: flex; flex-wrap: wrap; align-items: center; gap: .35rem;
	min-height: 2.6rem; padding: .3em 2.25em .3em .5em;
	border: 1px solid var(--color-neutral-200); background: var(--color-white);
	cursor: pointer; position: relative;
}
.multi-select__control::after {
	content: ""; position: absolute; right: .9em; top: 50%;
	width: .45em; height: .45em; margin-top: -.3em;
	border-right: 2px solid var(--color-neutral-600); border-bottom: 2px solid var(--color-neutral-600);
	transform: rotate(45deg); pointer-events: none;
}
.multi-select.is-open .multi-select__control { border-color: var(--color-teal-600); }
.multi-select__tags { display: contents; }
.multi-select__tag {
	display: inline-flex; align-items: center; gap: .3em;
	padding: .2em .3em .2em .6em; font-size: .85rem;
	background: var(--color-teal-600); color: var(--color-white);
	border-radius: var(--radius-btn);
}
.multi-select__tag button {
	border: 0; background: none; color: inherit; cursor: pointer;
	font-size: 1rem; line-height: 1; padding: 0 .2em;
}
.multi-select__toggle {
	flex: 1 1 4rem; border: 0; background: none; cursor: pointer;
	text-align: left; font: inherit; font-size: .95rem; color: var(--color-neutral-900);
	padding: .25em; min-height: 1.8rem;
}
.multi-select__panel {
	position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; right: 0;
	max-height: 18rem; overflow-y: auto;
	background: var(--color-white); border: 1px solid var(--color-neutral-200);
	box-shadow: 0 8px 24px rgba(11, 29, 46, .12); padding: .35rem 0;
}
.multi-select__panel[hidden] { display: none; }
.multi-select__option {
	display: flex; align-items: center; gap: .6em;
	padding: .45em .9em; cursor: pointer; font-size: .95rem;
}
.multi-select__option:hover { background: var(--color-neutral-100); }
.multi-select__option input { accent-color: var(--color-teal-600); margin: 0; }
.course-catalogue__category[hidden] { display: none; }
/* :not([hidden]) so spacing still works when earlier sections are filtered out. */
.course-catalogue__category:not([hidden]) ~ .course-catalogue__category:not([hidden]) { margin-top: 2.5rem; }
.course-catalogue__heading {
	font-size: 1.6rem; margin: 0 0 1rem; padding-bottom: .5rem;
	border-bottom: 1px solid var(--color-neutral-200);
	color: var(--color-heading-slate);
}
.course-catalogue__heading a, .wp-block-post-content .course-catalogue__heading a { color: var(--color-navy-800); text-decoration: none; }
.course-catalogue__heading a:hover { color: var(--color-teal-600); }
.course-catalogue__list {
	list-style: none; margin: 0; padding: 0;
	columns: 2 280px; column-gap: 2rem;
}
.course-catalogue__list li { break-inside: avoid; padding: .35rem 0; }
.course-catalogue__list a { color: var(--color-teal-600); text-decoration: none; }
.course-catalogue__list a:hover { text-decoration: underline; }

/* ---------- News / Past Trainings ---------- */
.news-past-trainings { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; }
.news-past-trainings h3 { color: var(--color-heading-slate); }
.news-list, .past-trainings-list { list-style: none; margin: 0; padding: 0; }
.news-list li, .past-trainings-list li { display: flex; gap: 1rem; margin-bottom: 1.5rem; }
.news-list a, .past-trainings-list a { display: flex; gap: 1rem; color: inherit; }
.news-list__thumb, .past-trainings-list__thumb { flex: 0 0 140px; border-radius: var(--radius-s); overflow: hidden; }
.news-list__thumb img, .past-trainings-list__thumb img { width: 140px; height: 86px; object-fit: cover; }
.news-list__body h5, .past-trainings-list__body h5 { margin: 0 0 .35rem; color: var(--color-teal-600); font-weight: 700; font-size: 1rem; }
.news-list__body p { margin: 0; font-size: .9rem; color: var(--color-neutral-900); }
.past-trainings-list__body .dates { font-size: .85rem; color: var(--color-neutral-900); }

/* ---------- Why Innoverto ---------- */
.why-innoverto { text-align: left; }
.why-innoverto h2 { color: var(--color-heading-brown); }
.why-innoverto__image { overflow: hidden; margin: 2rem 0; }
.clients-carousel { display: flex; align-items: center; justify-content: center; gap: 3rem; flex-wrap: wrap; }
/* Each logo is a core/image block (<figure class="wp-block-image">) now,
   not a custom .clients-carousel__logo wrapper - see the InnerBlocks-based
   registerBlockType() for 'innoverto/clients-carousel' in editor-blocks.js. */
.clients-carousel .wp-block-image img { max-height: 50px; width: auto; filter: grayscale(1); opacity: .75; }
.clients-carousel .wp-block-image img:hover { filter: none; opacity: 1; }

/* ---------- Course page ---------- */
.course-page__layout { gap: 3rem; margin-top: 1.5rem; }
.course-page .wp-block-post-title { color: var(--color-heading-brown); font-size: clamp(1.75rem, 3vw, 2.8rem); font-weight: 400; }
.breadcrumbs { font-size: .9rem; color: var(--color-neutral-900); margin-bottom: 1rem; }
.breadcrumbs a { color: var(--color-teal-600); }

.course-header-actions {
	display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
	gap: 1rem; background: var(--color-neutral-100); padding: 1rem 1.5rem; margin: 1rem 0 2rem;
}
.course-header-actions__meta { list-style: none; margin: 0; padding: 0; display: flex; gap: 2rem; flex-wrap: wrap; }
.course-header-actions__sold-out { font-weight: 700; text-transform: uppercase; color: var(--color-danger); }

/* Course content tabs (core/tabs, and [wptabs] via
   innoverto_shortcode_wptabs() - inc/shortcodes.php): horizontal
   wrapping gold/teal pill row, one continuous rounded bar per visual row
   (per direct reference screenshot of the old shortcode-based tabs).
   This used to live in theme.json's styles.blocks.core/tabs.css, but
   confirmed live (view-source, searched for the F6B426 gold hex - not
   present anywhere in the page) that WordPress's compiled Global Styles
   output isn't actually reaching the page on this install, for reasons
   still unconfirmed - most likely a saved Global Styles customization in
   the database (Site Editor -> Styles) taking full precedence over
   theme.json's file, same category of issue as the template-part
   database-override case, or a page-cache/CDN layer. Moved here instead
   since assets/css/style.css is confirmed reliably delivered (it's what
   actually styles everything else on the site). Row/column rounding
   (tab-row-start/-end) is applied by initTabRowRounding() in
   assets/js/main.js, which groups tabs by their rendered row since plain
   CSS can't detect flex-wrap line breaks on its own. */
.wp-block-tab-list { border-bottom: 0; gap: 8px 0; flex-wrap: wrap; }
.wp-block-tab-list button[role=tab] {
	font-family: inherit; font-weight: 600;
	background: var(--color-gold-500); color: var(--color-white);
	padding: 0.85rem 1.5rem; border: 0; margin: 0; cursor: pointer;
}
.wp-block-tab-list button[role=tab][aria-selected=true] { background: var(--color-teal-600); color: var(--color-white); }
.wp-block-tab-list button[role=tab].tab-row-start { border-top-left-radius: 6px; border-bottom-left-radius: 6px; }
.wp-block-tab-list button[role=tab].tab-row-end { border-top-right-radius: 6px; border-bottom-right-radius: 6px; }
.wp-block-tab-panel { padding-top: 1.5rem; }

.course-page .wp-block-tabs { margin: 1.5rem 0; }
.course-page .wp-block-tab-panel h2, .course-page .wp-block-tab-panel h3 { font-weight: 400; font-size: 1.4rem; }

.course-sidebar { position: sticky; top: 2.5rem; }
.course-sidebar__label { font-weight: 700; text-transform: uppercase; font-size: .8rem; letter-spacing: .04em; color: var(--color-neutral-900); }
/* FindCourses reviews widget (innoverto_render_findcourses_widget()). */
.course-sidebar__reviews { margin: 1.5rem 0 2rem; }
.course-sidebar__reviews:empty { display: none; }
.course-sidebar__crosssell { border: 1px solid var(--color-neutral-200); padding: 1rem; margin-bottom: 2rem; }
.course-sidebar__upcoming ul { list-style: none; margin: 0 0 1rem; padding: 0; }
.course-sidebar__upcoming li { padding: .75rem 0; border-bottom: 1px solid var(--color-neutral-200); }
.course-sidebar__upcoming li a { color: var(--color-teal-600); font-weight: 700; }
.course-sidebar__upcoming li span { display: block; font-size: .8rem; color: var(--color-neutral-900); }
.course-sidebar__all { font-weight: 700; color: var(--color-teal-600); }
/* .specialListRight - legacy class on a list in the sidebar widget content
   (Appearance -> Widgets, not this theme's markup) - reset to a bare list. */
.specialListRight, ul.menu,
.specialListRight li, ul.menu li { list-style: none; margin: 0; padding: 0; }
.specialListRight li, ul.menu li {margin-bottom:6px;}
.download-brochure, .course-enquiry {
	background: var(--color-neutral-100); padding: 2rem; margin: 2rem 0; border-radius: var(--radius-l);
}
/* Course enquiry form (non-bookable courses) sits straight in the booking
   modal's white dialog - no grey card inside the card. */
.booking-modal .course-enquiry { background: none; padding: 0; margin: 0; border-radius: 0; }
.download-brochure h2 { font-weight: 400; }
/* Target of the "Download the Brochure" buttons - land with a little room
   above rather than flush with the viewport edge. */
#download-brochure { scroll-margin-top: 1.5rem; }
/* Download links revealed under the form after a successful submit
   (main.js initBrochureDownloads). */
.download-brochure__files {
	margin-top: 1.5rem; padding: 1.25rem; background: var(--color-white);
	border-left: 4px solid var(--color-teal-600); border-radius: var(--radius-s);
}
.download-brochure__files[hidden] { display: none; }
.download-brochure__files-title { margin: 0 0 .5rem; font-weight: 700; }
.download-brochure__files ul { margin: 0; padding: 0; list-style: none; }
.download-brochure__files li + li { margin-top: .4rem; }
.download-brochure__files a { color: var(--color-teal-600); font-weight: 700; text-decoration: underline; }
.download-brochure__files a::before { content: "\2193\00a0"; text-decoration: none; display: inline-block; }

/* Forminator forms - site-wide, so any Forminator form (the brochure
   download block, the bespoke-training enquiry on /board-training/, a
   per-course enquiry_form override...) gets the same field boxes as the
   booking form (.booking-field further down). The forms themselves are
   built/edited in wp-admin -> Forminator, not in this theme, so this only
   targets Forminator's own markup/class names - re-check these selectors
   if a form is rebuilt with a different field layout.

   Forms set to Forminator's design "None" (data-design="none") ship no
   plugin CSS at all, so the row/column layout is supplied here too:
   rows are flex, Forminator's .forminator-col-N columns share the row,
   and they stack at the 900px breakpoint alongside .booking-fields. */
.download-brochure form.forminator-custom-form,
.course-enquiry form.forminator-custom-form {
	margin-top: 1.5rem;
}
.forminator-custom-form .forminator-row {
	display: flex;
	gap: 1rem;
	margin: 0 0 1rem;
}
.forminator-custom-form .forminator-row-last { margin-bottom: 0; }
.forminator-custom-form .forminator-col { flex: 1 1 0; min-width: 0; }
/* Forminator's "Post Data" field type (hidden, just captures post
   context) - hide its row entirely rather than let it sit as an empty
   half of a pair. */
.forminator-custom-form .forminator-row:has(.forminator-field-postdata) {
	display: none;
}
.forminator-custom-form .forminator-response-message[aria-hidden="true"] {
	display: none;
}
.forminator-custom-form .forminator-response-message:not([aria-hidden="true"]) {
	margin: 0 0 1rem;
	padding: .75rem 1rem;
	border-radius: var(--radius-s);
	background: var(--color-white);
	border-left: 4px solid var(--color-teal-600);
}
.forminator-custom-form .forminator-response-message.forminator-error { border-left-color: #c0392b; }

/* Field boxes: label sits overlaid on the input like a placeholder at
   rest, then shrinks and floats up to the top edge of the field (rather
   than fading out) once the field has focus or a value, so the field
   name stays visible above the input while typing. Forminator renders
   placeholder="" (which never counts as :placeholder-shown), so
   main.js initForminatorPlaceholders() swaps those for " ".

   !important throughout this block: forms using one of Forminator's own
   designs ship a default plugin stylesheet for this exact markup (grey
   filled `.forminator-input` boxes, stacked label-above-input), and
   depending on enqueue order it can load after (and/or match with equal
   specificity to) plain class selectors here - this is the same
   "fighting a third-party plugin's own CSS" situation as the
   .site-header/.site-footer hard guarantee further up this file, same
   fix.

   :not(:has(.forminator-button-submit)) excludes the submit button's own
   wrapper - Forminator wraps every field type, the button included, in a
   .forminator-field div, so without this the button would get the same
   white box + border as the text inputs. */
.forminator-custom-form .forminator-field:not(:has(.forminator-button-submit)) {
	position: relative !important;
	background: var(--color-white) !important;
	border: 1px solid var(--color-border-dark) !important;
}
.forminator-custom-form .forminator-label {
	position: absolute !important;
	left: .75em;
	top: 50%;
	transform: translateY(-50%);
	transform-origin: left center;
	margin: 0 !important;
	padding: 0 .3em;
	background: var(--color-white);
	color: var(--color-neutral-600) !important;
	font-weight: 400 !important;
	font-size: 1rem;
	line-height: 1.2;
	pointer-events: none;
	z-index: 2;
	transition: transform .15s ease-out, color .15s ease-out;
}
/* Textareas: label rests on the first line, not the vertical middle. */
.forminator-custom-form .forminator-field:has(textarea) .forminator-label { top: 1.45em; }
.forminator-custom-form .forminator-required { color: #c0392b !important; }
.forminator-custom-form .forminator-field:focus-within .forminator-label,
.forminator-custom-form .forminator-field:has(.forminator-input:not(:placeholder-shown), textarea:not(:placeholder-shown)) .forminator-label {
	top: 0;
	transform: translateY(-50%) scale(.78);
	color: var(--color-neutral-900) !important;
}
.forminator-custom-form .forminator-input,
.forminator-custom-form select.forminator-input,
.forminator-custom-form textarea {
	position: relative;
	z-index: 1;
	display: block;
	width: 100% !important;
	margin: 0;
	border: 0 !important;
	border-radius: 0;
	background: transparent !important;
	font-family: inherit;
	font-size: 1rem;
	color: inherit;
}
/* Not inside .iti - see the international phone field rules below. */
.forminator-custom-form .forminator-input:not(.iti *),
.forminator-custom-form textarea {
	padding: .85em .75em !important;
}
.forminator-custom-form .forminator-input:focus,
.forminator-custom-form textarea:focus { outline: none; }
/* International phone field (Forminator's intl-tel-input, which wraps the
   input in .iti with the country flag/dial-code button on the left):
   - the label stays floated on the top border, since resting in the
     middle it would sit on top of the flag;
   - padding-left is handed back to the plugin, which sizes it to fit the
     flag (and dial code, when shown separately) - the !important padding
     shorthand above would otherwise put the typed number under the flag;
   - the flag button and its country list are lifted above the input
     (z-index 1 above) and the labels of the fields below it. */
.forminator-custom-form .forminator-field:has(.iti) .forminator-label {
	top: 0;
	transform: translateY(-50%) scale(.78);
}
.forminator-custom-form .iti { display: block; width: 100%; }
.forminator-custom-form .iti .forminator-input {
	padding-top: .85em !important;
	padding-right: .75em !important;
	padding-bottom: .85em !important;
}
.forminator-custom-form .iti__flag-container,
.forminator-custom-form .iti__country-container { z-index: 3; }
.forminator-custom-form .iti__country-list,
.forminator-custom-form .iti__dropdown-content { z-index: 10; }
.forminator-custom-form .forminator-field:not(:has(.forminator-button-submit)):focus-within {
	border-color: var(--color-teal-600) !important;
	box-shadow: 0 0 0 1px var(--color-teal-600);
}
.forminator-custom-form textarea {
	min-height: var(--forminator-textarea-min-height, 140px);
	padding-bottom: 1.75em !important; /* clear the character counter */
	resize: vertical;
}
/* Character counter ("0 / 180") - Forminator puts it between the label
   and the textarea; pin it to the bottom-right corner inside the box. */
.forminator-custom-form .forminator-field > div:has(> .forminator-description) {
	position: absolute;
	right: .75em;
	bottom: .4em;
	z-index: 2;
	pointer-events: none;
}
.forminator-custom-form .forminator-description {
	font-size: .75rem;
	color: var(--color-neutral-600);
}
/* Inline validation errors hang just below the box. */
.forminator-custom-form .forminator-has_error .forminator-field,
.forminator-custom-form .forminator-field:has(.forminator-error-message) { border-color: #c0392b !important; margin-bottom: 1.25rem; }
.forminator-custom-form .forminator-error-message {
	position: absolute; left: 0; top: 100%; margin-top: .25rem;
	font-size: .8rem; line-height: 1.3; color: #c0392b;
}
.forminator-custom-form .forminator-button-submit {
	display: inline-block;
	background: var(--color-teal-600) !important;
	color: var(--color-white) !important;
	padding: 0.85em 1.6em !important;
	font-weight: 700 !important;
	font-family: inherit;
	font-size: 1rem;
	border: 0 !important;
	border-radius: var(--radius-btn) !important;
	cursor: pointer;
}
.forminator-custom-form .forminator-button-submit:hover { background: var(--color-teal-700) !important; }

/* Old download form pasted into course content (and its divider) -
   hidden rather than removed from every course by hand. Scoped to the
   course content column: inc/booking-ajax.php's legacy show_course
   endpoint also outputs a .registerFrame. */
.course-page__main .registerFrame,
.course-page__main .horizontalContentDivider2 { display: none !important; }

/* Contact Form 7 download form (CF7 #208 + Email Before Download) -
   TEMPORARY: back in use on courses whose content hasn't been moved to
   the download_file* fields yet (see innoverto_render_download_brochure()).
   Delete this block once nothing uses it. Styled to match the booking /
   Forminator field boxes above; keyed off EBD's .downloadform wrapper so
   other CF7 forms are untouched.

   Markup per field: .formHolder > p > label + span.wpcf7-form-control-wrap
   > input. The <p> is the box; the label floats over it like the others.
   CF7 inputs have no placeholder, so main.js
   initFloatingLabelPlaceholders() adds placeholder=" " for the
   :placeholder-shown check. */
.wpcf7:has(.downloadform):not(.download-brochure .wpcf7, .course-enquiry .wpcf7) {
	background: var(--color-neutral-100); padding: 2rem; margin: 2rem 0; border-radius: var(--radius-l);
}
/* Dynamic hidden "post title" field - only ever hidden inputs (or, with
   its plugin inactive, the raw shortcode text), so never worth a line.
   !important: EBD's inline script jQuery-.show()s every form child once
   a file is ticked, which writes an inline display over this. */
.wpcf7-form:has(.downloadform) > p:first-of-type { display: none !important; }

/* File checkboxes (EBD) - picking one reveals the rest of the form. */
.wpcf7-form .ebd_input {
	display: flex; align-items: center; gap: .6rem;
	margin: 0 0 .6rem; font-weight: 700; cursor: pointer;
}
.wpcf7-form .ebd_input input[type="checkbox"] {
	accent-color: var(--color-teal-600); width: 20px; height: 20px; flex-shrink: 0; margin: 0;
}

.wpcf7-form .downloadform {
	display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; margin-top: 1rem;
}
.wpcf7-form .downloadfiles:not(:has(*)),
.wpcf7-form .horizontalContentDivider { display: none; }
.wpcf7-form .downloadfiles { grid-column: 1 / -1; }
.wpcf7-form .dis10 { height: 1rem; }
.wpcf7-form .formHolder { min-width: 0; }
.wpcf7-form .formHolder > p { margin: 0; }
.wpcf7-form .imp, .wpcf7-form .notimp { font-size: .85em; }
.wpcf7-form .imp { color: #c0392b; }
.wpcf7-form .notimp { color: var(--color-neutral-600); }

/* Floating-label boxes. */
.wpcf7-form .formHolder > p:has(> label + .wpcf7-form-control-wrap) {
	position: relative;
	background: var(--color-white);
	border: 1px solid var(--color-border-dark);
}
.wpcf7-form .formHolder > p:has(> label + .wpcf7-form-control-wrap):focus-within {
	border-color: var(--color-teal-600);
	box-shadow: 0 0 0 1px var(--color-teal-600);
}
.wpcf7-form .formHolder > p > label:has(+ .wpcf7-form-control-wrap) {
	position: absolute;
	left: .75em;
	top: 50%;
	transform: translateY(-50%);
	transform-origin: left center;
	margin: 0;
	padding: 0 .3em;
	background: var(--color-white);
	color: var(--color-neutral-600);
	font-weight: 400;
	font-size: 1rem;
	line-height: 1.2;
	white-space: nowrap;
	pointer-events: none;
	z-index: 2;
	transition: transform .15s ease-out, color .15s ease-out;
}
.wpcf7-form .formHolder > p:focus-within > label:has(+ .wpcf7-form-control-wrap),
.wpcf7-form .formHolder > p:has(input:not([type="hidden"]):not(:placeholder-shown)) > label:has(+ .wpcf7-form-control-wrap) {
	top: 0;
	transform: translateY(-50%) scale(.78);
	color: var(--color-neutral-900);
}
/* CF7's own stylesheet makes the wrap position:relative, which would
   anchor the error tip inside the box instead of below it. */
.wpcf7-form .formHolder > p > .wpcf7-form-control-wrap { position: static; display: block; }
.wpcf7-form .formHolder > p > .wpcf7-form-control-wrap input {
	position: relative;
	z-index: 1;
	display: block;
	width: 100%;
	margin: 0;
	padding: .85em .75em;
	border: 0;
	border-radius: 0;
	background: transparent;
	font-family: inherit;
	font-size: 1rem;
	color: inherit;
}
.wpcf7-form .formHolder > p > .wpcf7-form-control-wrap input:focus { outline: none; }

/* Fields whose label wraps the input instead (the CAPTCHA): label above,
   boxed input below. */
.wpcf7-form .formHolder label:has(.wpcf7-form-control-wrap) { display: block; font-size: .9rem; }
.wpcf7-form .formHolder label .wpcf7-form-control-wrap { display: block; margin-top: .5rem; }
.wpcf7-form .formHolder label .wpcf7-form-control-wrap input {
	width: 100%; max-width: 320px; padding: .85em .75em; border: 1px solid var(--color-border-dark);
	background: var(--color-white); font-family: inherit; font-size: 1rem;
}

/* Validation: box goes red, message hangs just below it. */
.wpcf7-form .formHolder > p:has(.wpcf7-not-valid) { border-color: #c0392b; margin-bottom: 1.25rem; }
.wpcf7-form .formHolder > p .wpcf7-not-valid-tip {
	position: absolute; left: 0; top: 100%; margin-top: .25rem;
	font-size: .8rem; line-height: 1.3; color: #c0392b;
}
.wpcf7-form .formHolder label .wpcf7-not-valid-tip { position: static; margin-top: .35rem; font-size: .8rem; color: #c0392b; }

.wpcf7-form .formHolderSubmit p { margin: 0; display: flex; align-items: center; gap: .75rem; }
.wpcf7-form .wpcf7-submit {
	display: inline-block;
	background: var(--color-teal-600);
	color: var(--color-white);
	padding: .85em 1.6em;
	font-weight: 700;
	font-family: inherit;
	font-size: 1rem;
	border: 0;
	border-radius: var(--radius-btn);
	cursor: pointer;
}
.wpcf7-form .wpcf7-submit:hover { background: var(--color-teal-700); }
.wpcf7-form .wpcf7-spinner { margin: 0; }

/* Response banner - same look as the Forminator one. Extra classes to
   outrank CF7's own `.wpcf7 form.invalid .wpcf7-response-output` etc. */
.wpcf7 form.wpcf7-form .wpcf7-response-output {
	margin: 1rem 0 0;
	padding: .75rem 1rem;
	border: 0;
	border-left: 4px solid var(--color-teal-600);
	border-radius: var(--radius-s);
	background: var(--color-white);
}
.wpcf7 form.wpcf7-form.invalid .wpcf7-response-output,
.wpcf7 form.wpcf7-form.unaccepted .wpcf7-response-output,
.wpcf7 form.wpcf7-form.payment-required .wpcf7-response-output,
.wpcf7 form.wpcf7-form.failed .wpcf7-response-output,
.wpcf7 form.wpcf7-form.aborted .wpcf7-response-output,
.wpcf7 form.wpcf7-form.spam .wpcf7-response-output { border-left-color: #c0392b; }

/* ---------- Sticky booking bar ----------
   Docked to the bottom of the viewport on a course page: session
   (date/location) tabs + Early Bird / Standard Pricing / Date & Location
   summary + "More Dates" + a "Book Now" trigger that opens the full
   booking-modal. Matches Figma frame 380:221 "Group 50".

   Full-bleed width: this block is "align":"full" (see the
   innoverto/sticky-booking-bar usage in templates/single-event.html),
   inside the <main class="course-page"> group's own "constrained" layout
   (which keeps the columns/content boxed at the normal content width;
   only alignfull children like this bar bleed past it - .course-page
   itself stays at its normal max-width/centered size, same as any other
   page's <main>). The margin:calc(50% - 50vw) hard guarantee below is
   the same self-correcting negative-margin formula WordPress's own
   alignfull CSS uses (see the .site-header/.site-footer rule's comment
   further up this file) - self-correcting specifically means it doesn't
   matter that .course-page isn't forced full-width: the formula measures
   off of whatever (centered) box this bar actually sits in and pulls it
   out to the true viewport edge regardless, rather than needing a flat
   width:100%/margin:0 off an already-full-width parent. */
.sticky-booking-bar {
	position: sticky; bottom: 0; z-index: 40; background: var(--color-white);
	box-shadow: 0 0 47px 9px rgba(0,0,0,.11);
	padding: 1.25rem 1.75rem; margin-top: 2rem;
	width: auto !important; max-width: none !important;
	margin-left: calc(50% - 50vw) !important; margin-right: calc(50% - 50vw) !important;
}
/* "More Dates and Locations" <details> under the booking info + button:
   the full session list (current one highlighted, all in start-date
   order) - each row links to that session's own event page. */
.sticky-booking-bar__more-sessions { margin-top: 1rem; border-top: 1px solid var(--color-neutral-200); }
.sticky-booking-bar__more-sessions summary {
	display: flex; justify-content: space-between; align-items: center;
	padding-top: .85rem; font-weight: 700; cursor: pointer; list-style: none;
}
.sticky-booking-bar__more-sessions summary::-webkit-details-marker { display: none; }
.sticky-booking-bar__more-sessions summary::after {
	content: "\25BE"; margin-left: .75rem; transition: transform .25s ease;
}
.sticky-booking-bar__more-sessions[open] summary::after { transform: rotate(180deg); }
.sticky-booking-bar__sessions {
	display: flex; flex-direction: column; margin-top: .5rem;
	max-height: 40vh; overflow-y: auto;
}
.sticky-booking-bar__session {
	display: flex; justify-content: space-between; align-items: center; gap: 1rem;
	padding: .85rem .75rem; line-height: 1.4; text-decoration: none;
	color: var(--color-neutral-900); border-bottom: 1px solid var(--color-neutral-200);
}
.sticky-booking-bar__session:last-child { border-bottom: 0; }
.sticky-booking-bar__session small { font-weight: 400; color: var(--color-neutral-600); }
.sticky-booking-bar__session.is-active {
	background: var(--color-neutral-100); color: var(--color-teal-600); font-weight: 700;
}
.sticky-booking-bar__pricing { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1.5rem; }
.sticky-booking-bar__pricing-group { display: flex; align-items: flex-start; gap: 2.5rem; flex-wrap: wrap; }
.sticky-booking-bar__price-label { font-weight: 700; font-size: 1.1rem; margin: 0 0 .2rem; }
.sticky-booking-bar__price-value .excl-vat { color: var(--color-neutral-600); font-size: .85rem; }
/* Base-currency equivalent of a course priced in another currency (inc/currency.php). */
.sticky-booking-bar__price-value .price-converted { display: block; color: var(--color-neutral-600); font-size: .85rem; font-weight: 400; }
.ticketprice .price-converted { color: var(--color-neutral-600); font-size: .85em; font-weight: 400; }
.sticky-booking-bar__more-dates { font-weight: 700; color: var(--color-neutral-900); text-decoration: none; }
/* "Course Timings" button + popover (ACF course_timings field) after the
   Location column. The bar is docked to the bottom of the viewport, so the
   popover opens upwards, anchored to the button. */
.course-timings { position: relative; }
.course-timings__toggle {
	background: none; border: 2px solid var(--color-teal-600); border-radius: 4px;
	color: var(--color-teal-600); font: inherit; font-weight: 700; font-size: .9rem;
	padding: .4rem .9rem; cursor: pointer;
}
.course-timings__toggle:hover,
.course-timings__toggle[aria-expanded="true"] { background: var(--color-teal-600); color: var(--color-white); }
.course-timings__popup {
	position: absolute; bottom: calc(100% + .75rem); left: 50%; transform: translateX(-50%);
	z-index: 50; width: max-content; max-width: min(26rem, calc(100vw - 2rem));
	max-height: 60vh; overflow-y: auto;
	background: var(--color-white); border: 1px solid var(--color-neutral-200); border-radius: 6px;
	box-shadow: 0 8px 30px rgba(0,0,0,.15); padding: 1.25rem 2.5rem 1.25rem 1.25rem;
	text-align: left; line-height: 1.5;
}
.course-timings__popup[hidden] { display: none; }
.course-timings__close {
	position: absolute; top: .4rem; right: .5rem;
	background: none; border: 0; font-size: 1.5rem; line-height: 1; cursor: pointer;
	color: var(--color-neutral-600);
}
.course-timings__content > :first-child { margin-top: 0; }
.course-timings__content > :last-child { margin-bottom: 0; }
.course-timings__content ul, .course-timings__content ol { padding-left: 1.25rem; }
/* Booking panel copy (mobile only - on desktop the sticky bar has it):
   sits near the top of the modal, so the popover opens downwards, anchored
   to the full width of the Dates/Location list rather than the button. */
.booking-panel__meta { position: relative; flex-wrap: wrap; align-items: flex-start; }
.booking-panel__timings { display: none; }
.course-timings--panel { position: static; }
.course-timings--panel .course-timings__popup {
	bottom: auto; top: calc(100% + .5rem); left: 0; right: 0; transform: none;
	width: auto; max-width: none;
}
@media (max-width: 980px) {
	.booking-panel__timings { display: block; }
}

/* ---------- Booking modal ---------- */
.booking-modal { position: fixed; inset: 0; z-index: 1000; display: none; }
.booking-modal[aria-hidden="false"] { display: block; }
.booking-modal__overlay { position: absolute; inset: 0; background: rgba(11,29,46,.6); }
.booking-modal__dialog {
	position: relative; background: var(--color-white); max-width: 720px; margin: 4vh auto; padding: 2.5rem;
	max-height: 92vh; overflow-y: auto;
}
.booking-modal__close {
	position: absolute; top: 1rem; right: 1.25rem; background: none; border: 0; font-size: 1.8rem;
	line-height: 1; cursor: pointer; font-family: inherit; font-weight: 300;
}
.booking-modal__eyebrow { color: var(--color-neutral-900); margin: 0; font-size: 1.3rem; }
.booking-modal__title { margin-top: .1rem; font-weight: 400; }

.booking-panel__meta { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; gap: 2rem; }

/* "More Dates and Locations" <details> between the current session's
   date/location and the ticket/payment form: collapsed by default, and
   boxed in a grey panel with a teal accent so it reads as a separate
   switcher rather than part of the form below it (which keeps its own
   white background and extra top margin). Rows are buttons, not links -
   switching sessions AJAX-swaps the whole .booking-panel in place
   (assets/js/bookings.js), mid-booking-flow. */
.booking-panel__more-sessions {
	margin: 0 0 2rem; background: var(--color-neutral-100);
	border-left: 4px solid var(--color-teal-600); border-radius: 4px;
}
.booking-panel__more-sessions summary {
	display: flex; justify-content: space-between; align-items: center;
	padding: .8rem 1rem; font-weight: 700; color: var(--color-teal-600);
	cursor: pointer; list-style: none;
}
.booking-panel__more-sessions summary::-webkit-details-marker { display: none; }
.booking-panel__more-sessions summary::after {
	content: "\25BE"; margin-left: .75rem; transition: transform .25s ease;
}
.booking-panel__more-sessions[open] summary::after { transform: rotate(180deg); }
.session-tabs { display: flex; flex-direction: column; padding: 0 1rem .5rem; max-height: 30vh; overflow-y: auto; }
.session-tabs__tab {
	display: flex; justify-content: space-between; align-items: center; gap: 1rem;
	background: none; border: 0; border-top: 1px solid var(--color-neutral-200);
	padding: .75rem 0; font: inherit; font-size: .95rem; text-align: left; cursor: pointer;
	color: var(--color-neutral-900);
}
.session-tabs__tab small { font-weight: 400; color: var(--color-neutral-600); }
.session-tabs__tab:hover { color: var(--color-teal-600); }
.session-tabs__tab.is-active { color: var(--color-teal-600); font-weight: 700; cursor: default; }

/* ---------- Booking form ----------
   Markup: plugins/events-manager/placeholders/bookingform.php and
   forms/bookingform/*.php. Sections in order: tickets, attendees,
   registration information, summary, payment. */
.booking-form__section { margin-top: 2rem; }
.booking-form__section:first-of-type { margin-top: 0; }
.em-booking-section-title, .booking-form__title {
	font-family: inherit; font-weight: 700; font-size: 1.1rem; margin: 0 0 .5rem;
}
.booking-form__intro { margin: 0 0 1rem; font-size: .9rem; color: var(--color-neutral-600); }
.booking-form__panel { background: var(--color-neutral-100); border-radius: var(--radius-s); padding: 1.25rem; }
.em-booking-form .em-login-trigger { margin-bottom: 1rem; font-size: .9rem; }

/* Tickets */
.ticketbox__heading { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.ticketbox__discount-link { font-size: .85rem; font-weight: 700; }
.em-tickets { width: 100%; border-collapse: collapse; }
.em-tickets td { padding: .75rem 0; border-bottom: 1px solid var(--color-neutral-200); vertical-align: top; }
.em-bookings-ticket-table-price { font-weight: 700; white-space: nowrap; padding-left: 1rem !important; }
.em-bookings-ticket-table-price small { display: block; font-weight: 400; font-size: .8rem; color: var(--color-neutral-600); }
.ticket-desc, .ticket-desc-special { font-size: .85rem; color: var(--color-neutral-600); }

/* Each ticket row is a 2-column grid - name + price stacked on the left,
   the seats <select> centred on the right - which gives the design's
   "label / big price / excl. VAT" stack whether there's one ticket or
   several. Scoped to tr.em-ticket so any extra rows other plugins add
   via em_booking_form_tickets_loop_footer keep normal table layout. */
.ticketbox .em-tickets tr.em-ticket {
	display: grid; grid-template-columns: 1fr auto; column-gap: 1.5rem; align-items: center;
	padding: 1rem 0; border-bottom: 1px solid var(--color-neutral-200);
}
.ticketbox .em-tickets tr.em-ticket td { padding: 0; border-bottom: 0; }
.ticketbox .em-tickets .em-bookings-ticket-table-type { grid-column: 1; grid-row: 1; }
.ticketbox .em-tickets .em-bookings-ticket-table-price { grid-column: 1; grid-row: 2; font-size: 1.3rem; padding-left: 0 !important; margin-top:10px;}
.ticketbox .em-tickets .em-bookings-ticket-table-spaces { grid-column: 2; grid-row: 1 / span 2; }
/* "Select seats" label - not in the design, visually hidden (kept for
   screen readers) the same way core's .screen-reader-text does it. */
.ticketbox .em-bookings-ticket-table-spaces label {
	position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.ticketbox .em-ticket-select {
	min-width: 200px; padding: .75em 1em; border: 1px solid var(--color-border-dark);
	border-radius: var(--radius-btn); font-family: inherit; font-size: 1rem; background: var(--color-white);
}

.booking-attendees h3.booking-form__title {margin-bottom:0;}

/* Field grid shared by registration information and each attendee card.
   EM Pro field wrappers are <p class="input-group ..."> /
   <p class="input-user-field ...">; text/textarea ones also get
   .booking-field (see innoverto_em_style_form_field()). */
.booking-fields { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; }
.booking-fields > p, .booking-fields > div { margin: 0; min-width: 0; }
.booking-fields .booking-field--wide,
.booking-fields .input-textarea,
.booking-fields .input-checkbox,
.booking-fields .input-checkboxes,
.booking-fields .input-radio,
.booking-fields .input-captcha { grid-column: 1 / -1; }
.booking-fields .booking-html p { margin: 0; }

/* Fields that keep a label above the control (select, date, phone...). */
.booking-fields > p:not(.booking-field) > label { display: block; font-size: .85rem; font-weight: 700; margin-bottom: .35rem; }
.booking-fields > p:not(.booking-field) select,
.booking-fields > p:not(.booking-field) input[type="text"],
.booking-fields > p:not(.booking-field) input[type="tel"],
.booking-fields > p:not(.booking-field) input[type="email"],
.booking-fields > p:not(.booking-field) input[type="password"] {
	width: 100%; padding: .85em .75em; border: 1px solid var(--color-border-dark);
	background: var(--color-white); font-family: inherit; font-size: 1rem;
}
.booking-fields .input-checkbox label,
.booking-fields .input-checkboxes .input-group,
.booking-fields .input-radio .input-group { font-size: .9rem; font-weight: 400; }
.booking-fields .input-checkbox label { display: flex; align-items: center; gap: .6rem; }
.booking-fields input[type="checkbox"], .booking-fields input[type="radio"] {
	accent-color: var(--color-teal-600); width: 20px; height: 20px; flex-shrink: 0;
}
.em-form-required { color: #c0392b; }

/* Field boxes: same overlay/floating label as the download-brochure
   Forminator fields above - label sits over the input like a
   placeholder at rest, then shrinks and floats to the top edge of the
   field on focus/value instead of fading out. Requires each field's
   input/textarea to carry placeholder=" " (see booking-fields.php) so
   the :placeholder-shown check below has something to key off. */
.booking-field {
	position: relative;
	background: var(--color-white);
	border: 1px solid var(--color-border-dark);
}
.booking-field label {
	position: absolute;
	left: .75em;
	top: 50%;
	transform: translateY(-50%);
	transform-origin: left center;
	margin: 0;
	padding: 0 .3em;
	background: var(--color-white);
	color: var(--color-neutral-600);
	font-weight: 400;
	font-size: 1rem;
	line-height: 1.2;
	pointer-events: none;
	z-index: 2;
	transition: transform .15s ease-out, color .15s ease-out;
}
/* Textareas: label rests on the first line, not the vertical middle. */
.booking-field:has(textarea) label { top: 1.45em; }
/* Hidden inputs (EM's submitted phone number) and the country search box
   don't count as "has a value". */
.booking-field:focus-within label,
.booking-field:has(input:not([type="hidden"]):not(.iti__search-input):not(:placeholder-shown), textarea:not(:placeholder-shown)) label {
	top: 0;
	transform: translateY(-50%) scale(.78);
	color: var(--color-neutral-900);
}
.booking-field input, .booking-field textarea {
	position: relative;
	z-index: 1;
	width: 100%;
	padding: .85em .75em;
	border: 0;
	background: transparent;
	font-family: inherit;
	font-size: 1rem;
}
.booking-field textarea { resize: vertical; display: block; }

/* Attendees - one grey rounded card per seat, per Figma. */
.booking-attendees[hidden], .attendee-group[hidden] { display: none; }
.attendee-group + .attendee-group { margin-top: 1.5rem; }
.attendee-group__ticket { margin: 0 0 .75rem; font-weight: 700; color: var(--color-teal-600); }
.attendee-card { background: var(--color-neutral-100); border-radius: var(--radius-s); padding: 1.25rem; }
.attendee-card + .attendee-card { margin-top: 1rem; }
.attendee-card__title { margin: 0 0 1rem; font-weight: 700; }

/* Phone fields: floating label like the other fields, but EM's
   intl-tel-input country picker (flag + dial code) sits at the start of
   the box. EM pads the input to clear it (inline, !important, and wider
   for longer dial codes); booking-form.js copies that padding into
   --phone-label-left so the resting label lines up with where typing
   starts. Floated, it moves to the top-left corner like the others. */
.booking-fields .iti { display: block; width: 100%; }
.booking-field-phone label {
	left: calc(var(--phone-label-left, 6.5rem) - .3em);
	z-index: 4;
	transition: transform .15s ease-out, color .15s ease-out, left .15s ease-out;
}
.booking-field-phone:focus-within label,
.booking-field-phone:has(input[type="tel"]:not(:placeholder-shown)) label,
.booking-field-phone:not(:has(.iti)) label { left: .75em; } /* last: picker didn't load */
/* Picker above the field layers (its dropdown included) so neighbouring
   fields can't cover it; the input itself stays below the picker. */
.booking-field-phone .iti__country-container { z-index: 3; }
.booking-field-phone .iti input[type="tel"] { z-index: auto; }
/* EM shows an example number as the placeholder - only once focused, so it
   doesn't sit under the resting label. */
.booking-field-phone input[type="tel"]::placeholder { color: transparent; }
.booking-field-phone input[type="tel"]:focus::placeholder { color: var(--color-neutral-600); }
.booking-fields .iti__selected-country {
	padding: 0 .6rem 0 .75rem; background: transparent; border: 0;
	border-right: 1px solid var(--color-neutral-200); font: inherit; color: inherit; cursor: pointer;
}
.booking-fields .iti__selected-country:hover,
.booking-fields .iti__selected-country:focus-visible { background: var(--color-neutral-100); }
.booking-fields .iti__selected-dial-code { font-size: 1rem; color: var(--color-neutral-900); }
.booking-fields .iti__dropdown-content {
	margin-top: 4px; background: var(--color-white); border: 1px solid var(--color-border-dark);
	border-radius: var(--radius-s); box-shadow: 0 12px 32px rgba(0,0,0,.15); overflow: hidden; z-index: 30;
}
.booking-fields .iti__search-input {
	width: 100%; padding: .7em 2.25em; border: 0; border-bottom: 1px solid var(--color-neutral-200);
	border-radius: 0; font: inherit; font-size: .95rem; background: var(--color-white);
}
.booking-fields .iti__search-input:focus { outline: 2px solid var(--color-teal-600); outline-offset: -2px; }
.booking-fields .iti__country-list { margin: 0; padding: .25rem 0; list-style: none; max-height: 240px; }
.booking-fields .iti__country { margin: 0; padding: .5em .75em; font-size: .9rem; }
.booking-fields .iti__country.iti__highlight { background: var(--color-neutral-100); }
.booking-fields .iti__country[aria-selected="true"] { color: var(--color-teal-600); font-weight: 700; }
.booking-fields .iti__dial-code { color: var(--color-neutral-600); }

/* Phone / email errors (assets/js/booking-form.js; EM's own phone check
   uses the same .em-inline-error element). */
.em-booking-form .em-inline-error { margin-top: .35rem; font-size: .8rem; line-height: 1.3; color: #c0392b; }
.em-booking-form .em-inline-error .em-icon { display: none; }
.em-booking-form [aria-invalid="true"], .em-booking-form .iti.invalid-number input { border-color: #c0392b !important; }
/* Floating-label boxes: the message hangs just below the box instead of
   inside its border. */
.booking-field.has-error { border-color: #c0392b; margin-bottom: 1.25rem; }
.booking-field > .em-inline-error { position: absolute; left: 0; top: 100%; }

.sticky-booking-bar__price-note, .sticky-booking-bar__price-value {margin-top:0;}
.sticky-booking-bar__price-note {font-size: 0.95em;}

/* Payment */
.booking-panel__payment-note { margin: 0 0 1rem; font-size: .85rem; color: var(--color-neutral-600); }
.em-bookings-form-coupon { max-width: 320px; margin: 0 0 1.25rem; }
.em-coupon-message { display: block; margin-top: .35rem; font-size: .85rem; }
.em-booking-form-section-confirm .input-field-data_privacy_consent,
.em-booking-form-section-confirm .em-data-privacy-consent { font-size: .85rem; margin: 1rem 0; }
.em-booking-form-section-confirm input[type="checkbox"] { accent-color: var(--color-teal-600); width: 20px; height: 20px; vertical-align: middle; }

/* Payment methods accordion (forms/bookingform/payment-methods.php).
   The radio itself is the toggle: whichever is checked shows its panel,
   via :has(), so it needs no JS. */
.payment-methods { border: 1px solid var(--color-neutral-200); border-radius: var(--radius-s); overflow: hidden; }
.payment-method + .payment-method { border-top: 1px solid var(--color-neutral-200); }
.payment-method__header {
	display: flex; align-items: center; gap: .85rem; padding: 1rem 1.25rem;
	cursor: pointer; font-weight: 700; background: var(--color-white);
	transition: background-color .15s ease-out;
}
.payment-method__header:hover { background: var(--color-neutral-100); }
.payment-method__radio {
	accent-color: var(--color-teal-600); width: 22px; height: 22px; margin: 0; flex-shrink: 0;
}
.payment-method__title { flex: 1; }
.payment-method__chevron {
	width: .55rem; height: .55rem; margin-right: .25rem;
	border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
	transform: rotate(45deg); transition: transform .2s ease-out;
}
.payment-method__panel {
	display: grid; grid-template-rows: 0fr;
	background: var(--color-neutral-100);
	transition: grid-template-rows .25s ease-out;
}
.payment-method__panel-inner { overflow: hidden; padding: 0 1.25rem 0 calc(1.25rem + 22px + .85rem); font-size: .9rem; }
.payment-method__panel-inner > :first-child { margin-top: 1rem; }
.payment-method__panel-inner > :last-child { margin-bottom: 1rem; }
.payment-method:has(.payment-method__radio:checked) .payment-method__header { background: var(--color-neutral-100); color: var(--color-teal-600); }
.payment-method:has(.payment-method__radio:checked) .payment-method__chevron { transform: rotate(-135deg); }
.payment-method:has(.payment-method__radio:checked) .payment-method__panel { grid-template-rows: 1fr; }
.payment-method__header:has(.payment-method__radio:focus-visible) { outline: 2px solid var(--color-teal-600); outline-offset: -2px; }
/* MamoPay prints an empty cost box into its panel. */
#costinfobox:empty { display: none; }
@media (prefers-reduced-motion: reduce) {
	.payment-method__panel, .payment-method__chevron { transition: none; }
}

/* Payment methods - EM Pro 3.2+ (\EM\Payments\Gateways, 3.9.6 live).
   EM Pro's own markup, forced to its radio layout (see
   innoverto_em_booking_form_hooks()), styled to match the accordion
   above: one bordered row per gateway, then the selected gateway's
   instructions/card fields in a grey panel below the list. EM's gateway
   JS shows/hides with a .hidden class, which EM's own stylesheet would
   otherwise define. Each row is fully clickable (assets/js/booking-form.js
   - EM's labels aren't tied to their radios). */
.em-payment-gateways.hidden,
.em-payment-gateways .hidden { display: none !important; }
.em-payment-gateways .em-payment-gateway-selector:empty { display: none; }
.em-payment-gateways .em-payment-gateway-options {
	margin: 0; padding: 0; border: 1px solid var(--color-neutral-200);
	border-radius: var(--radius-s); overflow: hidden; min-width: 0;
}
.em-payment-gateways .em-payment-gateway-option-radio {
	display: flex; align-items: center; gap: .85rem; padding: 1rem 1.25rem;
	cursor: pointer; font-weight: 700; background: var(--color-white);
	transition: background-color .15s ease-out;
}
.em-payment-gateways .em-payment-gateway-option-radio + .em-payment-gateway-option-radio { border-top: 1px solid var(--color-neutral-200); }
.em-payment-gateways .em-payment-gateway-option-radio:hover { background: var(--color-neutral-100); }
.em-payment-gateways .em-payment-gateway-option-radio input[type="radio"] {
	accent-color: var(--color-teal-600); width: 22px; height: 22px; margin: 0; flex-shrink: 0; cursor: pointer;
}
.em-payment-gateways .em-payment-gateway-option-radio label { flex: 1; margin: 0; cursor: pointer; font-weight: inherit; }
.em-payment-gateways .em-payment-gateway-option-radio:has(input:checked) { background: var(--color-neutral-100); color: var(--color-teal-600); }
.em-payment-gateways .em-payment-gateway-option-radio:has(input:focus-visible) { outline: 2px solid var(--color-teal-600); outline-offset: -2px; }
.em-payment-gateways .em-payment-gateway-form {
	margin-top: .75rem; padding: 1rem 1.25rem; background: var(--color-neutral-100);
	border-radius: var(--radius-s); font-size: .9rem;
}
.em-payment-gateways .em-payment-gateway-form:not(:has(.em-payment-gateway-form-info > *, .em-payment-gateway-form-data > *, .em-payment-gateway-form-loading > *)) { display: none; }
.em-payment-gateways .em-payment-gateway-form > div > :first-child { margin-top: 0; }
.em-payment-gateways .em-payment-gateway-form > div > :last-child { margin-bottom: 0; }

/* EM Pro 3.2+ coupon field (launch offer only - innoverto_em_coupon_section()). */
.em-booking-form-section-coupons { margin: 0 0 1.25rem; max-width: 420px; }
.em-booking-form-section-coupons label { display: block; font-size: .85rem; font-weight: 700; margin-bottom: .35rem; }
.em-booking-form-section-coupons .em-coupon-code-fields { display: flex; gap: .5rem; }
.em-booking-form-section-coupons .em-coupon-code-wrap { flex: 1; min-width: 0; }
.em-booking-form-section-coupons .em-coupon-code {
	width: 100%; padding: .85em .75em; border: 1px solid var(--color-border-dark);
	background: var(--color-white); font-family: inherit; font-size: 1rem;
}
.em-booking-form-section-coupons .em-coupon-code-button {
	padding: 0 1.25em; border: 1px solid var(--color-teal-600); border-radius: var(--radius-btn);
	background: var(--color-white); color: var(--color-teal-600); font: inherit; font-weight: 700; cursor: pointer;
}
.em-booking-form-section-coupons .em-coupon-code-button:hover { background: var(--color-teal-600); color: var(--color-white); }

.total-cost { font-size: 1rem; margin: 1rem 0; }
.em-booking-buttons { margin-top: 1.5rem; text-align: right; }

/* Sticky bar mobile toggle - hidden on desktop, where the bar's content
   (sessions + pricing) is already visible inline by default. */
.sticky-booking-bar__mobile-toggle { display: none; }
.sticky-booking-bar__content { display: block; }
.em-booking-submit { width: 100%; font-size: 1rem; border-radius: var(--radius-btn); }

/* EM's live booking summary box. */
.em-booking-form-section-summary .em-booking-section { background: var(--color-neutral-100); border-radius: var(--radius-l); padding: 1rem 1.25rem; }

/* Booking summary - Sub Total / Taxes / Total breakdown. Each .em-bs-row
   holds 2-3 cells (qty + desc + price, or just desc + price); pushing
   the price cell to the right with margin-left:auto keeps one flex rule
   working for every row shape without needing to touch EM's markup. */
.em-booking-summary { font-size: 1rem; }
.em-bs-row { display: flex; align-items: baseline; gap: .4rem; padding: .35rem 0; }
.em-bs-cell-price { margin-left: auto; white-space: nowrap; }
.em-bs-row-item { color: var(--color-neutral-600); }
.em-bs-row-item .em-bs-cell-price { color: var(--color-neutral-900); }
.em-bs-section-subtotals { border-top: 1px solid var(--color-neutral-200); margin-top: .5rem; padding-top: .35rem; }
.em-bs-section-total { border-top: 1px solid var(--color-neutral-900); margin-top: .5rem; padding-top: .5rem; }
.em-bs-row-total { font-weight: 700; font-size: 1.05rem; }

.em-form-submit.em-booking-submit {
	background: var(--color-teal-600); color: var(--color-white); border: 0;
	padding: .85em 1.5em; font-weight: 700; font-family: inherit; cursor: pointer;
}
.em-form-submit.em-booking-submit:hover { background: var(--color-teal-700); }

.discountoffers.parentbox { display: none; }
.discountoffers.parentbox.is-open {
	display: block; position: absolute; background: var(--color-white); border: 1px solid var(--color-neutral-200);
	padding: 1.5rem; box-shadow: 0 12px 32px rgba(0,0,0,.15); z-index: 10; max-width: 360px;
}
.listTable { width: 100%; border-collapse: collapse; }
.listTable td { padding: .4em 0; border-bottom: 1px solid var(--color-neutral-200); }

/* ---------- Footer ---------- */
.newsletter-bar { background: var(--color-navy-900); color: var(--color-white);}
.newsletter-bar h4, .newsletter-bar p { color: var(--color-white); margin: 0; }
.newsletter-bar__form { display: flex; gap: .5rem; }
.newsletter-bar__form input[type="email"] { padding: .7em 1em; border: 0; min-width: 260px; }

.site-footer { background: var(--color-navy-900); color: var(--color-white); }
.footer-main { padding: 3rem 1rem; gap: 2rem; }
.footer-main a { color: var(--color-white); }
.site-footer a:hover { color: var(--color-gold-500); }
/* Bare icons only, no colored circle behind them - "Logos Only" is core's
   built-in social-links style for this; the rules below are a defensive
   backstop in case that style's own CSS isn't loaded. */
.footer-social.wp-block-social-links { gap: 1rem; }
.footer-social .wp-social-link { background: none !important; }
.footer-social a { color: var(--color-white) !important; }

/* ---------- Content links ---------- */
.general_page__sidebar {font-size:0.9em;}
.general_page__sidebar h3.widget-title {margin-bottom: 4px;line-height: 1.2em;font-size: 1.4em;}

.wp-block-post-content a {
	color: var(--color-teal-600);
	text-decoration: none;
}

.content-container {box-shadow:0px -80px 30px 14px rgba(0, 0, 0, 0.04);
max-width:var(--wp--style--global--wide-size);margin:auto;
}

.footer-menu-columns { display: flex; gap: 3rem; flex-wrap: wrap; }
/* A <button> now (mobile accordion toggle - see .js-footer-menu-toggle in
   main.js), reset to read as plain bold text rather than a form control. */
.footer-menu-columns__title {
	display: block; width: 100%; margin: 0 0 1.25rem; padding: 0;
	background: none; border: 0; color: inherit; font: inherit; text-align: left; cursor: pointer;
	font-size: .85rem; font-weight: 700; letter-spacing: .03em;
}
.footer-menu-columns__col ul { list-style: none; margin: 0; padding: 0; }
.footer-menu-columns__col li { margin-bottom: 1rem; }
.footer-menu-columns__col li:last-child { margin-bottom: 0; }
.footer-menu-columns__col a { font-size: .9rem; opacity: .9; line-height: 1.4; }
.footer-menu-columns__col a:hover { opacity: 1; color: var(--color-gold-500); text-decoration: underline; }

/* Footer nav columns built with core "List" blocks (wp-block-list) instead
   of the innoverto/footer-menu-columns PHP block - each column is a plain
   <ul class="wp-block-list"> with a single <li> holding a bold heading
   link followed by the rest of the links separated by <br>, not one <li>
   per link. Strip the default browser list styling (marker + indent) and
   use line-height to give the <br>-separated links breathing room, since
   they can't be spaced with margin individually. */
.site-footer .wp-block-list {
	list-style: none;
	margin: 0;
	padding: 0;
}
.site-footer .wp-block-list li {
	margin: 0;
	line-height: 1.8;
}
.site-footer .wp-block-list a {
	color: var(--color-white);
	text-decoration: none;
	font-size: .9rem;
	opacity: .9;
}
.site-footer .wp-block-list a:hover {
	opacity: 1;
	color: var(--color-gold-500);
	text-decoration: underline;
}
.site-footer .wp-block-list li > strong:first-child a {
	display: inline-block;
	margin-bottom: .5rem;
	font-size: .85rem;
	text-transform: uppercase;
	letter-spacing: .03em;
	opacity: 1;
}

/* Admin-only setup hints (empty states shown when content isn't configured yet) */
.innoverto-empty-state {
	background: repeating-linear-gradient(45deg, #fff8e1, #fff8e1 10px, #fff3cd 10px, #fff3cd 20px);
	border: 1px dashed #d69215; color: #5b4400; padding: 1rem; font-size: .85rem;
}
.footer-side { padding: 0 1rem 2rem; }
.footer-side img { display: inline-block; margin-right: 1rem; }
/* This block's own "align":"center" attribute in parts/footer.html drives
   text-centering (has-text-align-center), not width - so now that its
   parent <footer> is a "constrained" layout (see MIGRATION.md v1.13),
   it would otherwise be newly treated as an unaligned child and shrunk
   to the Small width. Deliberately left the block's own markup/attributes
   untouched to avoid a block-validation mismatch in the editor (Group's
   save() output has to match what's on the page) - this CSS override
   keeps it visually full-width instead. */
.footer-copyright { max-width: none !important; margin-left: 0 !important; margin-right: 0 !important; padding: 1.5rem 1rem; border-top: 1px solid rgba(255,255,255,.15); font-size: .85rem; }

/* ---------- Course banner (post featured image) ----------
   Figma places this above the breadcrumb/title (it's the event's
   featured image, not text baked into the body content), with a drop
   shadow and rounded corners on both desktop and mobile. */
.course-page__banner { margin: 1.5rem 0; }
.course-page__banner img {
	box-shadow: 0 0 38px 14px rgba(0,0,0,.05); width: 100%; height: auto;
}

/* Mobile "Download the Brochure" / "Book Now" CTA pair shown right under
   the banner (Figma frame 380:363). Hidden on desktop, where the
   equivalent actions already exist (sidebar button + sticky booking bar). */
.mobile-course-cta { display: none; }

/* ---------- Featured images (global default) ----------
   WordPress adds "wp-post-image" to the <img> from get_the_post_thumbnail()
   automatically; this is the site-wide fallback for any featured image
   that isn't inside a component with its own explicit sizing (course
   cards, news/past-trainings lists and the course banner override this
   above via higher-specificity selectors, so they're unaffected). */
/*.wp-post-image,
.featured-image {
	width: 200px;
	height: auto;
	object-fit: cover;
}
li .wp-post-image,
li .featured-image {
	width: 140px;
	height: 86px;
}*/

/* ---------- Responsive ---------- */

/* Boxed page content (WordPress's native constrained/wide-aligned blocks,
   marked with the "is-layout-constrained" class WordPress adds to every
   constrained-layout block) has no side padding of its own - it just
   centers up to contentSize/wideSize (both 1300px, see theme.json
   settings.layout) via margin:auto. Above that width there's always
   leftover viewport space outside the box; at/below it the box becomes
   exactly viewport-width with zero gutter, so text/buttons touch the
   screen edge. Add a manual gutter here once that happens, to every
   element that gets that max-width from WordPress's native mechanism -
   i.e. every "is-layout-constrained > *" that isn't .alignfull (alignfull
   children like the sticky booking bar/booking modal are meant to stay
   full-bleed, so they're excluded; this includes the header's own
   .site-header__top-inner/.site-header__nav-inner, which carry "alignwide"
   the same way). Not scoped to <main> - some plugin/classic markup (e.g.
   Events Manager's own templates) isn't necessarily nested under a
   block-templated <main is-layout-constrained>. Keep this breakpoint in
   sync with theme.json's settings.layout.wideSize/contentSize if that
   value ever changes.

   The gutter is only meant for the OUTERMOST constrained box in a given
   column - the one actually touching the viewport edge. WordPress marks
   every constrained group with "is-layout-constrained", though, including
   ones nested well inside already-padded content (e.g. ".section" is
   itself constrained, sitting inside <main is-layout-constrained>, and
   several footer/header sub-groups are constrained inside an already-
   constrained parent). Matching every one of those independently stacked
   this same 30px on top of each nesting level's own padding, which is
   what made most of the page look over-padded/cluttered on both outer
   and inner elements. ":not(.is-layout-constrained .is-layout-constrained)"
   excludes any constrained element that itself has a constrained ancestor,
   so only the outermost one per column - the one genuinely at the
   viewport edge - gets the manual gutter; inner ones keep only their own
   component-level padding (e.g. ".section"'s own "padding: 3rem 1rem"). */
@media (max-width: 1300px) {
	.is-layout-constrained:not(.is-layout-constrained .is-layout-constrained) > :not(.alignfull) {
		padding-left: 25px !important;
		padding-right: 25px !important;
	}
	.content-container {margin-left:25px;margin-right:25px;}
}

/* Header nav collapses into the hand-rolled toggle button below this width -
   the horizontal menu doesn't have room once the header content above it
   has started wrapping around this width. The menu list itself starts
   hidden and only appears once .site-header__nav gets .is-nav-open (see
   .js-nav-toggle in assets/js/main.js), as a full-width panel dropping
   down from the nav bar rather than squeezed inline. Submenu items (the
   chevron-toggle buttons on menu items with children) keep working
   unmodified - that's core/navigation's own click-to-expand behaviour,
   independent of the overlayMenu setting this replaces - they just needed
   actual mobile styling, which they had none of before. */
@media (max-width: 979px) {
	.site-header__nav-toggle { display: flex; }
	.site-header__nav { position: relative; }

	/* nav.site-header__navigation.wp-block-navigation - tag-qualified with
	   "nav", not just the two classes. Confirmed from the live rendered
	   markup: WordPress stamps the block's own wrapper classes
	   ("site-header__navigation wp-block-navigation") onto BOTH the outer
	   <nav> AND its child <ul class="wp-block-navigation__container ...">
	   - core mirrors them onto the inner container too, not just the
	   block's root element. A plain ".site-header__navigation.wp-block-
	   navigation" selector (no tag) matched both, so both the <nav> and
	   its own child <ul> independently became positioned at once - only
	   the <nav> is a "nav" element (the <ul> obviously isn't), so
	   qualifying by tag makes the selector match just the one intended
	   element.

	   The panel itself is a full-height drawer sliding in from the left
	   (position:fixed, not absolute - anchors to the viewport regardless
	   of any positioned ancestor, which a dropdown anchored to the nav
	   bar's own bottom edge doesn't need but a drawer spanning the full
	   viewport height does). display stays "block" in both states so
	   transform can actually transition (display can't be animated) -
	   "closed" is fully off-screen via translateX(-100%) with
	   visibility:hidden so it's not tabbable/clickable while hidden; the
	   "visibility 0s linear .3s" delay on the closed rule only holds the
	   panel visible until the slide-out transform finishes, then hides it
	   - the open rule's own transition (no delay) means opening is
	   immediate in the other direction. */
	nav.site-header__navigation.wp-block-navigation {
		display: block !important; width: min(320px, 85vw);
		position: fixed; top: 0; bottom: 0; left: 0; z-index: 200;
		background: var(--color-navy-900);
		max-height: none; height: 100vh; overflow-y: auto;
		box-shadow: 0 0 30px rgba(0,0,0,.35);
		transform: translateX(-100%);
		visibility: hidden;
		transition: transform .3s ease, visibility 0s linear .3s;
	}
	.site-header__nav.is-nav-open nav.site-header__navigation.wp-block-navigation {
		transform: translateX(0);
		visibility: visible;
		transition: transform .3s ease, visibility 0s linear;
	}
	.site-header__nav.is-nav-open ~ .site-header__nav-backdrop {
		opacity: 1; visibility: visible; pointer-events: auto;
		transition: opacity .3s ease, visibility 0s linear;
	}
	.site-header__navigation .wp-block-navigation__container {
		flex-direction: column; align-items: stretch; gap: 0;
	}
	/* flex:1 1 0% (not flex:1 1 auto, and not width:100%) + min-width:0 -
	   the label is one of up to 3 flex children on the <li> (label,
	   submenu-toggle chevron button, submenu <ul> - see the has-child rule
	   below). With a flex-basis of "auto", the label's hypothetical size
	   for the purposes of "does this fit on the current flex line" is its
	   own full single-line text width - fine for a short label like
	   "Events", but for a long one like "Executive Team Workshops" that
	   alone nearly fills the row, so the browser decides the chevron
	   doesn't fit next to it and bumps the *chevron* onto its own line,
	   rather than shrinking the label. A flex-basis of 0% starts the
	   label's hypothetical size at 0 for that same fit check, so it and
	   the chevron always share line 1 regardless of label length; the
	   label's flex-grow:1 then expands it to fill whatever room is left
	   after the chevron, and it's THAT already-fitted width the label's
	   own text wraps within if it's too long for one line - producing the
	   wanted "long label wraps to 2 lines, chevron stays put beside it"
	   result instead of "chevron drops to its own line". min-width:0 lets
	   it actually shrink that far (flex items default to a min-width
	   based on their content, which would otherwise override flex-shrink
	   and stop it from ever giving up that space). The row divider moves
	   to the <li> itself (below) rather than living on the label, so it
	   still spans the full row now that the label alone no longer does. */
	.site-header__nav .wp-block-navigation-item > a,
	.site-header__nav .wp-block-navigation-item > .wp-block-navigation-item__content {
		display: block; flex: 1 1 0%; min-width: 0; box-sizing: border-box;
		padding: 1rem 1.5rem !important;
	}
	.site-header__nav .wp-block-navigation-item {
		border-bottom: 1px solid rgba(255,255,255,.1);
	}
	.site-header__nav .wp-block-navigation-item.noborders {
		border-bottom: 0;
	}

	/* core's .wp-block-navigation-item is "display:flex; align-items:
	   center" unconditionally (its normal desktop role: laying the label
	   and the submenu-toggle chevron out side by side on one line) with
	   no flex-wrap, i.e. nowrap. A has-child item's <li> holds 3 children
	   - the label <a>, the toggle <button>, and the submenu <ul> - and
	   once that <ul> becomes position:static (below) it's just the 3rd
	   flex child in that same nowrap row, shrinking to fit alongside the
	   label/chevron instead of dropping to a new line - that's what put
	   submenus beside their parent instead of under it. flex-wrap:wrap
	   keeps the label+chevron on their own first line (they fit) and
	   forces the submenu-container - given width:100% below, wider than
	   any remaining space on that line - onto a full-width line of its
	   own underneath. */
	.site-header__nav .wp-block-navigation-item.has-child {
		flex-wrap: wrap;
	}

	/* !important on every property here, not just position: core's own
	   "open" rule for a clicked submenu toggle
	   (.wp-block-navigation-submenu__toggle[aria-expanded="true"] ~
	   .wp-block-navigation__submenu-container, in the block library's own
	   stylesheet) sets width:auto/min-width:200px with 3 classes' worth of
	   specificity - higher than this 2-class selector - so without
	   !important those two properties still win over ours even though
	   position:static (already !important) correctly wins its own fight.
	   left/top/right/transform are reset too in case a future core version
	   computes an inline offset for the flyout position (harmless no-ops
	   once position is static, since static ignores all four anyway). */
	.site-header__nav .wp-block-navigation__submenu-container {
		position: static !important;
		min-width: 0 !important; width: 100% !important;
		left: auto !important; right: auto !important; top: auto !important;
		transform: none !important;
		box-shadow: none;
	}
	.site-header__nav .wp-block-navigation-submenu__toggle {
		background: none; border: 0; color: var(--color-gold-500); cursor: pointer;
		padding: 0.85rem 1.4rem;
	}
}

@media (max-width: 980px) {
	/* Sticky booking bar stays docked to the bottom of the viewport at
	   this width too (same position: sticky as desktop, from the base rule
	   above), but the pricing/dates/"More Dates and Locations" content
	   above is dropped entirely rather than tucked behind a toggle - the
	   booking modal it opens (.js-open-booking-modal) already repeats all
	   of it (date/location, the session switcher, tickets), so a mobile
	   visitor never actually needs to see it inline first. */
	.sticky-booking-bar { padding: 0; box-shadow: none; background: none; margin-top: 0; }
	.sticky-booking-bar__content { display: none; }
	.sticky-booking-bar__mobile-toggle {
		display: block; width: 100%; box-sizing: border-box;
		background: var(--color-teal-600); color: var(--color-white) !important;
		border: 0; padding: 1rem; font-weight: 700; font-size: 1.1rem;
		font-family: inherit; text-align: center; text-decoration: none; cursor: pointer;
		box-shadow: 0 0 14px 5px rgba(0,0,0,.12);
	}
	.sticky-booking-bar__mobile-toggle.is-sold-out {
		background: var(--color-neutral-200); color: var(--color-neutral-900) !important; cursor: default;
	}

	.is-layout-constrained:not(.is-layout-constrained .is-layout-constrained)> :not(.alignfull) {
		padding-left: 25px !important;
		padding-right: 25px !important;
	}
}

@media (max-width: 900px) {
	/* :not(.course-grid--carousel) - the Slick-powered carousel variant
	   already gets grid-template-columns:none from its own base rule
	   above (JS/Slick owns its slide-count responsiveness, see main.js's
	   `responsive` breakpoints), so it should always render its single
	   .slick-list child at full width. Without this exclusion, this rule
	   ties that base rule's specificity (one class each) and wins by
	   coming later in the cascade, reinstating an explicit 2-column grid
	   on the carousel container - which then only gives its one child
	   (.slick-list) the first of those 2 columns, i.e. half the row,
	   leaving the other half blank. That's exactly the 900-600px gap:
	   below 600px the equivalent override becomes 1fr (one column), which
	   is coincidentally still full width, so the bug is invisible there. */
	.course-grid:not(.course-grid--carousel) { grid-template-columns: repeat(2, 1fr); }
	.course-page__layout, .page-layout, .news-past-trainings, .booking-fields { grid-template-columns: 1fr; }
	.forminator-custom-form .forminator-row { flex-direction: column; }
	.wpcf7-form .downloadform { grid-template-columns: 1fr; }
	/* Ticket row: seats dropdown drops below the name/price, full width. */
	.ticketbox .em-tickets tr.em-ticket { grid-template-columns: 1fr; row-gap: .75rem; }
	.ticketbox .em-tickets .em-bookings-ticket-table-spaces { grid-column: 1; grid-row: 3; }
	.ticketbox .em-ticket-select { min-width: 0; width: 100%; }
	.ticketbox__heading { flex-direction: column; align-items: flex-start; gap: .25rem; }
	.course-page__layout.wp-block-columns, .page-layout.wp-block-columns { flex-wrap: wrap; }
	.course-page__main, .course-page__sidebar, .page-layout > .wp-block-column { /*flex-basis: 100% !important;*/ }

	/* Pill tabs already wrap onto extra rows via theme.json's global
	   core/tabs style (flex-wrap) - just tighten the padding a bit so
	   more of them fit per row on narrow screens. */
	.course-page .wp-block-tab-list button[role=tab] { padding: 0.7rem 1.1rem; }
}

@media (max-width: 699px) {
	/* Below 700px there's no longer room for the star rating + phone/email
	   column alongside the logo without the top bar wrapping/crowding, so
	   they're dropped entirely rather than squeezed - they're supplementary
	   trust signals, not primary navigation, and both are still reachable
	   from page content further down. */
	.header-rating, .site-header__contact { display: none; }

	/* News/Past Trainings list rows: side-by-side thumb+text (the base
	   ".news-list a/li { display:flex; }" rule) gets cramped once the
	   fixed 140px thumbnail is competing with the text for space on a
	   narrow screen - stack the thumbnail above the text instead, at full
	   width, same as a typical mobile card list. */
	.news-list li, .past-trainings-list li,
	.news-list a, .past-trainings-list a {
		flex-direction: column;
	}
	.news-list__thumb, .past-trainings-list__thumb {
		flex-basis: auto; width: 100%;
	}
	.news-list__thumb img, .past-trainings-list__thumb img {
		width: 100%; height: auto;
	}
}

@media (max-width: 600px) {
	.is-layout-constrained:not(.is-layout-constrained .is-layout-constrained)> :not(.alignfull) {
			padding-left: 10px !important;
			padding-right: 10px !important;
		}
	/* "Large"/"Small" width both collapse to 96% on mobile (both the
	   width-large/-small utility classes and WordPress's own wideSize/
	   contentSize alignment, so this covers header/footer content rows
	   and ordinary aligned page content the same way). "Full" width
	   stays 100% edge-to-edge on mobile too, same as desktop - the
	   header/footer background bars are meant to keep touching the
	   screen edge, not gain a mobile gutter. */
	:root {
		--width-large: 96vw;
		--width-small: 96vw;
		--wp--style--global--wide-size: 96vw;
		--wp--style--global--content-size: 96vw;
	}

	.course-grid:not(.course-grid--carousel) { grid-template-columns: 1fr; }
	.news-past-trainings { display: block; }
	.booking-modal__dialog { margin: 0; max-width: none; height: 100%; max-height: none; border-radius: 0; }
	.site-header__top { flex-wrap: wrap; padding: .75rem 1rem; }
	.site-header__nav-inner { padding: 0 1rem; }

	/* Newsletter bar: the text block and the form (both top-level flex
	   children of .newsletter-bar) cascade into one column instead of
	   sitting side by side; align-items:stretch makes the form actually
	   take the bar's full width so the input's own width:100% below means
	   something. Inside the form, input-then-button also switches to a
	   column - the existing ".newsletter-bar__form { gap: .5rem }" (base
	   rule, row-only before) still applies once it's a column, giving the
	   space between them. min-width:0 drops the email input's desktop
	   floor (min-width:260px) which would otherwise fight width:100% and
	   overflow on a narrow phone. */
	.newsletter-bar { flex-direction: column; align-items: stretch; }
	.newsletter-bar__form { flex-direction: column; }
	.newsletter-bar__form input[type="email"] { width: 100%; min-width: 0; }
	.newsletter-bar__form .button { width: 100%; }

	/* Footer nav collapses into an accordion: each column's submenu starts
	   hidden and slides open when its parent title is tapped (see
	   .js-footer-menu-toggle in main.js, which sets an explicit max-height
	   for the transition since "auto" heights can't be animated). */
	.footer-menu-columns { display: block; }
	.footer-menu-columns__col { border-bottom: 1px solid rgba(255,255,255,.15); }
	.footer-menu-columns__col:last-child { border-bottom: 0; }
	.footer-menu-columns__title {
		display: flex; align-items: center; justify-content: space-between;
		padding: 1rem 0; margin: 0;
	}
	.footer-menu-columns__title::after {
		content: "\25BE"; margin-left: .75rem; flex-shrink: 0;
		transition: transform .25s ease;
	}
	.footer-menu-columns__col.is-open .footer-menu-columns__title::after { transform: rotate(180deg); }
	.footer-menu-columns__col ul {
		max-height: 0; overflow: hidden; transition: max-height .3s ease;
	}
	.footer-menu-columns__col ul li:first-child { padding-top: .25rem; }
	.footer-menu-columns__col ul li:last-child { padding-bottom: 1rem; }

	/* All content columns stack on mobile - explicit, rather than relying
	   solely on WordPress core's own columns-block mobile behaviour
	   (found a real gap here: the "Why Innoverto" 3-column row and the
	   home hero's text/image columns both stayed side-by-side and
	   squeezed without this). Header/nav layout is unaffected since it's
	   built from wp:group flex layouts, not wp:columns. */
	.wp-block-columns { flex-wrap: wrap !important; }
	.wp-block-columns > .wp-block-column {
		flex-basis: 100% !important;
	}
	.home-hero__image { margin-top: 1.5rem; }
	.home-hero__copy h1 { font-size: 2rem; }

	/* Tabs: one full-width accordion-style bar per tab (Figma shows each
	   tab as its own bar with a chevron rather than a row of pills). In
	   this stacked column layout every button is its own single-item
	   "row", so main.js's initTabRowRounding() would otherwise mark every
	   one of them as both tab-row-start AND tab-row-end (fully rounded) -
	   reset that back to flat/square bars here. */
	.course-page .wp-block-tab-list { flex-direction: column; }
	.course-page .wp-block-tab-list button[role=tab] {
		text-align: left; position: relative; padding-right: 2.5rem;
	}
	.course-page .wp-block-tab-list button[role=tab].tab-row-start,
	.course-page .wp-block-tab-list button[role=tab].tab-row-end {
		border-radius: 0;
	}
	.course-page .wp-block-tab-list button[role=tab]::after {
		content: "\25BE"; position: absolute; right: 1rem; top: 50%; transform: translateY(-50%);
	}

	/* Mobile CTA row under the course banner. */
	.mobile-course-cta { display: flex; gap: 1rem; margin: 1rem 0 1.5rem; display:none;}
	.mobile-course-cta .button { flex: 1 1 0; text-align: center; }
}


/* Block visibility ("Hide on mobile/tablet/desktop" in the editor).
   Mirrors WordPress core's viewport breakpoints: mobile <= 480px,
   tablet 481-781px, desktop >= 782px. */
@media (max-width: 580px) {
	.wp-block-hidden-mobile { display: none !important; }
}
@media (min-width: 581px) and (max-width: 781px) {
	.wp-block-hidden-tablet { display: none !important; }
}
@media (min-width: 782px) {
	.wp-block-hidden-desktop { display: none !important; }
}
