/*
 * OPAL block styling.
 *
 * theme.json carries the design system: palette, Montserrat, the type
 * scale, spacing and the 1272px measure. This file does the rest, which
 * is making core block output read as OPAL.
 *
 * Everything here hangs off a block style variation (is-style-*) or a
 * core block class, so nothing depends on hand written markup. Values
 * are ported from opal-static/css/theme.css.
 *
 * No shadows anywhere, matching the static site. Hex only, no rgba.
 *
 *   01  Sections and measure
 *   02  Page hero (core/cover)
 *   03  Cards (core/group, core/columns)
 *   04  Ticks (core/list)
 *   05  Headings, eyebrows, ledes
 *   06  Media split (core/media-text)
 *   07  CTA card, mini, jump links
 *   08  Buttons
 *   09  Header, nav and footer chrome
 *   10  Reduced motion
 *   11  Dark band with a photograph
 *   12  Homepage client logo strip
 *   13  Homepage components
 *   14  Hero furniture
 *   15  Header, dark and over the hero
 *   16  Corrections
 *   17  Matching the static site
 *   18  Footer
 *   19  Contact band
 *   20  Page layout corrections
 *   21  Card grids wrap
 *   22  Interactive diagrams
 *   23  Capability matrix
 *   24  Contact form and verbatim utilities
 *   25  Mobile navigation
 */


/* 01  SECTIONS AND MEASURE
   -------------------------------------------------------------------------- */

/* Sections are full bleed, their inner constrained group carries the
   1272px measure. theme.json sets contentSize, so this only handles the
   vertical rhythm the static site gets from --section-y. */
.wp-site-blocks .opal-section {
	padding-block: 30px;
}

@media (min-width: 992px) {
	.wp-site-blocks .opal-section {
		padding-block: 50px;
	}
}

/* A dark band with a photograph behind it, graded back with a solid
   layer at reduced opacity rather than rgba, the same as the hero. */
.opal-section.has-dark-background-color :is(h1, h2, h3, h4),
.wp-block-cover.is-style-opal-hero :is(h1, h2, h3, h4) {
	color: var(--wp--preset--color--white);
}


/* 02  PAGE HERO
   core/cover, with the image as the cover background and the overlay
   doing the grading. In the static site each photograph carried a
   measured --hero-shade; here the Cover block's own dim control does the
   same job and is adjustable in the editor.
   -------------------------------------------------------------------------- */

/* The band sits flush under the header, so no block gap above it, and
   the interior hero keeps a shallow band with a floor on its height. */
.wp-block-cover.is-style-opal-hero {
	min-height: 0;
	padding-block: 10px;
	align-items: center;
	margin-top: 0;
	margin-block-start: 0;
}

.wp-block-cover.is-style-opal-hero:first-child {
	min-height: 320px;
}

.wp-block-cover.is-style-opal-hero .wp-block-cover__inner-container {
	width: 100%;
	max-width: var(--wp--style--global--content-size);
	margin-inline: auto;
}

.wp-block-cover.is-style-opal-hero :is(h1, h2) {
	max-width: 90ch;
	text-wrap: balance;
	color: var(--wp--preset--color--white);
}

.wp-block-cover.is-style-opal-hero p {
	max-width: 90ch;
	color: var(--wp--preset--color--white);
}

/* The text sits on the left, so the shade only needs full strength
   there. Fading it rightward lets the photograph read without touching
   the contrast behind the heading. Hex with alpha, so still no rgba. */
.wp-block-cover.is-style-opal-hero .wp-block-cover__background {
	-webkit-mask-image: linear-gradient(to right, #000 0%, #000 55%, #000000b3 78%, #00000080 100%);
	mask-image: linear-gradient(to right, #000 0%, #000 55%, #000000b3 78%, #00000080 100%);
}


/* 03  CARDS
   -------------------------------------------------------------------------- */

.wp-block-group.is-style-opal-card,
.wp-block-column.is-style-opal-card,
.wp-block-group.is-style-opal-card-link,
.wp-block-column.is-style-opal-card-link {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 7px;
	padding: 28px;
}

/* Equal heights across a row of cards. */
/* Real grid cells: core gives every column a flex-basis percentage that
   would keep them on one row, so it is overridden in section 22. */
.wp-block-columns.is-style-opal-cards > .wp-block-column {
	display: flex;
	flex-direction: column;
	flex-basis: auto !important;
	width: auto;
}

.wp-block-columns.is-style-opal-cards > .wp-block-column > .wp-block-group {
	flex: 1 1 auto;
}

/* A whole card that is a link. The anchor is on the card's heading,
   because core/group cannot be one and wrapping its children in an
   anchor makes the block invalid in the editor. Stretching that anchor
   over the card keeps the whole card clickable, and keeps one link in
   the accessibility tree rather than wrapping the image and copy in it
   as well. */
.is-style-opal-card-link {
	display: block;
	position: relative;
	transition: border-color .2s ease;
}

.is-style-opal-card-link:hover,
.is-style-opal-card-link:focus-within {
	border-color: var(--wp--preset--color--teal-light);
}

.opal-card__link::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 7px;
}

/* Card imagery. 16:9 in a card, cropped, corners clipped. */
.is-style-opal-card .wp-block-image,
.is-style-opal-card-link .wp-block-image {
	margin-bottom: 18px;
	border-radius: 7px;
	overflow: hidden;
}

.is-style-opal-card .wp-block-image img,
.is-style-opal-card-link .wp-block-image img {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
}

/* Accreditation strip, /insights/awards-and-memberships/. The one card
   image that is a logo lockup rather than a photograph, so the 16:9 crop
   above would slice the three marks down to the middle one. It resets
   that and keeps its own ratio. 1210px is the card's own inner width at
   the 1272px measure, so the strip runs the full measure of the copy
   above it. The supplied artwork is black on transparent,
   the opposite of the white set the footer carries, so it only works on
   the light card behind it. Matches .accred-strip in
   opal-static/css/theme.css. */
.is-style-opal-card .wp-block-image.accred-strip,
.wp-block-image.accred-strip {
	margin-top: 24px;
	margin-bottom: 0;
	max-width: 1210px;
	overflow: visible;
}

.is-style-opal-card .wp-block-image.accred-strip img,
.is-style-opal-card-link .wp-block-image.accred-strip img,
.wp-block-image.accred-strip img {
	width: 100%;
	aspect-ratio: auto;
	object-fit: fill;
}

/* Card title. H4 size regardless of heading level, so nesting stays
   correct without the type jumping about. */
.is-style-opal-card :is(h2, h3, h4),
.is-style-opal-card-link :is(h2, h3, h4) {
	margin-bottom: 12px;
	font-size: var(--wp--preset--font-size--h-4);
	font-weight: 600;
	line-height: 1.35;
	text-wrap: balance;
}

/* The six leadership profile cards: centred, the paragraphs a step
   smaller so six long bios sit in a three-column grid, and the name in
   teal. Mirrors .card--profile in the static theme.css. #428496 is a hair
   off the palette teal (#4C8497) and was specified as such. */
.is-style-opal-card.opal-card--profile {
	text-align: center;
}
.is-style-opal-card.opal-card--profile p {
	font-size: 0.85rem;
}
.is-style-opal-card.opal-card--profile :is(h2, h3, h4) {
	color: #428496;
}


/* 04  TICKS
   -------------------------------------------------------------------------- */

.wp-block-list.is-style-ticks {
	display: grid;
	gap: 10px;
	margin-top: 18px;
	padding: 0;
	list-style: none;
}

.wp-block-list.is-style-ticks li {
	position: relative;
	padding-left: 28px;
	font-size: 0.9375rem;
	line-height: 1.6;
}

.wp-block-list.is-style-ticks li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.55em;
	width: 14px;
	height: 7px;
	border-left: 2px solid var(--wp--preset--color--teal);
	border-bottom: 2px solid var(--wp--preset--color--teal);
	transform: rotate(-45deg);
}

.has-dark-background-color .wp-block-list.is-style-ticks li::before {
	border-color: var(--wp--preset--color--teal-light);
}


/* 05  HEADINGS, EYEBROWS, LEDES
   -------------------------------------------------------------------------- */

/* The short teal rule above a heading. */
.wp-block-heading.is-style-opal-rule {
	position: relative;
	padding-top: 18px;
}

.wp-block-heading.is-style-opal-rule::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	width: 36px;
	height: 3px;
	background: var(--wp--preset--color--teal);
	border-radius: 7px;
}

.wp-block-heading.is-style-opal-accent {
	color: var(--wp--preset--color--teal);
}

.wp-block-heading.is-style-opal-eyebrow {
	margin-bottom: 12px;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--teal);
}

.wp-block-paragraph.is-style-opal-lede,
p.is-style-opal-lede {
	max-width: min(80%, 90ch);
}


/* 06  MEDIA SPLIT
   core/media-text already does the layout and the flip, so this only
   restates the OPAL proportions and image crop.
   -------------------------------------------------------------------------- */

.wp-block-media-text.is-style-opal-split {
	gap: 28px;
	align-items: center;
	margin-bottom: 20px;
	grid-template-columns: 1fr;
}

.wp-block-media-text.is-style-opal-split .wp-block-media-text__media img {
	width: 100%;
	height: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	display: block;
	border-radius: 7px;
}

.wp-block-media-text.is-style-opal-split .wp-block-media-text__content {
	padding: 0;
}

.wp-block-media-text.is-style-opal-split .wp-block-media-text__content > * + * {
	margin-top: 14px;
}

@media (min-width: 768px) {
	.wp-block-media-text.is-style-opal-split {
		grid-template-columns: 35fr 65fr;
		gap: 48px;
	}

	.wp-block-media-text.is-style-opal-split.has-media-on-the-right {
		grid-template-columns: 65fr 35fr;
	}

	.wp-block-media-text.is-style-opal-split .wp-block-media-text__media img {
		aspect-ratio: 5 / 4;
	}
}


/* 07  CTA CARD, MINI, JUMP LINKS
   -------------------------------------------------------------------------- */

.wp-block-group.is-style-opal-cta-card {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 20px;
	margin-top: 24px;
	padding: 28px;
	background: var(--wp--preset--color--off-white);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 7px;
}

.wp-block-group.is-style-opal-mini {
	padding-left: 18px;
	border-left: 2px solid var(--wp--preset--color--teal-light);
}

.wp-block-list.is-style-opal-jump {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	padding: 0;
	list-style: none;
}

.wp-block-list.is-style-opal-jump a {
	display: inline-block;
	padding: 8px 16px;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 7px;
	background: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	color: var(--wp--preset--color--grey);
}

.wp-block-list.is-style-opal-jump a:hover,
.wp-block-list.is-style-opal-jump a:focus-visible {
	border-color: var(--wp--preset--color--teal);
	color: var(--wp--preset--color--teal-dark);
	text-decoration: none;
}


/* 08  BUTTONS
   theme.json styles the default button. This adds the two variants the
   static site uses on dark grounds and on the brand gradient.

   CONTRAST NOTE, carried across from the static site deliberately:
   white on teal measures 4.15:1, and white on the teal-light hover state
   measures 2.20:1. Both sit below the 4.5:1 AA asks of text this size.
   Built to the written specification.
   -------------------------------------------------------------------------- */

.wp-block-button.is-style-outline .wp-block-button__link {
	background: none;
	border: 1px solid var(--wp--preset--color--white);
	color: var(--wp--preset--color--white);
}

.wp-block-button.is-style-outline .wp-block-button__link:hover,
.wp-block-button.is-style-outline .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--dark);
}


/* 09  HEADER, NAV AND FOOTER CHROME
   The header part is core blocks, so this styles what those blocks
   render rather than any bespoke markup.
   -------------------------------------------------------------------------- */

.opal-header .wp-block-navigation {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
}

.opal-header .wp-block-navigation .wp-block-navigation__submenu-container {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 7px;
	padding: 8px 0;
}

/* The chrome's three logos are theme assets rather than media library
   items, so nothing adds intrinsic dimensions for them at render time.
   core/image writes its size as a width with height:auto, so the ratio
   is given here instead and the images reserve their space before they
   load. Source files are 141x58 and 500x86. */
.opal-header__brand img,
.opal-footer .wp-block-image img {
	aspect-ratio: 141 / 58;
}

/* The brand mark, sized as .site-header__logo sizes it in opal-static.
   The block carries no width of its own, so this is the only thing
   setting it and there is no inline style to fight. */
.opal-header__brand img {
	max-height: 36px;
	width: auto;
}

.opal-footer .opal-footer__accred img {
	aspect-ratio: 500 / 86;
}

.opal-footer .opal-footer__accred {
	margin-bottom: 20px;
}

.opal-footer {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
}

.opal-footer :is(h1, h2, h3, h4) {
	color: var(--wp--preset--color--white);
}

/* The contact band above the footer, on the brand gradient. */
.opal-cta-band {
	background: var(--wp--preset--gradient--brand);
	color: var(--wp--preset--color--white);
}

.opal-cta-band :is(h1, h2, h3, h4) {
	color: var(--wp--preset--color--white);
}


/* 10  REDUCED MOTION
   The logo strip has its own rule beside its animation, in section 13.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}
}


/* 11  DARK BAND WITH A PHOTOGRAPH
   The homepage "who we are" band. Same treatment as the hero: a solid
   dark layer at a measured opacity over the picture, never rgba.
   -------------------------------------------------------------------------- */

.wp-block-cover.is-style-opal-band :is(h1, h2, h3, h4),
.wp-block-cover.is-style-opal-band p,
.wp-block-cover.is-style-opal-band li {
	color: var(--wp--preset--color--white);
}

.wp-block-cover.is-style-opal-band .wp-block-cover__inner-container {
	width: 100%;
	max-width: var(--wp--style--global--content-size);
	margin-inline: auto;
}


/* 12  HOMEPAGE CLIENT LOGO STRIP
   The markup comes across from the static site unchanged inside an HTML
   block, so it keeps the original class names rather than the block ones.
   These rules are the static site's own, ported.

   The logos are white on transparent, so they only read on a dark ground.
   That is why the strip sits inside the hero rather than on white.
   -------------------------------------------------------------------------- */

.hero__logos {
	margin-top: 32px;
}

.hero__logos-label {
	margin-bottom: 12px;
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--teal-light);
}

.hero__logos-list {
	display: flex;
	align-items: center;
	gap: 22px var(--logo-gap);
	margin: 0;
	padding: 0;
	list-style: none;
	flex-wrap: nowrap;
	/* Translated by exactly one list width plus the gap, so the pair of
	   identical lists loops seamlessly. */
	animation: opal-hero-logos 46s linear infinite;
}

.hero__logos-list li::marker {
	content: "";
}

.hero__logos-item {
	flex: 0 0 auto;
	list-style: none;
}

.hero__logos-img {
	display: block;
	height: 45px;
	width: auto;
}

@media (max-width: 767px) {
	.hero__logos-img {
		height: 32px;
	}
}


/* 13  HOMEPAGE COMPONENTS
   Stats, pillars, case teasers and the band intro. These carry their own
   card and colour treatment in the static site, so they need it here too.
   Values ported from opal-static/css/theme.css sections 12 to 16.
   -------------------------------------------------------------------------- */

.wp-block-group.opal-stat {
	text-align: center;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 7px;
	padding: 28px;
	height: 100%;
}

.opal-stat .wp-block-image {
	margin-bottom: 18px;
	border-radius: 7px;
	overflow: hidden;
}

.opal-stat .wp-block-image img {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
}

.opal-stat__figure {
	font-size: var(--wp--preset--font-size--h-1);
	font-weight: 600;
	line-height: 1.15;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--dark);
}

.opal-stat__label {
	margin-top: 8px;
	text-wrap: balance;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5;
	color: var(--wp--preset--color--grey);
}

.wp-block-group.opal-pillar {
	background: var(--wp--preset--color--dark-1);
	border: 1px solid var(--wp--preset--color--teal);
	border-radius: 7px;
	padding: 28px;
	color: var(--wp--preset--color--white);
	height: 100%;
}

.opal-pillar p {
	color: var(--wp--preset--color--white);
}

.opal-pillar__lead {
	display: block;
	margin-bottom: 8px;
	font-weight: 700;
	color: var(--wp--preset--color--white);
}

.wp-block-group.opal-case {
	padding: 0;
	overflow: hidden;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 7px;
	height: 100%;
	/* A column, so the read link can be pinned to the bottom of a card
	   whose copy is shorter than its neighbours'. Stretch because the
	   constrained layout's auto side margins would otherwise centre any
	   child narrower than the card, leaving short titles indented. */
	display: flex;
	flex-direction: column;
	align-items: stretch;
}

/* Full width so a short title is not centred, and border-box so the 20px
   of side padding these children carry counts inside that width rather
   than being added to it. Without the box-sizing the text ran 40px past
   the card edge. */
.opal-case > * {
	margin-left: 0;
	margin-right: 0;
	max-width: none;
	width: 100%;
	box-sizing: border-box;
}

/* .case__body in opal-static is a flex column with a 12px gap, inside a
   20px padding. The block markup here is flat, with no body wrapper, so
   the 12px gap goes on the card and the first content child makes up the
   difference: 12 + 8 lands the heading the same 20px below the image.
   Without this the card takes the global 24px blockGap and stands taller
   than its static twin. */
.wp-block-group.opal-case {
	gap: 12px;
}

.opal-case > * {
	margin-top: 0;
	margin-bottom: 0;
}

.opal-case .wp-block-image {
	margin: 0;
}

.opal-case > .wp-block-image {
	flex: 0 0 auto;
}

/* Reserving the title and teaser space means the image, heading, copy
   and read link sit at the same height across the row without the copy
   having to be padded to match. Card 02 has a one line title where 01
   and 03 run to two, so the title reserves both. Values match .case h3
   and .case__text in opal-static/css/theme.css. */
.opal-case > :is(h2, h3, h4) {
	/* core emits the preset size classes as !important, so matching the
	   static 1.2rem takes one back. */
	font-size: 1.2rem !important;
	min-height: 3.45rem;
}

.opal-case > .opal-case__text {
	flex: 1 1 auto;
	min-height: calc(6 * 1.65em);
}

.opal-case > .opal-link-arrow {
	flex: 0 0 auto;
	margin-top: 0;
}

.opal-case .wp-block-image img {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
	border-bottom: 1px solid var(--wp--preset--color--border);
}

.opal-case > :not(.wp-block-image) {
	padding-inline: 20px;
}

/* :first-of-type would match the first of each element type, so the
   heading and the teaser paragraph both took the 20px and the card ran
   20px taller than the static one. */
.opal-case > :not(.wp-block-image):first-child,
.opal-case > .wp-block-image:first-child + * {
	padding-top: 8px;
}

.opal-case > :last-child {
	padding-bottom: 20px;
}

.wp-block-group.opal-band-intro {
	max-width: min(80%, 90ch);
	margin: 0 auto 36px;
	text-align: center;
}

.opal-band-intro :is(h1, h2, h3, h4),
.opal-band-intro p {
	color: var(--wp--preset--color--white);
}


/* 14  HERO FURNITURE
   The eyebrow pill and the teal strapline. Both sit inside the cover.
   -------------------------------------------------------------------------- */

p.opal-hero__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 20px;
	padding: 6px 16px;
	border: 1px solid var(--wp--preset--color--teal-light);
	border-radius: 7px;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--white);
	max-width: none;
}

p.opal-hero__eyebrow::before {
	content: "";
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--wp--preset--color--teal-light);
	flex: 0 0 auto;
}

p.opal-hero__strapline {
	margin-top: 16px;
	color: var(--wp--preset--color--teal-light);
	font-size: var(--wp--preset--font-size--h-3);
	font-weight: 600;
	line-height: 1.3;
}


/* 15  HEADER, DARK AND OVER THE HERO
   The static header is dark, sticky, and sits on the hero rather than
   above it, with Contact Us as a filled button.
   -------------------------------------------------------------------------- */

.opal-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--wp--preset--color--dark);
	/* Same colour as the bar until scrolled, so adding the border later
	   cannot shift the layout. script.js sets .is-scrolled past 40px. */
	border-bottom: 1px solid var(--wp--preset--color--dark);
	transition: border-color .2s ease;
}

.opal-header.is-scrolled {
	border-bottom-color: var(--wp--preset--color--teal-light);
}

.opal-header .wp-block-navigation .wp-block-navigation-item__content {
	color: var(--wp--preset--color--white);
}

.opal-header .wp-block-navigation .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--teal-light);
}

/* The last top level item is Contact Us, which is a button on the static
   site. Targeting the last item keeps it working if the label changes. */
.opal-header .wp-block-navigation__container > .wp-block-navigation-item:last-child > .wp-block-navigation-item__content {
	background: var(--wp--preset--color--teal);
	color: var(--wp--preset--color--white);
	padding: 11px 22px;
	border-radius: 7px;
}

.opal-header .wp-block-navigation__container > .wp-block-navigation-item:last-child > .wp-block-navigation-item__content:hover {
	background: var(--wp--preset--color--teal-light);
	color: var(--wp--preset--color--white);
}

.opal-header .wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	color: var(--wp--preset--color--grey);
}


/* 16  CORRECTIONS
   Two rules that lost to earlier, more specific selectors.
   -------------------------------------------------------------------------- */

/* The cover's blanket white on paragraphs was beating the strapline, which
   is teal on the static site. Matched at the same depth so it wins. */
.wp-block-cover.is-style-opal-hero p.opal-hero__strapline {
	color: var(--wp--preset--color--teal-light);
}

/* The logo strip is two lists, the second aria-hidden and duplicated for
   the scroll effect. They must sit side by side on one line, clipped by
   the viewport, not stack as a second row. Ends are faded so marks enter
   rather than pop. */
.hero__logos-viewport {
	--logo-gap: 26px;
	display: flex;
	gap: 22px var(--logo-gap);
	overflow: hidden;
	-webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
	mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
}

.hero__logos-viewport > .hero__logos-list {
	flex: 0 0 auto;
}

/* The paragraph form of the eyebrow, above a card title. Same treatment
   as .micro-heading, which is a heading and picks up the block style. */
p.opal-eyebrow {
	margin-bottom: 12px;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--teal);
}


/* 17  MATCHING THE STATIC SITE
   Raised after a side by side comparison. Values ported from
   opal-static/css/theme.css rather than guessed.
   -------------------------------------------------------------------------- */

/* 17.1  Header: one fixed height rather than block padding, and sticky.
   The static bar is 80px tall with no padding of its own. */
.wp-block-group.opal-header {
	padding-top: 0;
	padding-bottom: 0;
	position: sticky;
	top: 0;
	z-index: 100;
}

.opal-header > .wp-block-group {
	min-height: 80px;
	align-items: center;
}

/* The admin bar is fixed on the front end for logged in users, so a
   sticky header needs to start below it rather than under it. */
.admin-bar .wp-block-group.opal-header {
	top: 32px;
}

@media (max-width: 782px) {
	.admin-bar .wp-block-group.opal-header {
		top: 46px;
	}
}

/* 17.2  No gap between the header and the cover. */
main.wp-block-group > .wp-block-cover:first-child {
	margin-top: 0;
}


@keyframes opal-hero-logos {
	from {
		transform: translateX(0);
	}

	to {
		transform: translateX(calc(-100% - var(--logo-gap)));
	}
}

@media (prefers-reduced-motion: reduce) {
	.hero__logos-list {
		animation: none;
	}
}

/* 17.3  Testimonial. The markup comes across verbatim, so these are the
   static site's own selectors. */
.testimonial {
	display: grid;
	gap: 48px;
	align-items: center;
}

@media (min-width: 992px) {
	.testimonial {
		grid-template-columns: auto 1fr;
	}
}

/* A teal block sits behind the portrait, offset left and down so it
   reads as a wrap on two sides. The wrapper is sized by the picture, so
   the block tracks whatever height the picture is given. */
.testimonial__media {
	position: relative;
	margin-left: 16px;
	width: auto;
	max-width: 100%;
}

.testimonial__media::before {
	content: "";
	position: absolute;
	left: -16px;
	top: 16px;
	width: 100%;
	height: 100%;
	background: var(--wp--preset--color--teal);
	border-radius: 7px;
}

/* Above the teal block, and 215px tall with the width following the
   image's own 500 by 392 ratio so it is not stretched. */
.testimonial__img {
	display: block;
	position: relative;
	z-index: 1;
	height: 215px;
	width: auto;
	aspect-ratio: 500 / 392;
	object-fit: cover;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 7px;
}

.testimonial__eyebrow {
	margin-bottom: 16px;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--teal);
}

.testimonial__quote blockquote {
	margin: 0;
	padding: 0;
	border: 0;
}

.testimonial__quote blockquote p {
	font-size: var(--wp--preset--font-size--h-3);
	font-weight: 400;
	line-height: 1.3;
	color: var(--wp--preset--color--grey);
}

.testimonial__attrib {
	margin-top: 24px;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5;
	color: var(--wp--preset--color--grey);
}

.testimonial__flag {
	display: inline-block;
	margin-left: 10px;
	padding: 2px 8px;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 7px;
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--teal-dark);
	vertical-align: middle;
}

/* 17.4  Links in body copy: teal and bold, as the static site has them.
   Chrome and buttons are excluded, they carry their own treatment. */
.wp-site-blocks main a:where(:not(.wp-block-button__link):not(.wp-element-button)) {
	color: var(--wp--preset--color--teal-dark);
	font-weight: 600;
}

.wp-site-blocks main a:where(:not(.wp-block-button__link):not(.wp-element-button)):hover {
	text-decoration: underline;
}

/* The card that is entirely a link must not turn its whole contents bold.
   The body link rule above is (0,1,2), so these have to carry at least
   two classes to beat it. Without the .wp-site-blocks main prefix the
   card link rule lost and every card read teal and semibold.

   The contact band's button is excluded the same way the body link rule
   excludes it. Without that exclusion this rule, at (0,2,1), beat the
   white-on-teal button rule below at (0,2,0), and the button inherited
   the band's white text onto its own white background: invisible on
   every page. :where() adds no specificity, so the card and jump link
   selectors are unchanged. */
.wp-site-blocks main .is-style-opal-card-link a,
.wp-site-blocks main .wp-block-list.is-style-opal-jump a,
.wp-site-blocks .opal-cta-band a:where(:not(.wp-block-button__link):not(.wp-element-button)) {
	font-weight: inherit;
	color: inherit;
}


/* 18  FOOTER
   Ported from opal-static section 19. The footer was reading too large
   across the board, the quick links had no chevrons and no rhythm, and
   the contact block had lost its icons.
   -------------------------------------------------------------------------- */

.wp-block-group.opal-footer {
	padding-top: 72px;
	padding-bottom: 32px;
}

/* Body copy in the footer is a step down from the site's base size. */
.opal-footer p,
.opal-footer li {
	font-size: 0.9rem;
	line-height: 1.6;
}

.opal-footer .opal-footer__blurb {
	max-width: 34ch;
	font-size: 0.8125rem;
}

/* Column headings: small, uppercase, teal, with real space beneath. */
.opal-footer :is(h2, h3, h4) {
	margin-bottom: 30px;
	font-size: 0.9rem;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--teal-light);
}

/* Quick links: a chevron column, then the label. */
.opal-footer .opal-footer__links {
	padding: 0;
	list-style: none;
}

.opal-footer .opal-footer__links li + li {
	margin-top: 12px;
}

.opal-footer .opal-footer__links a {
	display: grid;
	grid-template-columns: 12px 1fr;
	gap: 9px;
	align-items: start;
	font-size: 0.875rem;
	line-height: 1.5;
	color: var(--wp--preset--color--white);
	text-decoration: none;
}

.opal-footer .opal-footer__links a:hover {
	text-decoration: underline;
}

.opal-footer .site-footer__chev {
	margin-top: 5px;
	color: var(--wp--preset--color--teal-light);
	transition: transform .2s ease;
}

.opal-footer .opal-footer__links a:hover .site-footer__chev {
	transform: translateX(2px);
}

/* Contact block: icon column, then the detail, a step down in size from
   the quick links beside it. */
.opal-footer .opal-footer__contact,
.opal-footer .opal-footer__contact li,
.opal-footer .opal-footer__contact a,
.opal-footer .site-footer__addr {
	font-size: 0.8125rem;
}

.opal-footer .opal-footer__contact {
	padding: 0;
	list-style: none;
}

.opal-footer .opal-footer__contact li + li {
	margin-top: 14px;
}

.opal-footer .opal-footer__ci {
	display: grid;
	grid-template-columns: 15px 1fr;
	gap: 10px;
	align-items: start;
}

.opal-footer .site-footer__icon {
	margin-top: 4px;
	color: var(--wp--preset--color--teal-light);
	flex: 0 0 auto;
}

.opal-footer .site-footer__addr {
	display: block;
	line-height: 1.6;
}

/* Footer links generally are underlined, so they read as links on the
   dark ground where colour alone is not enough. */
.opal-footer a {
	color: var(--wp--preset--color--white);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.opal-footer a:hover {
	color: var(--wp--preset--color--teal-light);
}

.opal-footer .opal-footer__accred-text {
	margin-top: 16px;
	font-size: 0.8125rem;
	line-height: 1.6;
}

/* The legal line: one step below the footer's own size, centred, and
   separated by a rule. */
.opal-footer .opal-footer__legal {
	margin-top: 48px;
	padding-top: 24px;
	border-top: 1px solid var(--wp--preset--color--grey);
	font-size: 0.75rem;
	line-height: 1.6;
	color: var(--wp--preset--color--white);
	text-align: center;
	width: 90%;
	max-width: var(--wp--style--global--content-size);
	margin-inline: auto;
}


/* 19  CONTACT BAND
   The static band is the brand gradient over a photograph, not a flat
   colour. The Cover's own dim is a solid, so the gradient is layered on
   top of it here at the same 90% the static site uses.
   -------------------------------------------------------------------------- */

.wp-block-cover.opal-cta-band {
	text-align: center;
}

.wp-block-cover.opal-cta-band .wp-block-cover__background {
	background: linear-gradient(133deg,
		color-mix(in srgb, var(--wp--preset--color--teal-light) 60%, var(--wp--preset--color--dark)),
		color-mix(in srgb, var(--wp--preset--color--teal) 60%, var(--wp--preset--color--dark)));
	opacity: .90;
}

.opal-cta-band :is(h1, h2, h3, h4),
.opal-cta-band p {
	color: var(--wp--preset--color--white);
}

.opal-cta-band .opal-cta-band__text {
	margin-top: 16px;
	max-width: 90ch;
	margin-inline: auto;
}

/* White button on the gradient. */
.opal-cta-band .wp-block-button__link {
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--teal);
	border-color: var(--wp--preset--color--white);
}

.opal-cta-band .wp-block-button__link:hover,
.opal-cta-band .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--off-white);
	color: var(--wp--preset--color--teal);
}


/* 19.1  WordPress's constrained layout sets margin-left and margin-right to
   auto with !important, which centred the hero lede against its own
   heading. The static hero is one left aligned column, so the auto
   margins have to be beaten at the same weight. */
.wp-block-cover.is-style-opal-hero .wp-block-cover__inner-container > * {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

/* The flow layout was putting a gap above the first block on the page,
   which showed as a white strip between the header and the hero. */
main.wp-block-group,
main.wp-block-group > .entry-content,
main.wp-block-group > .entry-content > :first-child {
	margin-top: 0;
	margin-block-start: 0;
}

/* The legal line was inheriting the footer's full width rather than the
   site measure, so it ran wider than everything above it. */

/* 20  PAGE LAYOUT CORRECTIONS
   Four places where core's own layout rules had to be answered directly.
   -------------------------------------------------------------------------- */

/* No gaps between the top level bands. The root flow layout was
   putting its 24px block gap between the header, the hero, the contact
   band and the footer, which showed as white strips. Those four sit
   flush against each other on the static site. */
.wp-site-blocks > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

main.wp-block-group > .entry-content > * + * {
	margin-block-start: 0;
}


/* The header template part is wrapped in a div that is exactly as tall
   as the header itself, so a sticky header had no room to travel inside
   its own containing block and simply scrolled away. Taking the wrapper
   out of the layout makes .wp-site-blocks the containing block, which is
   the full page height. */
.wp-site-blocks > .wp-block-template-part:has(> .opal-header) {
	display: contents;
}

/* Footer column headings were inheriting whichever preset size the
   pattern carried. One size for all of them, whatever the level. */
.opal-footer :is(h1, h2, h3, h4, h5, h6) {
	font-size: 0.9rem;
}

/* Submenu chevron: white on the dark bar, small, outline only. */
.opal-header .wp-block-navigation__submenu-icon {
	color: var(--wp--preset--color--white);
}

.opal-header .wp-block-navigation__submenu-icon svg {
	width: 10px;
	height: 10px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
}

/* The cover's blanket white on paragraphs outranks a single class, the
   same way it did for the strapline. Matched at the same depth. */
.wp-block-cover.is-style-opal-hero .hero__logos-label {
	color: var(--wp--preset--color--teal-light);
}


/* 21  CARD GRIDS WRAP
   core/columns puts every child on a single row, so a nine card section
   came out as nine columns 125px wide instead of three rows of three.
   These are real grids, with the static site's own breakpoints: one
   column on a phone, two from 768, then the intended count from 992.
   -------------------------------------------------------------------------- */

.wp-block-columns.is-style-opal-cards {
	display: grid;
	grid-template-columns: 1fr;
	gap: 24px;
	align-items: stretch;
}

@media (min-width: 768px) {
	.wp-block-columns.is-style-opal-cards {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 992px) {
	.wp-block-columns.is-style-opal-cards.opal-cards--2 {
		grid-template-columns: repeat(2, 1fr);
	}

	.wp-block-columns.is-style-opal-cards.opal-cards--3 {
		grid-template-columns: repeat(3, 1fr);
	}

	.wp-block-columns.is-style-opal-cards.opal-cards--4 {
		grid-template-columns: repeat(4, 1fr);
	}
}

/* The mini grid follows the same idea: two up from 768, three from 992. */
.wp-block-columns.opal-mini-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 20px;
	margin-top: 50px;
}

@media (min-width: 768px) {
	.wp-block-columns.opal-mini-grid {
		grid-template-columns: repeat(2, 1fr);
		gap: 24px;
	}
}

@media (min-width: 992px) {
	.wp-block-columns.opal-mini-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

.wp-block-columns.opal-mini-grid > .wp-block-column {
	flex-basis: auto !important;
	width: auto;
}


/* 22  INTERACTIVE DIAGRAMS
   Ported wholesale from opal-static/css/theme.css section 23. The two
   diagrams come across as verbatim markup inside core/html blocks and
   js/script.js drives anything carrying data-dgm, but without this the
   markup had no styling at all, so they rendered as a flat list.
   Only the palette variables are changed, to the theme's own tokens.

   Two diagrams built from the client's reference artwork
   the Pandora Platform and Ecosystem diagrams:

     .dgm--platform  three solution circles feeding one platform lens,
                     with the eight shared capabilities as bubbles
     .dgm--hub       sixteen modules on a ring around the core platform

   Both are tablists. Every panel ships visible, so with JS off the page
   still reads as a full list of nodes and descriptions.

   Geometry is CSS only: the ring uses one custom property per node and
   the connectors are static SVG, so nothing is measured at runtime and
   nothing redraws on resize.
   -------------------------------------------------------------------------- */

.dgm{
  border:1px solid var(--wp--preset--color--border);
  border-radius:7px;
  background:var(--wp--preset--color--off-white);
  padding:24px 20px;
}

.dgm__head{margin-bottom:8px;text-align:center}
.dgm__head-title{
  font-size:clamp(1.3125rem,1.15rem + 0.8vw,1.75rem);
  font-weight:700;
  line-height:1.25;
  letter-spacing:-0.01em;
  color:var(--wp--preset--color--dark);
  text-wrap:balance;
}
.dgm__head-accent{color:var(--wp--preset--color--teal)}
.dgm__head-text{margin:10px auto 0;max-width:56ch;font-size:0.9375rem;color:var(--wp--preset--color--grey)}

@media (min-width:768px){.dgm{padding:36px 32px}}


/* -- Solution circles ------------------------------------------------------
   Round nodes with a tinted fill and a coloured ring, per the artwork.
   color-mix keeps the tints derived from the tokens rather than adding
   new colours; the flat background before it is the fallback.
   -------------------------------------------------------------------------- */

.dgm--platform .dgm__sols{display:grid;gap:20px;margin-top:28px}

.dgm__sol{
  display:flex;
  align-items:center;
  justify-content:center;
  padding:26px;
  border:1px solid var(--wp--preset--color--teal);
  border-radius:7px;
  background:var(--wp--preset--color--white);
  text-align:center;
}
.dgm__sol-inner{display:block;max-width:30ch}

.dgm__sol-icon{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:52px;
  height:52px;
  margin-bottom:14px;
  border-radius:50%;
  background:var(--wp--preset--color--white);
  color:var(--wp--preset--color--teal);
}
.dgm__sol-title{
  font-size:1.0625rem;
  font-weight:700;
  line-height:1.3;
  color:var(--wp--preset--color--dark);
}
.dgm__sol-rule{
  display:block;
  width:34px;
  height:2px;
  margin:10px auto;
  background:var(--wp--preset--color--teal);
  border-radius:7px;
}
.dgm__sol-text{
  display:block;
  font-size:0.8125rem;
  line-height:1.6;
  color:var(--wp--preset--color--grey);
}

/* Three tokens for three solutions, so each stays identifiable. */
/* --mid is the default accent, stated so the set of three is explicit. */
.dgm__sol--mid{border-color:var(--wp--preset--color--teal)}
.dgm__sol--mid .dgm__sol-icon{color:var(--wp--preset--color--teal)}
.dgm__sol--mid .dgm__sol-rule{background:var(--wp--preset--color--teal)}
.dgm__sol--light{border-color:var(--wp--preset--color--teal-light)}
.dgm__sol--light .dgm__sol-icon{color:var(--wp--preset--color--teal-light)}
.dgm__sol--light .dgm__sol-rule{background:var(--wp--preset--color--teal-light)}
.dgm__sol--warm{border-color:var(--wp--preset--color--teal-dark)}
.dgm__sol--warm .dgm__sol-icon{color:var(--wp--preset--color--teal-dark)}
.dgm__sol--warm .dgm__sol-rule{background:var(--wp--preset--color--teal-dark)}

@media (min-width:768px){
  .dgm--platform .dgm__sols{grid-template-columns:repeat(3,1fr);gap:24px}
  /* Circular from here up, where there is room for the text inside. */
  .dgm__sol{
    aspect-ratio:1;
    border-radius:50%;
    padding:34px;
    background:var(--wp--preset--color--white);
    background:radial-gradient(circle at 50% 34%,
      color-mix(in srgb,var(--wp--preset--color--teal) 12%,var(--wp--preset--color--white)) 0%,
      var(--wp--preset--color--white) 72%);
  }
  .dgm__sol--light{
    background:radial-gradient(circle at 50% 34%,
      color-mix(in srgb,var(--wp--preset--color--teal-light) 14%,var(--wp--preset--color--white)) 0%,
      var(--wp--preset--color--white) 72%);
  }
  .dgm__sol--warm{
    background:radial-gradient(circle at 50% 34%,
      color-mix(in srgb,var(--wp--preset--color--teal-dark) 10%,var(--wp--preset--color--white)) 0%,
      var(--wp--preset--color--white) 72%);
  }
  .dgm__sol-icon{background:var(--wp--preset--color--off-white)}
}


/* -- Dashed arrows down into the lens -------------------------------------- */

.dgm--platform .dgm__arrows{display:none}

@media (min-width:768px){
  .dgm--platform .dgm__arrows{
    display:grid;
    grid-template-columns:repeat(3,1fr);
    gap:24px;
    height:56px;
    margin-top:-6px;
  }
  .dgm__arrow{
    justify-self:center;
    width:12px;
    height:100%;
  }
  .dgm__arrow line{
    stroke:var(--wp--preset--color--teal);
    stroke-width:2;
    stroke-dasharray:5 5;
  }
  .dgm__arrow polygon{fill:var(--wp--preset--color--teal)}
  .dgm__arrows .dgm__arrow:nth-child(1) line{stroke:var(--wp--preset--color--teal-light)}
  .dgm__arrows .dgm__arrow:nth-child(1) polygon{fill:var(--wp--preset--color--teal-light)}
  .dgm__arrows .dgm__arrow:nth-child(3) line{stroke:var(--wp--preset--color--teal-dark)}
  .dgm__arrows .dgm__arrow:nth-child(3) polygon{fill:var(--wp--preset--color--teal-dark)}
}


/* -- The platform lens ------------------------------------------------------ */

.dgm--platform .dgm__lens{
  margin-top:24px;
  padding:28px 20px;
  border:1px dashed var(--wp--preset--color--border);
  border-radius:7px;
  background:var(--wp--preset--color--white);
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--wp--preset--color--teal-light) 10%,var(--wp--preset--color--white)) 0%,
    var(--wp--preset--color--white) 100%);
  text-align:center;
}
.dgm__band-title{
  font-size:clamp(1rem,0.9rem + 0.5vw,1.375rem);
  font-weight:700;
  letter-spacing:0.22em;
  text-transform:uppercase;
  color:var(--wp--preset--color--dark);
}
.dgm__band-text{
  margin-top:8px;
  font-size:0.875rem;
  font-weight:600;
  color:var(--wp--preset--color--teal);
}

@media (min-width:768px){
  .dgm--platform .dgm__lens{
    margin-top:0;
    padding:40px 32px 44px;
    border-radius:50% / 14%;
  }
}


/* -- Capability bubbles ----------------------------------------------------- */

.dgm--platform .dgm__bubs{display:grid;gap:14px;margin-top:8px}
.dgm__bub-row{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:14px;
}

.dgm__bub{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:6px;
  width:104px;
  height:104px;
  padding:8px;
  border:1px solid var(--wp--preset--color--border);
  border-radius:50%;
  background:var(--wp--preset--color--white);
  color:var(--wp--preset--color--grey);
  text-align:center;
  transition:border-color .2s ease,color .2s ease,transform .2s ease;
}
.dgm__bub-icon{display:inline-flex;color:var(--wp--preset--color--teal);transition:color .2s ease}
.dgm__bub-label{font-size:0.6875rem;font-weight:600;line-height:1.25}

.dgm__bub:hover{border-color:var(--wp--preset--color--teal-light);color:var(--wp--preset--color--dark)}
.dgm__bub[aria-selected="true"]{
  border-color:var(--wp--preset--color--teal);
  background:var(--wp--preset--color--teal);
  color:var(--wp--preset--color--white);
}
.dgm__bub[aria-selected="true"] .dgm__bub-icon{color:var(--wp--preset--color--white)}

@media (min-width:576px){
  .dgm__bub{width:118px;height:118px;gap:8px}
  .dgm__bub-label{font-size:0.75rem}
}


/* -- Ecosystem wheel --------------------------------------------------------
   Below 768px a ring of sixteen is unreadable, so the same buttons fall
   back to a plain wrapped list with visible names.
   -------------------------------------------------------------------------- */

.dgm--hub .dgm__wheel{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:10px;
}
.dgm--hub .dgm__wires{display:none}

.dgm__spoke,
.dgm__core{
  display:flex;
  align-items:center;
  gap:10px;
  padding:10px 14px;
  border:1px solid var(--wp--preset--color--border);
  border-radius:7px;
  background:var(--wp--preset--color--white);
  color:var(--wp--preset--color--grey);
  text-align:left;
  transition:border-color .2s ease,background-color .2s ease,color .2s ease;
}
.dgm__spoke-icon,
.dgm__core-icon{display:inline-flex;flex:0 0 auto;color:var(--wp--preset--color--teal)}
.dgm__spoke-name,
.dgm__core-name{font-size:0.8125rem;font-weight:600;line-height:1.3}

.dgm__spoke:hover,
.dgm__core:hover{border-color:var(--wp--preset--color--teal-light);color:var(--wp--preset--color--dark)}
.dgm__spoke[aria-selected="true"],
.dgm__core[aria-selected="true"]{
  border-color:var(--wp--preset--color--teal);
  background:var(--wp--preset--color--teal);
  color:var(--wp--preset--color--white);
}
.dgm__spoke[aria-selected="true"] .dgm__spoke-icon,
.dgm__core[aria-selected="true"] .dgm__core-icon{color:var(--wp--preset--color--white)}

@media (min-width:768px){
  .dgm--hub .dgm__wheel{
    display:block;
    position:relative;
    width:min(100%,620px);
    margin-inline:auto;
    aspect-ratio:1;
  }
  .dgm--hub .dgm__wires{
    display:block;
    position:absolute;
    inset:0;
    width:100%;
    height:100%;
  }
  .dgm__wires line{
    stroke:var(--wp--preset--color--teal-light);
    stroke-width:0.5;
  }
  .dgm__wires path{fill:var(--wp--preset--color--teal-light)}

  /* One custom property per node does the placement: rotate out to the
     ring, then counter-rotate so the node itself stays upright. */
  .dgm__spoke{
    position:absolute;
    top:50%;
    left:50%;
    width:64px;
    height:64px;
    padding:0;
    border-radius:50%;
    justify-content:center;
    /* Fallback first for anything without container query units. */
    transform:
      translate(-50%,-50%)
      rotate(var(--a))
      translate(225px)
      rotate(calc(var(--a) * -1));
    transform:
      translate(-50%,-50%)
      rotate(var(--a))
      translate(37cqw)
      rotate(calc(var(--a) * -1));
  }
  .dgm--hub .dgm__wheel{container-type:inline-size}
  /* Only the active node shows its name, so the ring stays readable
     instead of carrying sixteen labels at once. The name is still in the
     accessibility tree for every node. */
  .dgm__spoke-name{
    position:absolute;
    top:calc(100% + 6px);
    left:50%;
    transform:translateX(-50%);
    max-width:150px;
    padding:4px 9px;
    border:1px solid var(--wp--preset--color--border);
    border-radius:7px;
    background:var(--wp--preset--color--white);
    color:var(--wp--preset--color--dark);
    font-size:0.6875rem;
    line-height:1.3;
    text-align:center;
    white-space:normal;
    opacity:0;
    pointer-events:none;
    transition:opacity .15s ease;
  }
  .dgm__spoke:hover .dgm__spoke-name,
  .dgm__spoke:focus-visible .dgm__spoke-name,
  .dgm__spoke[aria-selected="true"] .dgm__spoke-name{opacity:1}
  /* The active node's label can overlap its neighbours, so lift it. */
  .dgm__spoke:hover,
  .dgm__spoke:focus-visible,
  .dgm__spoke[aria-selected="true"]{z-index:2}

  .dgm__core{
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%,-50%);
    flex-direction:column;
    gap:6px;
    width:140px;
    height:140px;
    border-radius:50%;
    border-color:var(--wp--preset--color--teal);
    justify-content:center;
    text-align:center;
  }
  .dgm__core-name{font-size:0.875rem}
}


/* -- Hint and panels, shared ------------------------------------------------ */

.dgm__hint{
  margin:22px 0 14px;
  font-size:0.875rem;
  color:var(--wp--preset--color--grey);
  text-align:center;
}

.dgm__panels{margin-top:22px}
.dgm__panel{
  padding:22px 24px;
  border:1px solid var(--wp--preset--color--border);
  border-left:3px solid var(--wp--preset--color--teal);
  border-radius:7px;
  background:var(--wp--preset--color--white);
}
.dgm__panel-title{
  font-size:1.1875rem;
  font-weight:600;
  line-height:1.35;
  color:var(--wp--preset--color--dark);
  margin-bottom:8px;
}
.dgm__panel p{font-size:0.9375rem;line-height:1.65;color:var(--wp--preset--color--grey)}
.dgm__panel + .dgm__panel{margin-top:12px}


/* 22.1  Reduced motion, diagrams.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion:reduce){
  .dgm__bub,
  .dgm__bub-icon,
  .dgm__spoke,
  .dgm__core{transition:none}
}


/* 23  CAPABILITY MATRIX
   Ported from opal-static section 21. The table comes across as verbatim
   markup inside a core/html block, because core/table stores cell
   content as rich text and would re-serialise the tick and cross SVGs,
   so it keeps the static site's own selectors.
   -------------------------------------------------------------------------- */

.table-wrap {
	overflow-x: auto;
	margin-top: 24px;
}

.matrix {
	width: 100%;
	min-width: 760px;
	border-collapse: collapse;
	font-size: 0.875rem;
}

.matrix th,
.matrix td {
	padding: 14px 12px;
	text-align: left;
	border-bottom: 1px solid var(--wp--preset--color--border);
	vertical-align: middle;
}

.matrix thead th {
	background: var(--wp--preset--color--off-white);
	font-weight: 600;
	color: var(--wp--preset--color--dark);
	white-space: nowrap;
}

.matrix tbody th[scope="row"] {
	font-weight: 400;
	color: var(--wp--preset--color--grey);
	text-align: left;
	min-width: 210px;
}

.matrix tbody th[scope="row"] strong {
	display: block;
	color: var(--wp--preset--color--dark);
	margin-bottom: 2px;
}

.matrix .yes { color: var(--wp--preset--color--teal); }
.matrix .no  { color: var(--wp--preset--color--grey); }


/* 24  CONTACT FORM AND VERBATIM UTILITIES
   Ported from opal-static sections 08 and 22. The form comes across as
   verbatim markup inside a core/html block, so it keeps the static
   site's own selectors, and without these it rendered as unstyled
   browser default inputs. .btn is here for the form's submit button;
   every other button on the site is a core/button block, styled in
   section 08. .visually-hidden is used by the matrix's tick and cross
   labels, which were reading out on the page rather than only to a
   screen reader.
   -------------------------------------------------------------------------- */

.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.form {
	display: grid;
	gap: 20px;
	margin-top: 24px;
}

.field {
	display: grid;
	gap: 6px;
}

.field label {
	font-size: 0.875rem;
	font-weight: 600;
	color: var(--wp--preset--color--grey);
}

.field input,
.field select,
.field textarea {
	width: 100%;
	box-sizing: border-box;
	padding: 12px 14px;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 7px;
	background: var(--wp--preset--color--white);
	font: inherit;
	font-size: 1rem;
	color: var(--wp--preset--color--grey);
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
	border-color: var(--wp--preset--color--teal);
}

.field textarea {
	resize: vertical;
}

.field--wide {
	margin-top: 4px;
	justify-items: start;
}

@media (min-width: 768px) {
	.form {
		grid-template-columns: repeat(2, 1fr);
	}

	.field--wide,
	.form .field:has(textarea) {
		grid-column: 1 / -1;
	}
}

/* The form's submit button. */
.form .btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	padding: 16px 32px;
	border: 1px solid transparent;
	border-radius: 7px;
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.2;
	text-align: center;
	cursor: pointer;
	transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}

.form .btn--primary {
	background: var(--wp--preset--color--teal);
	border-color: var(--wp--preset--color--teal);
	color: var(--wp--preset--color--white);
}

.form .btn--primary:hover,
.form .btn--primary:focus-visible {
	background: var(--wp--preset--color--teal-light);
	border-color: var(--wp--preset--color--teal-light);
}


/* 25  MOBILE NAVIGATION
   The panel is core's navigation overlay. Left alone it is a full screen
   white sheet with black, right aligned text and every submenu forced
   open. The static site has a 340px dark panel from the right, white
   type, dividers, and the sections collapsed behind a chevron.

   Core's own overlay rules run to four and five classes, so several of
   these have to be written out at that depth to win. The submenu
   accordion needs script.js as well: core hides the chevron in the
   overlay and pins every submenu open, so the button is given back its
   size here and its behaviour there.
   -------------------------------------------------------------------------- */

/* Core switches to the overlay at 600px. The static site switches at
   992, and between the two the desktop bar is too cramped to read. */
@media (max-width: 991.98px) {
	.opal-header .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none;
	}

	.opal-header .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}
}

/* Burger and close, white on the dark bar, at the 44px touch size. */
.opal-header .wp-block-navigation__responsive-container-open,
.opal-header .wp-block-navigation__responsive-container-close {
	width: 44px;
	height: 44px;
	align-items: center;
	justify-content: center;
	color: var(--wp--preset--color--white);
}

/* The panel itself. Core paints an unconditional white ground and black
   text on a navigation block with no background of its own, at four
   classes, so this is written at five to sit above it. */
.opal-header .wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
	left: auto;
	width: min(340px, 86vw);
	box-sizing: border-box;
	padding: 96px 24px 40px;
	background-color: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--white);
	overscroll-behavior: contain;
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	width: 100%;
	padding-top: 0;
	align-items: stretch;
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	display: block;
	width: 100%;
	gap: 0;
}

/* Top level rows: a divider under each, label left, chevron right, and
   the submenu on its own line beneath the pair. */
.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	border-bottom: 1px solid var(--wp--preset--color--dark-1);
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation__submenu-container {
	grid-column: 1 / -1;
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content {
	display: block;
	padding: 14px 0;
	font-size: 1rem;
	color: var(--wp--preset--color--white);
}

/* Core hides the chevron in the overlay. It is the accordion control
   here, so it comes back at the touch size. */
.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	background: transparent;
	border: 0;
	color: var(--wp--preset--color--white);
}

/* Core points the chevron by aria-expanded, which its own store owns and
   rewrites. The open state here is the .opal-sub-open class, so the
   chevron follows that instead and cannot end up upside down. */
.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon > svg {
	transform: none;
	transition: transform .2s ease;
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .opal-sub-open > .wp-block-navigation__submenu-icon > svg {
	transform: rotate(180deg);
}

/* The close button positions against the dialog, which sits inside the
   panel's padding and starts level with the first menu item. Taking the
   dialog out of the positioning chain puts the button in the panel's own
   top right corner instead, clear of the list. */
.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog {
	position: static;
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close {
	top: 24px;
	right: 24px;
}

/* Submenus: no panel of their own, indented, and collapsed until the
   chevron is pressed. */
.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container {
	display: none;
	min-width: 0;
	padding: 0 0 12px;
	background: transparent;
	border: 0;
	border-radius: 0;
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .opal-sub-open > .wp-block-navigation__submenu-container {
	display: block;
}

/* The nav block's right justification reaches the submenu rows as a flex
   align, which pushes each link to the right edge. They read as an
   indented list under their section, so the rows go back to blocks. */
.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container > .wp-block-navigation-item {
	display: block;
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	padding: 10px 0 10px 12px;
	font-size: 0.9375rem;
	font-weight: 400;
	color: var(--wp--preset--color--white);
	white-space: normal;
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--teal-light);
}

/* Contact Us stays the filled button it is on the bar, with air above it
   rather than a divider. */
.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:last-child {
	display: block;
	border-bottom: 0;
	padding-top: 20px;
}

.opal-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:last-child > .wp-block-navigation-item__content {
	display: inline-block;
	padding: 11px 22px;
	border-radius: 7px;
	background: var(--wp--preset--color--teal);
	font-size: 0.875rem;
	font-weight: 600;
}
