/*
Theme Name: Clean Child Theme
Theme URI: https://clean.axiomthemes.com/
Description: Clean is a Premium WordPress theme that has built-in support for popular Page Builders, slider with swipe gestures, and is SEO- and Retina-ready. The unique system of inheritance and override options allows setting up individual parameters for different sections of your site and supported plugins.
Author: AxiomThemes
Author URI: https://axiomthemes.com/
Version: 1.6.0+build.19-3829fe5
Tested up to: 6.9
Requires at least: 5.5
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: blog, e-commerce, portfolio, grid-layout, one-column, two-columns, three-columns, four-columns, left-sidebar, right-sidebar, custom-background, custom-colors, custom-header, custom-logo, custom-menu, editor-style, featured-image-header, featured-images, flexible-header, footer-widgets, full-width-template, microformats, post-formats, sticky-post, theme-options, threaded-comments, translation-ready, block-styles, wide-blocks
Text Domain: clean
Template: clean
*/


/* =Child-Theme customization starts here
------------------------------------------------------------ */


/* The deep accent tone
   ------------------------------------------------------------
   One variable for the darkest step of the brand rose, which several
   components reach for on hover and press: the cookie banner's buttons, the
   consent-gated embed panels, the call-to-action band buttons. It used to be
   the literal #7E454E repeated in each of them.

   It is a variable and not a literal because the header overrides it - see the
   monochrome block below - and a literal cannot be overridden per section.

   --theme-color-link (#B76E79) and --theme-color-hover (#9F5A64) are the
   parent theme's own, written into CSS custom properties on .scheme_default
   from skins/default/css/__custom.css. They are left exactly as the theme
   sets them; this is a third tone beneath them, not a replacement.
------------------------------------------------------------ */

:root {
	--mda-accent-deep: #7E454E;

	/* Buttons
	   ------------------------------------------------------------
	   Every filled button on the site is black, at the client's request: the
	   Contact Us pill in the header was already monochrome (see the block
	   below) and they asked for the rest to match it. The rose stays where it
	   was always doing the work - links, prices, rules, the small marks - so
	   the brand colour still runs through the site without a rose button on
	   every page competing with the photographs.

	   Two tokens rather than a hard-coded black, because a button is the one
	   thing on a page that has to be changed everywhere at once or not at all.

	   The hover is LIGHTER, not darker, because black cannot be deepened. That
	   is the usual answer for a black button and it is the only colour signal
	   available here - which matters under prefers-reduced-motion, where the
	   lift these buttons also carry is switched off and the colour is all that
	   is left. #2B2B2B on white is 13.7:1, and white on it is the same, so the
	   label clears AAA in both states. */
	--mda-button: #000000;
	--mda-button-hover: #2B2B2B;

	/* The dark band
	   ------------------------------------------------------------
	   The footer's palette, defined here rather than on .footer_millicent
	   because the Faces Consent band on Testimonials is the same band in a
	   different place, and two near-blacks that drift apart by a shade is
	   exactly the kind of thing nobody notices until both are on screen. */
	--mda-footer-bg: #131313;
	--mda-footer-text: #b6b3ae;
	--mda-footer-heading: #ffffff;
	--mda-footer-rule: rgba(255, 255, 255, 0.12);
}


/* Monochrome header
   ------------------------------------------------------------
   The site keeps its rose accent. The header bar does not: the MDA mark is
   black on white, the bar is the one element that carries the mark, and a rose
   pill sitting next to a black wordmark was the thing that read as off-brand.
   So the monochrome is scoped here and stops at the edge of the bar.

   Done by re-pointing the theme's own colour variables on the bar rather than
   by rewriting the rules inside it. Custom properties inherit, so every
   descendant that already reads --theme-color-link or --theme-color-hover -
   the menu underline, the current-page marker, the Contact Us pill, the phone
   and search discs - follows from these three lines, and any future header
   component follows automatically.

   The mobile menu panel is included: it is the same header, opened. It lives
   outside .mda_bar in the DOM (the parent theme renders it as a sibling), so
   it has to be named separately.

   Contrast on the bar's white ground:
     #2B2B2B  13.7:1  - accent text, and white text on it
     #000000  19.5:1  - hover and pressed
   Both pass AA and AAA. The rose never cleared AA at label size, which is why
   several rules in this file reach past it for a darker tone by hand.
------------------------------------------------------------ */

.top_panel_navi.mda_bar,
.menu_mobile {
	--theme-color-link: #2B2B2B;
	--theme-color-hover: #000000;
	--mda-accent-deep: #000000;
}


/* Site header: the floating stripe
   ------------------------------------------------------------
   A rounded bar inset from the edges of the window, holding the logo, the menu
   and the tools - and on the home page it floats over the banner photograph
   rather than sitting above it. Markup: clean-child/skins/default/templates/
   header-navi.php, which overrides the parent's.

   The logo comes from clean-child/images/logo.webp, fed to the theme through
   the 'custom_logo' theme mod (see clean_child_use_bundled_logo). The pinning
   is the child theme's own - the theme's fixed-header feature lives in the
   trx_addons plugin, which this site does not run - and is driven by
   js/header.js adding .mda_header_stuck to the body.

   The measured height of the stripe is published as --mda-header-h so the
   spacer below can hold its place, and so anchored headings clear it.
------------------------------------------------------------ */

/* White rather than the page's cream: the stripe has to read as an object
   sitting on the page, and cream on cream is invisible on every page that
   isn't the home page's photograph. */
.top_panel_navi.mda_bar {
	margin: 12px clamp(10px, 1.4vw, 20px) 0;
	padding: 0 clamp(16px, 2vw, 30px);
	border-radius: 14px;
	background-color: #ffffff;
	box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
	transition: background-color .35s ease, box-shadow .35s ease, padding .35s ease;
}

.mda_bar_inner {
	display: flex;
	align-items: center;
	gap: clamp(16px, 2.5vw, 40px);
	min-height: 68px;
}

/* The menu takes all the room left between the logo and the tools, and sets
   its items against the right-hand end of it.

   flex:1 rather than margin-left:auto for a specific reason: the theme's menu
   script measures the nav's own width and folds any items that don't fit into
   a "..." dropdown. Sized to its content, the nav reported barely enough room
   and Contact Us and Book Now were being collapsed away on a 1440px screen.
   Given the whole gap to measure, all seven items stay on the bar. */
.mda_bar_menu {
	flex: 1 1 auto;
	min-width: 0;
}

/* Items sit against the right-hand end of the bar.

   Done with text-align + inline-block rather than flex on purpose: the theme
   floats the top-level items, and a floated item in a flex container is taken
   out of the flex flow entirely - the row stayed left-packed however the
   container was set. Clearing the float and letting them run as inline blocks
   puts them under the control of text-align, which the theme does not fight. */
.top_panel .mda_bar .mda_bar_menu > .sc_layouts_menu_nav {
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
	text-align: right;
}

.top_panel .mda_bar .mda_bar_menu > .sc_layouts_menu_nav > li {
	display: inline-block;
	float: none;
	text-align: left;
	vertical-align: middle;
}

.mda_bar_menu .sc_layouts_menu_nav > li > a {
	padding-right: clamp(8px, 0.9vw, 16px);
	padding-left: clamp(8px, 0.9vw, 16px);
	white-space: nowrap;
}

/* Off the home page the links sit in the middle of the bar instead of packed
   against the right. On the home page the bar floats over the banner
   photograph, where the right-hand cluster reads as one group, so that layout
   is left alone.

   Same text-align mechanism as above rather than flex. Flex genuinely does not
   drive these items - setting justify-content on the list moves nothing, which
   is what the note above was warning about - so the switch is text-align on the
   list, and a right float on Book Now to take it out of the centred run and
   park it at the end, next to the phone. */
body:not(.home) .top_panel .mda_bar .mda_bar_menu > .sc_layouts_menu_nav {
	text-align: center;
}

/* The float is what puts Book Now at the end of the row, but a float aligns to
   the top of its line box, and the list is 59px tall against the button's 49px
   - so it sat 5px high, out of line with the phone beside it and with the same
   button on the home page, where there is no float and it centres by itself.

   5px is half that 10px difference. Both heights are fixed: the menu's type
   size does not change with the viewport, and the button's vertical padding is
   a flat 11px, so the gap is the same at every width. The obvious alternative,
   top:50% with a translate, does not work on a float - a percentage offset on a
   relatively positioned box resolves against its container's height, the list
   has no declared height, so the offset computes to zero and only the translate
   fires, throwing the button 25px upwards. */
body:not(.home) .top_panel .mda_bar .mda_bar_menu > .sc_layouts_menu_nav > li.mda_menu_cta {
	float: right;
	margin-top: 5px;
}

/* "Book Now" is the one thing the whole site is pointing at, so it stops being
   a menu item and becomes a button. The class is put there by
   clean_child_mark_menu_cta(), matched on the page it links to rather than on
   its position or label. */
.mda_bar_menu .sc_layouts_menu_nav > li.mda_menu_cta {
	margin-left: clamp(6px, 0.8vw, 14px);
}

.mda_bar_menu .sc_layouts_menu_nav > li.mda_menu_cta > a {
	padding: 11px clamp(16px, 1.4vw, 24px);
	border-radius: 100px;
	background-color: var(--mda-button);
	color: #ffffff;
	transition: background-color .3s ease, transform .3s ease, box-shadow .3s ease;
}

/* Same gesture as .mda_cta_button at the foot of the page - lift, deepen to
   --mda-accent-deep - but a tighter shadow, because this one is boxed in. On
   the bar that variable is black (see the monochrome block at the top of this
   file); everywhere else on the site it is still the deep rose.

   The bar runs 12-80 and the pill sits 16-66, so there are 14px of bar beneath
   it. The page button's 0 16px 32px shadow reaches roughly 48px past its own
   edge, which put most of it outside the white bar entirely, as a smudge on the
   page behind. 0 4px 12px stays inside the bar.

   The colour needs !important only because the parent theme sets
   `.sc_layouts_menu_nav > li > a:hover { color: ... !important }` (skins/default
   /css/style.css). Without it the white label washes to the link colour on
   hover, and a label that is not white on this pill is unreadable. */
.mda_bar_menu .sc_layouts_menu_nav > li.mda_menu_cta > a:hover,
.mda_bar_menu .sc_layouts_menu_nav > li.mda_menu_cta > a:focus-visible {
	transform: translateY(-3px);
	background-color: var(--mda-button-hover);
	color: #ffffff !important;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.32);
}

/* On its own page WordPress marks this item current, and the theme colours
   current items with the link colour - which landed mid-tone text on the filled
   pill and left the label looking switched off, exactly where the visitor has
   just arrived. The pill keeps its white label on every page. */
.mda_bar_menu .sc_layouts_menu_nav > li.mda_menu_cta.current-menu-item > a,
.mda_bar_menu .sc_layouts_menu_nav > li.mda_menu_cta.current_page_item > a,
.mda_bar_menu .sc_layouts_menu_nav > li.mda_menu_cta.current-menu-item > a > span,
.mda_bar_menu .sc_layouts_menu_nav > li.mda_menu_cta.current_page_item > a > span {
	color: #ffffff !important;
}

/* The underline the other items grow on hover would draw across the pill. */
.mda_bar_menu .sc_layouts_menu_nav > li.mda_menu_cta > a::after {
	display: none;
}

.sc_layouts_logo img {
	display: block;
	width: auto;
	max-width: 100%;
	height: clamp(34px, 3.2vw, 44px);
	transition: height .35s ease, opacity .3s ease;
}

.sc_layouts_logo:hover img {
	opacity: 0.75;
}

/* ---------- Tools: search, phone, mobile menu ---------- */

/* margin-left:auto rather than relying on the menu to push these right. The
   menu carries flex:1 and does the pushing on desktop, but it is display:none
   below the tablet breakpoint - so on a phone the call and burger were sitting
   immediately after the logo with the rest of the bar empty to their right. */
.mda_bar_tools {
	display: flex;
	align-items: center;
	gap: clamp(4px, 0.8vw, 12px);
	margin-left: auto;
}

/* The tinted disc is carried at rest, not only on hover, so the phone and search
   read as buttons rather than as loose glyphs floating on the bar. Same
   treatment as the contact page's detail icons, which is where a visitor sees
   this shape first. */
.mda_bar_icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 50%;
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-title);
	cursor: pointer;
	list-style: none;
	transition: background-color .3s ease, color .3s ease, transform .3s ease;
}

/* Hover fills the disc instead of tinting it - the tint is the resting state
   now, so it can no longer carry the hover as well.

   --mda-accent-deep rather than --theme-color-link: the link tone is the
   lighter of the two, and a 1.5px white stroke on it lands at about 3:1, right
   on the WCAG minimum for non-text contrast. The deep tone clears it
   comfortably and is the same colour the Contact Us pill settles on, so the two
   tools agree on hover. On the bar both resolve to black. */
.mda_bar_icon:hover,
.mda_bar_icon:focus-visible {
	transform: translateY(-2px);
	background-color: var(--mda-accent-deep);
	color: #ffffff;
}

/* The theme's own burger, shown only once the menu itself is hidden. */
.mda_bar_burger {
	display: none;
}

@media (max-width: 1023px) {
	.mda_bar_burger {
		display: inline-flex;
	}
}

/* The marker js/header.js watches to know when the page has left the top. It
   is 1px rather than 0 because a zero-area target is an edge case in
   IntersectionObserver, and the pixel is taken straight back with a negative
   margin so it changes no layout. */
.mda_header_sentinel {
	height: 1px;
	margin-bottom: -1px;
	pointer-events: none;
}

/* ---------- Pinned state ---------- */

/* The stripe stays a floating pill when it pins - it is the same object, now
   following the reader - rather than snapping to a full-width bar, which reads
   as a second, different header appearing. */
.mda_header_stuck .top_panel_navi.mda_bar {
	position: fixed;
	z-index: 1000;
	top: 12px;
	right: clamp(10px, 1.4vw, 20px);
	left: clamp(10px, 1.4vw, 20px);
	margin: 0;
	box-shadow: 0 12px 34px rgba(0, 0, 0, 0.1);
	animation: mda_header_drop .4s ease both;
}

/* Off the home page the stripe is in the flow, so pinning it would pull the
   page up by its height. This holds the space it left. */
.mda_header_stuck .top_panel_default {
	padding-top: var(--mda-header-h, 92px);
}

/* On the home page it was never in the flow - it floats over the banner - so
   there is no gap to hold open. */
body.home.mda_header_stuck .top_panel_default {
	padding-top: 0;
}

.mda_header_stuck .mda_bar_inner {
	min-height: 58px;
}

.mda_header_stuck .sc_layouts_logo img {
	height: clamp(30px, 2.6vw, 36px);
}

.admin-bar.mda_header_stuck .top_panel_navi.mda_bar {
	top: 44px;
}

@media (max-width: 782px) {
	.admin-bar.mda_header_stuck .top_panel_navi.mda_bar {
		top: 58px;
	}
}

/* Comes down from above rather than fading in on the spot: the movement is
   what tells you the bar is now pinned rather than part of the page. */
@keyframes mda_header_drop {
	from {
		transform: translateY(-100%);
	}
	to {
		transform: translateY(0);
	}
}

/* Anchored headings (the legal pages' contents nav) must clear the pinned bar
   instead of landing underneath it. */
:root {
	scroll-behavior: smooth;
}

[id] {
	scroll-margin-top: calc(var(--mda-header-h, 96px) + 24px);
}

@media (prefers-reduced-motion: reduce) {
	:root {
		scroll-behavior: auto;
	}
	.mda_header_stuck .top_panel_navi {
		animation: none;
	}
}


/* FAQs page (template-faq.php)
------------------------------------------------------------ */

/* The bottom margin clears the call-to-action band that follows. Without it
   the last answer's hairline rule sat straight on the top edge of a full-bleed
   dark band, with nothing to say the list had ended. */
.faq_page .faq_groups {
	margin-top: 2em;
	margin-bottom: clamp(60px, 7vw, 110px);
}

/* The FAQ band carries the shopfront, and the brief is that the name across the
   fascia reads in full. 'cover' on a 3:2 photograph in a band this shallow keeps
   the full width but only a slice of the height, and past about 1900px the band
   stops growing (its padding is capped) while the scaled photograph keeps
   getting taller - so the slice narrows until it closes in on the sign. The
   floor is that slice's minimum: 21vw of a 3:2 image is a little over a third of
   its height, and the lettering occupies a quarter of it, centred. Capped, so it
   cannot run away on an ultra-wide monitor. */
.faq_page .mda_cta {
	/* Flex, because a min-height on its own would leave the extra height as a
	   gap under the copy rather than around it. align-items stays at its
	   default stretch, so .mda_cta_inner keeps centring itself on its own
	   max-width. */
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-height: min(21vw, 700px);
}

.faq_page .faq_group + .faq_group {
	margin-top: 3em;
}

.faq_page .faq_group_title {
	margin-bottom: 1em;
}

.faq_page .faq_item {
	border-bottom: 1px solid var(--theme-color-bd_color);
}

.faq_page .faq_group .faq_item:first-child {
	border-top: 1px solid var(--theme-color-bd_color);
}

.faq_page .faq_item_question {
	position: relative;
	display: block;
	padding: 1.2em 3em 1.2em 0;
	cursor: pointer;
	list-style: none;
	color: var(--theme-color-title);
	font-family: var(--theme-font-h5_font-family);
	font-size: var(--theme-font-h5_font-size);
	font-weight: var(--theme-font-h5_font-weight);
	line-height: 1.4;
	transition: color .3s ease;
}

/* Hide the default disclosure triangle */
.faq_page .faq_item_question::-webkit-details-marker {
	display: none;
}
.faq_page .faq_item_question::marker {
	content: '';
}

.faq_page .faq_item_question:hover,
.faq_page .faq_item[open] > .faq_item_question {
	color: var(--theme-color-link);
}

.faq_page .faq_item_question:focus-visible {
	outline: 2px solid var(--theme-color-link);
	outline-offset: 2px;
}

/* Plus / minus marker */
.faq_page .faq_item_marker {
	position: absolute;
	top: 50%;
	right: 0;
	width: 1em;
	height: 1em;
	margin-top: -0.5em;
}

.faq_page .faq_item_marker::before,
.faq_page .faq_item_marker::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 0;
	width: 100%;
	height: 2px;
	margin-top: -1px;
	background-color: currentColor;
	transition: transform .3s ease;
}

.faq_page .faq_item_marker::after {
	transform: rotate(90deg);
}

.faq_page .faq_item[open] .faq_item_marker::after {
	transform: rotate(0deg);
}

.faq_page .faq_item_answer {
	padding: 0 3em 1.5em 0;
	color: var(--theme-color-text);
}

.faq_page .faq_item_answer p:last-child {
	margin-bottom: 0;
}

/* Call to action block.
   bg_color_2 (#F2F0EC) is the light tinted panel colour.
   Do NOT use alt_bg_color here - that is the DARK inverse colour (#1F2A30). */
/* Contact Us page (template-contact.php)
   Uses the theme's own design tokens so this page matches the rest of the site.
   Only these --theme-color-* variables are actually emitted as CSS custom
   properties by the theme (see skins/default/css/__custom.css):
     bg_color, bg_color_2, bd_color, title, text, meta, link, hover, alt_*
   Names like "alter_bg_color" / "text_link" exist only as PHP-side aliases and
   resolve to nothing in CSS, so they must not be used here.
   - bg_color_2 (#F2F0EC) = light tinted panel. alt_bg_color is DARK (#1F2A30).
   - Input colour/border/radius/padding/font-size are left to the theme's own
     input styling, so fields match every other form on the site.
------------------------------------------------------------ */

/* stretch, not start: both columns run to the same height, so the details
   column and the form card finish on one line instead of one hanging below
   the other. Each column then pins its last block to the bottom (opening
   times on the left, the submit button on the right) so the two bottom edges
   agree rather than leaving a ragged gap. */
.contact_page .contact_layout {
	display: grid;
	grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
	gap: 60px;
	align-items: stretch;
}

.contact_page .contact_details {
	display: flex;
	flex-direction: column;
}

/* ---------- Left column: details ---------- */

.contact_page .contact_eyebrow {
	display: block;
	margin-bottom: 25px;
	color: var(--theme-color-link);
	font-size: 14px;
	font-weight: 500;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.contact_page .contact_intro {
	margin-bottom: 40px;
}

/* Justification for this and every other run of prose is set once, in the
   "Justified body copy, sitewide" block at the end of this file. */
.contact_page .contact_intro p:last-child {
	margin-bottom: 0;
}

.contact_page .contact_details_list {
	list-style: none;
	margin: 0 0 30px;
	padding: 0;
}

.contact_page .contact_details_item {
	display: flex;
	align-items: flex-start;
	gap: 16px;
	padding: 20px 0;
	border-bottom: 1px solid var(--theme-color-bd_color);
}

.contact_page .contact_details_item:first-child {
	padding-top: 0;
}

.contact_page .contact_details_icon {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-link);
	transition: background-color .35s ease, color .35s ease, transform .35s ease;
}

/* The whole row answers the pointer, not just the link inside it. Hovering the
   number, the address or the tile itself inverts the tile the same way
   .about_value and .home_promise invert theirs, so the three details behave
   like the cards elsewhere on the site rather than like inert text.

   Driven from the <li> rather than the <a>, because the address is not a link -
   without this it would be the one row that did nothing.

   Guarded by (hover: hover) for the same reason the cards are: two of these
   rows are tap targets on a phone, and :hover sticks after a tap, which would
   leave an inverted tile sitting there until something else was tapped. The
   clock below needs no such guard - it turns a full revolution, so a stuck
   hover state lands exactly where it started. */
@media (hover: hover) {
	.contact_page .contact_details_item:hover .contact_details_icon {
		transform: rotate(-8deg) scale(1.06);
		background-color: var(--theme-color-link);
		color: var(--theme-color-bg_color);
	}
}

.contact_page .contact_details_body {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-width: 0;
	padding-top: 3px;
}

.contact_page .contact_details_label {
	color: var(--theme-color-meta);
	font-size: 12px;
	line-height: 1.4;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.contact_page .contact_details_value {
	color: var(--theme-color-title);
	font-size: 16px;
	line-height: 1.5;
	overflow-wrap: anywhere;
}

.contact_page a.contact_details_value:hover {
	color: var(--theme-color-link);
}

/* ---------- Social ---------- */

/* The last thing in the column, so the spacing is above it rather than below.

   A plain margin, NOT margin-top:auto. The auto was tried when opening times
   came off, to keep the foot of this column level with the foot of the form
   card opposite - and it is the wrong tool here. The form is a nine-field card
   roughly twice the height of these three contact lines, so `auto` had around
   300px of free space to absorb and it puts all of it in one gap: the address
   ended, and the Facebook and Instagram buttons sat most of a screen below it,
   apparently belonging to nothing.

   Bottom alignment is only worth having when the two columns are close in
   height. They are not, so the details column simply stops when it runs out of
   details, which is what the eye expects. The Opening Times card keeps its own
   margin-top:auto for the day it returns - at that point the column is tall
   enough for the alignment to read as alignment rather than as a hole. */
.contact_page .contact_social {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 24px;
}

.contact_page .contact_social_link {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 10px 18px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: 100px;
	color: var(--theme-color-title);
	font-size: 15px;
	line-height: 1.4;
	transition: border-color .3s ease, color .3s ease, background-color .3s ease;
}

.contact_page .contact_social_link:hover {
	border-color: var(--theme-color-link);
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-link);
}

.contact_page .contact_social_icon {
	display: inline-flex;
	color: var(--theme-color-link);
}

/* ---------- Opening times ---------- */

/* NOT RENDERED TODAY, and kept deliberately. Opening times were taken off at
   the client's request by emptying clean_child_get_business()['hours'], and
   template-contact.php skips the whole panel when that list is empty - so
   putting the hours back is one array in one file, and the panel comes back
   styled. Deleting this would make that a markup-and-CSS job instead.

   The social links below take the margin-top:auto in its absence, so the
   bottom of this column still lines up with the form card opposite. */

/* margin-top:auto pushes this and the social links below it down to the foot of
   the column, so the group lines up with the bottom of the form card opposite. */
/* The transparent border is what the shared card hover at the foot of this file
   colours in - same as .about_value and .book_way, which is where this card's
   lift, plum hairline and shadow come from. */
.contact_page .contact_hours {
	margin-top: auto;
	padding: 30px;
	border: 1px solid transparent;
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
}

.contact_page .contact_hours_title {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 18px;
	font-size: 19px;
	line-height: 1.3;
}

.contact_page .contact_hours_icon {
	display: inline-flex;
	color: var(--theme-color-link);
}

/* A full revolution on hover, as the About page's value icons do - a clock face
   is the one icon in the set where turning it means something. .7s over 360deg
   is slow enough to read as a sweep rather than a flicker. */
.contact_page .contact_hours_icon svg {
	transition: transform .7s ease;
}

.contact_page .contact_hours:hover .contact_hours_icon svg {
	transform: rotate(360deg);
}

.contact_page .contact_hours_list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.contact_page .contact_hours_item {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	padding: 10px 0;
	border-bottom: 1px solid var(--theme-color-bd_color);
}

.contact_page .contact_hours_item:first-child {
	padding-top: 0;
}

.contact_page .contact_hours_item:last-child {
	padding-bottom: 0;
	border-bottom: none;
}

.contact_page .contact_hours_label {
	color: var(--theme-color-title);
}

.contact_page .contact_hours_value {
	color: var(--theme-color-text);
	white-space: nowrap;
}

/* .contact_hours_item_closed is still set in the template and is deliberately
   left unstyled: "Closed" was dropped to the meta grey, which put the one line
   people most need to notice at the lowest contrast in the card. It now reads
   at the same weight as the opening hours it sits under. The class stays as the
   hook it always was. */

/* ---------- Full-bleed map band ----------
   Sits below the two-column layout and breaks out of the page container via
   the theme's own .alignfull class. Height is fixed rather than an aspect
   ratio: at 100vw a ratio makes the band absurdly tall on wide monitors and
   too short to read on small ones. clamp() keeps it a readable strip at every
   width.
------------------------------------------------------------ */

.contact_page .contact_map {
	position: relative;
	margin-top: 70px;
}

.contact_page .contact_map_frame {
	overflow: hidden;
	height: clamp(320px, 34vw, 480px);
	background-color: var(--theme-color-bg_color_2);
}

.contact_page .contact_map_frame iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: none;
}

/* Floating "Get Directions" button over the bottom-right of the map, clear of
   Google's own controls on the left and the attribution strip along the base. */
.contact_page .contact_map_directions {
	position: absolute;
	right: clamp(16px, 4vw, 60px);
	bottom: clamp(46px, 6vw, 70px);
	z-index: 2;
	margin: 0;
}

@media (max-width: 767px) {
	.contact_page .contact_map {
		margin-top: 50px;
	}
	.contact_page .contact_map_frame {
		height: 300px;
	}
	.contact_page .contact_map_directions {
		right: 50%;
		bottom: 20px;
		transform: translateX(50%);
	}
}

/* ---------- Right column: form card ---------- */

/* A flex column so the form inside can fill the card's full height - that is
   what lets the submit button sit on the card's bottom edge and line up with
   the opening times opposite. */
.contact_form_wrap {
	display: flex;
	flex-direction: column;
	padding: 40px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color);
}

.contact_form_wrap .contact_form {
	display: flex;
	flex-direction: column;
	flex: 1;
}

.contact_form_wrap .contact_form_title {
	margin: 0 0 8px;
	font-size: 28px;
	line-height: 1.2;
}

.contact_form_wrap .contact_form_subtitle {
	margin-bottom: 30px;
	color: var(--theme-color-meta);
}

.contact_form_wrap .contact_form_notice {
	margin-bottom: 25px;
	padding: 16px 20px;
	border-radius: var(--theme-var-global-border-radius-small, 6px);
	border: none;
	outline: 2px solid var(--theme-color-hover);
	outline-offset: 3px;
}

.contact_form_wrap .contact_form_notice_success {
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-title);
}

.contact_form_wrap .contact_form_notice_error {
	background-color: #F9ECEA;
	color: var(--theme-color-hover);
}

/* Swapped in and out by js/enquiry-form.js without a page load. */
.contact_form_wrap .contact_form_notice {
	transition: opacity 0.3s ease, transform 0.3s ease;
}

.contact_form_wrap .contact_form_notice_leaving {
	opacity: 0;
	transform: translateY(-6px);
}

.contact_form_wrap .contact_form_button[aria-busy="true"] {
	opacity: 0.6;
	cursor: progress;
}

@media (prefers-reduced-motion: reduce) {
	.contact_form_wrap .contact_form_notice {
		transition: none;
	}
}

/* Honeypot: hidden from people, still reachable by bots. */
.contact_form_wrap .contact_form_hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.contact_form_wrap .contact_form_grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 20px;
}

.contact_form_wrap .contact_form_row {
	margin: 0;
	min-width: 0;
}

.contact_form_wrap .contact_form_row_full {
	grid-column: 1 / -1;
}

.contact_form_wrap .contact_form_row label {
	display: block;
	margin-bottom: 8px;
	color: var(--theme-color-title);
	font-size: 15px;
	line-height: 1.4;
}

.contact_form_wrap .contact_form_row .required {
	color: var(--theme-color-link);
}

/* Only layout here on purpose: colour, border, radius, padding and font-size
   come from the theme's own input styling, so these fields match every other
   form on the site instead of inventing a second look. */
.contact_form_wrap .contact_form_row input,
.contact_form_wrap .contact_form_row textarea {
	display: block;
	width: 100%;
}

.contact_form_wrap .contact_form_row textarea {
	min-height: 150px;
	resize: vertical;
}

/* margin-top:auto pushes the button to the foot of the card whenever the
   details column opposite is the taller of the two. The gap above it comes
   from padding rather than margin, because an auto margin collapses to zero
   when there is no slack to absorb - which would leave the button touching
   the message field. */
.contact_form_wrap .contact_form_submit {
	margin: auto 0 0;
	padding-top: 30px;
}

.contact_form_wrap .contact_form_button {
	cursor: pointer;
}

/* The notice a captcha provider's terms require in place of their floating
   badge (inc/captcha.php). Small print, but 13px at this colour still clears
   4.5:1 against the card, so it is readable rather than merely present. */
.contact_form_wrap .contact_form_legal {
	margin: 14px 0 0;
	color: var(--theme-color-text_light);
	font-size: 13px;
	line-height: 1.5;
}

.contact_form_wrap .contact_form_legal a {
	color: inherit;
	text-decoration: underline;
}

.contact_form_wrap .contact_form_legal a:hover,
.contact_form_wrap .contact_form_legal a:focus-visible {
	color: var(--theme-color-hover);
}

/* The submitted/failed message. It is the first thing the page has to say
   after a submission, and focus is moved to it, so it needs a visible outline
   of its own rather than the browser's default on a non-interactive element. */
.contact_form_wrap .contact_form_notice:focus {
	outline: 2px solid var(--theme-color-hover);
	outline-offset: 3px;
}

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

@media (max-width: 1023px) {
	.contact_page .contact_layout {
		grid-template-columns: minmax(0, 1fr);
		gap: 50px;
	}
}

@media (max-width: 767px) {
	.contact_form_wrap {
		padding: 25px 20px;
	}
	.contact_form_wrap .contact_form_grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 18px;
	}
	.contact_page .contact_hours {
		padding: 22px 20px;
	}
	.contact_page .contact_hours_item {
		flex-direction: column;
		gap: 2px;
	}
	.contact_page .contact_details_icon {
		width: 40px;
		height: 40px;
	}
}


/* Site footer (templates/footer-millicent.php)
   ------------------------------------------------------------
   Replaces the parent theme's widget-driven footer. Dark band, logo on its
   own line, three columns below it, then a rule and the small print.

   Colours are set literally rather than through the theme's --theme-color-*
   vars: those follow whichever colour scheme the page is using, and the footer
   has to stay dark on every page regardless.
------------------------------------------------------------ */

.footer_millicent {
	/* Palette on :root - see "The dark band" at the top of this file. */
	padding: 70px 0 40px;
	background-color: var(--mda-footer-bg);
	color: var(--mda-footer-text);
	font-size: 15px;
	line-height: 1.7;
}

.footer_millicent a {
	color: var(--mda-footer-text);
	text-decoration: none;
	transition: color 0.2s ease;
}

.footer_millicent a:hover,
.footer_millicent a:focus-visible {
	color: var(--mda-footer-heading);
}

.footer_millicent .mda_footer_title {
	margin: 0 0 25px;
	color: var(--mda-footer-heading);
	font-size: 20px;
	line-height: 1.3;
}

/* ---------- Logo ---------- */

.footer_millicent .mda_footer_logo {
	display: inline-block;
	margin-bottom: 45px;
}

.footer_millicent .mda_footer_logo img {
	display: block;
	width: auto;
	max-width: 230px;
	height: auto;
	max-height: 85px;
}

.footer_millicent .mda_footer_logo_text {
	color: var(--mda-footer-heading);
	font-size: 22px;
	letter-spacing: 0.02em;
}

/* ---------- Columns ---------- */

/* The Contact column carries the longest single string on the page (the email
   address), so it gets more room than the Pages list beside it. */
.footer_millicent .mda_footer_columns {
	display: grid;
	grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.8fr) minmax(0, 1.15fr);
	gap: 40px 55px;
	align-items: start;
}

.footer_millicent .mda_footer_about_text {
	margin: 0 0 30px;
	max-width: 42ch;
}

.footer_millicent .mda_footer_socials {
	display: flex;
	gap: 12px;
}

/* A hairline ring on the dark band, not a white disc. The marks were briefly
   set in Facebook blue and the Instagram gradient on white chips; that was
   reverted at the client's request. The mark takes its colour from the footer
   text, and the ring gives it the same standing-control shape the header tools
   use. */
.footer_millicent .mda_footer_social {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border: 1px solid var(--mda-footer-rule);
	border-radius: 50%;
}

.footer_millicent .mda_footer_social:hover {
	border-color: var(--mda-footer-heading);
}

.footer_millicent .mda_footer_menu,
.footer_millicent .mda_footer_contacts {
	list-style: none;
	margin: 0;
	padding: 0;
}

.footer_millicent .mda_footer_menu_item + .mda_footer_menu_item {
	margin-top: 10px;
}

.footer_millicent .mda_footer_contact {
	display: flex;
	/* flex-start, not center: the email wraps to two lines in a narrow column
	   and the icon should stay with the first line, not float to the middle. */
	align-items: flex-start;
	gap: 10px;
	min-width: 0;
}

.footer_millicent .mda_footer_contact + .mda_footer_contact {
	margin-top: 10px;
}

/* The email is a single 43-character word with no natural break point, so it
   has to be allowed to break mid-string or it overflows the column. */
.footer_millicent .mda_footer_contact a {
	min-width: 0;
	overflow-wrap: anywhere;
}

/* The glyphs sat bare against the dark band with nothing to hold them, so they
   read as marks in the text rather than as the pair of standing controls they
   sit beside. A tinted disc gives them the same shape the header tools and the
   Contact page's detail icons already use, and the padding that shape implies.

   28px against a 24px line box, so it stays level with the first line of the
   address rather than towering over it. */
.footer_millicent .mda_footer_contact_icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	background-color: rgba(255, 255, 255, 0.07);
	color: var(--mda-footer-heading);
	transition: background-color .3s ease, color .3s ease, transform .3s ease;
}

.footer_millicent .mda_footer_contact_icon svg {
	width: 17px;
	height: 17px;
}

/* Driven from the row, not the link. The icon is a sibling of the anchor and
   aria-hidden, so it cannot be reached from a:hover - and hovering anywhere
   along the line is what a visitor expects to acknowledge them, the same way
   the treatments rows light their own prices.

   The marks were rose on the black band, which the client asked to take off
   brand. They are white now, and the hover inverts to a white disc with the
   band's own near-black glyph rather than reaching for a colour: it is the
   strongest contrast available down here (19.5:1 either way) and it matches
   the black buttons the rest of the site now uses. */
.footer_millicent .mda_footer_contact:hover .mda_footer_contact_icon,
.footer_millicent .mda_footer_contact:focus-within .mda_footer_contact_icon {
	transform: translateY(-1px);
	background-color: var(--mda-footer-heading);
	color: var(--mda-footer-bg);
}

.footer_millicent .mda_footer_contact a {
	transition: color .3s ease;
}

.footer_millicent .mda_footer_contact:hover a,
.footer_millicent .mda_footer_contact a:focus-visible {
	color: var(--mda-footer-heading);
}

@media (prefers-reduced-motion: reduce) {
	.footer_millicent .mda_footer_contact:hover .mda_footer_contact_icon,
	.footer_millicent .mda_footer_contact:focus-within .mda_footer_contact_icon {
		transform: none;
	}
}

/* ---------- The clinic address ---------- */

/* The registered company name, number and registered office used to lead this
   column and were taken off at the client's request - the registered office is
   a private home and the footer runs on every page. The clinic's own address
   takes the slot, as the first row of the contact list, so the three facts
   someone actually needs from a footer (where, email, phone) sit together in
   one list with one icon rhythm.

   It is a plain <span>, not a link: a mailto and a tel are both something to
   press, an address is something to read, and giving it the link colour would
   promise a map that is not there. The map is on the Contact page. */
.footer_millicent .mda_footer_address {
	color: var(--mda-footer-text);
	overflow-wrap: anywhere;
}

/* ---------- Bottom bar ---------- */

/* Now carries only the copyright, the build credit and the legal links, so it
   can sit on one baseline rather than stacking. */
.footer_millicent .mda_footer_bottom {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 18px 40px;
	margin-top: 65px;
	padding-top: 28px;
	border-top: 1px solid var(--mda-footer-rule);
	font-size: 14px;
}

.footer_millicent .mda_footer_copyright {
	margin: 0;
}

.footer_millicent .mda_footer_bottom_links {
	display: flex;
	flex: 0 0 auto;
	gap: 25px;
	list-style: none;
	margin: 0;
	padding: 0;
}

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

@media (max-width: 1023px) {
	.footer_millicent .mda_footer_columns {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	}
	.footer_millicent .mda_footer_col_about {
		grid-column: 1 / -1;
	}
}

@media (max-width: 767px) {
	.footer_millicent {
		padding: 50px 0 35px;
	}
	.footer_millicent .mda_footer_columns {
		grid-template-columns: minmax(0, 1fr);
		gap: 35px;
	}
	.footer_millicent .mda_footer_logo {
		margin-bottom: 35px;
	}
	.footer_millicent .mda_footer_bottom {
		flex-direction: column;
		margin-top: 45px;
	}
}

/* ---------- "Built by North" credit ---------- */

.footer_millicent .mda_footer_credit {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 10px 0 0;
}

.footer_millicent .mda_footer_credit_label {
	font-size: 14px;
}

.footer_millicent .mda_footer_credit_link {
	display: inline-flex;
	align-items: center;
}

.footer_millicent .mda_footer_credit_link img {
	display: block;
	width: auto;
	height: 18px;
}

/* Inline wordmark from clean_child_north_logo(). Sized by height so the drawn
   mark and an images/north.svg replacement line up the same way. */
.footer_millicent .mda_footer_credit_link svg {
	display: block;
	width: auto;
	height: 20px;
	color: var(--mda-footer-heading);
	overflow: visible;
}

.footer_millicent .mda_footer_credit_link:hover svg {
	opacity: 0.8;
}



/* "Follow us on Instagram" band (templates/footer-millicent.php)
   ------------------------------------------------------------
   Sitewide strip directly above the footer. Tiles are square and sit in one
   full-width row on desktop, all linking to the clinic's Instagram profile.
   Hidden entirely by the template when no instagram-*.webp files are bundled.
------------------------------------------------------------ */

/* The bottom padding separates the tiles from the footer. Without it the last
   row of photographs ran straight into the dark band, and the two read as one
   block rather than as the strip and the footer under it. */
.mda_instagram {
	padding: 60px 0 clamp(50px, 6vw, 90px);
	background-color: var(--theme-color-bg_color);
	text-align: center;
}

/* Trirong, sentence case: this is a heading, and the small-caps treatment made
   it read as an eyebrow label above the strip instead. The tracking comes down
   with the case - 0.12em is spacing for capitals, and it opens sentence case up
   until the words stop holding together. */
.mda_instagram_title {
	margin: 0 0 35px;
	font-family: var(--theme-font-h1_font-family);
	font-size: clamp(26px, 3vw, 38px);
	font-weight: 400;
	line-height: 1.25;
	letter-spacing: 0;
	text-transform: none;
}

/* Underline accent under the word "Instagram" only, as in the reference. */
.mda_instagram_title_link {
	display: inline-block;
	padding-bottom: 6px;
	border-bottom: 2px solid var(--theme-color-link);
	color: inherit;
}

.mda_instagram_title_link:hover {
	color: var(--theme-color-link);
}

.mda_instagram_grid {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: 20px;
	padding: 0 20px;
}

.mda_instagram_item {
	position: relative;
	display: block;
	overflow: hidden;
	aspect-ratio: 1 / 1;
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
}

/* Every tile is a link to the profile now, not decoration beside one. The band
   exists to send people to Instagram, and six photographs that look clickable
   and are not is the most expensive kind of dead end - a visitor who presses
   one and gets nothing does not press the heading afterwards. */
.mda_instagram_item img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .5s ease;
}

.mda_instagram_item:hover img {
	transform: scale(1.06);
}

/* Scrim drawn on the tile itself, so the glyph over it stays legible whatever
   the photograph underneath is doing. */
.mda_instagram_item::after {
	content: '';
	position: absolute;
	inset: 0;
	opacity: 0;
	background-color: rgba(0, 0, 0, 0.35);
	transition: opacity .3s ease;
	pointer-events: none;
}

.mda_instagram_item:hover::after,
.mda_instagram_item:focus-visible::after {
	opacity: 1;
}

/* The glyph that says where the tile goes. Hidden until hover so the strip
   still reads as photographs rather than as a row of buttons - but present in
   the markup either way, because it also has to appear on keyboard focus, and
   on touch, where there is no hover, the whole tile is the target and the
   heading above already names the destination. */
.mda_instagram_item_mark {
	position: absolute;
	z-index: 1;
	top: 50%;
	left: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	opacity: 0;
	color: #ffffff;
	transform: translate(-50%, -50%) scale(.9);
	transition: opacity .3s ease, transform .3s ease;
	pointer-events: none;
}

.mda_instagram_item_mark svg {
	width: 26px;
	height: 26px;
}

.mda_instagram_item:hover .mda_instagram_item_mark,
.mda_instagram_item:focus-visible .mda_instagram_item_mark {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
}

/* The tile is a link now, so it takes focus. The ring is drawn outside the
   rounded corner rather than inset, or the overflow:hidden above clips it. */
.mda_instagram_item:focus-visible {
	outline: 2px solid var(--theme-color-title);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.mda_instagram_item:hover .mda_instagram_item_mark,
	.mda_instagram_item:focus-visible .mda_instagram_item_mark {
		transform: translate(-50%, -50%);
	}
}

@media (max-width: 1023px) {
	.mda_instagram_grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 15px;
	}
}

@media (max-width: 767px) {
	.mda_instagram {
		padding-top: 45px;
	}
	.mda_instagram_grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 12px;
		padding: 0 15px;
	}

	/* Two tiles on a phone rather than six.

	   At two columns the full set became three rows of near-full-width squares
	   between the map and the footer - a long scroll through pictures the
	   visitor did not ask for, sitting directly in front of the contact
	   details. One row makes the same point: there is an Instagram, here is
	   what it looks like, the heading above is the way in.

	   Hidden rather than cut from the markup because the choice is a viewport
	   question and the markup is shared with the desktop layout. Nothing is
	   wasted: these carry loading="lazy", and a display:none image is never
	   fetched, so a phone downloads two photographs instead of six.

	   Which two is simply the first two from
	   clean_child_get_instagram_images(). To show a different pair, reorder
	   that list - it is filterable - rather than changing the number here. */
	.mda_instagram_item:nth-child(n + 3) {
		display: none;
	}
}


/* About Us page (template-about.php)
   ------------------------------------------------------------
   Follows the theme demo's About layout: a two-tone hero headline with the
   lead paragraphs set to one side, a facts row, alternating heading/body
   sections, an oversized watermark word, a staggered photo row and a centred
   closing call to action.

   Sections that depend on a photograph carry a _no_media class when the file
   isn't bundled, which collapses the grid to one column so the copy runs full
   width instead of leaving a hole.
------------------------------------------------------------ */

.about_page .about_eyebrow {
	display: block;
	margin-bottom: 22px;
	color: var(--theme-color-link);
	font-size: 13px;
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.about_page .about_section_title {
	margin-top: 0;
	margin-bottom: 0.7em;
}

.about_page .about_section_title_large {
	margin-bottom: 0;
	font-size: clamp(32px, 4vw, 52px);
	line-height: 1.15;
}

/* ---------- Hero ---------- */

/* Two columns: the eyebrow and headline travel together as one block on the
   left, the lead copy on the right.

   The copy is roughly three times the headline's height, so the two will never
   match by chance. The headline block is centred against it rather than
   top- or bottom-aligned: bottom-aligning drove a gap between the eyebrow and
   the headline it belongs to, and top-aligning left the headline dangling
   above a long column of copy. Centred, the whole hero reads as balanced with
   no orphaned space anywhere in it. */
.about_page .about_hero {
	display: grid;
	grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
	gap: 0 70px;
	align-items: center;
	padding-top: 30px;
	margin-bottom: 55px;
}

.about_page .about_hero_head {
	grid-column: 1;
}

.about_page .about_hero .about_eyebrow {
	margin-bottom: 18px;
}

.about_page .about_hero_title {
	margin: 0;
	font-size: clamp(34px, 4.3vw, 58px);
	line-height: 1.14;
	letter-spacing: -0.01em;
}

/* The opening clause takes its own line in a lighter tone, so the tonal shift
   lands on a line break instead of mid-sentence. */
.about_page .about_hero_title_lead {
	display: block;
	color: var(--theme-color-meta);
}

.about_page .about_hero_text {
	grid-column: 2;
	font-size: 17px;
	line-height: 1.75;
}

.about_page .about_hero_text p:last-child {
	margin-bottom: 0;
}

.about_page .about_hero_media {
	margin: 0 0 70px;
}

/* A fixed band rather than whatever proportions the file happens to have.

   about-hero.webp is 1800x1000, which is this ratio exactly, so it is unchanged
   by the crop. treatments-banner.webp is 1100x733 - half again as tall for its
   width - and with height:auto it rendered about 860px deep at full content
   width, taller than the window it opened in and a different shape from the
   other hero on the site. Declaring the band means a hero is the same object on
   every page and a replacement photograph cannot change the page's proportions
   by being a different crop. */
.about_page .about_hero_media img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 9 / 5;
	object-fit: cover;
	object-position: center;
	border-radius: var(--theme-var-global-border-radius, 10px);
}

/* ---------- Facts row ---------- */

/* An editorial rail: a hairline over each item with a short accent segment at
   its left end. The rule is drawn per item rather than as one line across the
   whole row so that the columns stay marked out when the grid drops to two-up
   and then one-up - and so the four read as one component instead of four
   blocks of text floating in space. */
.about_page .about_facts {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	align-items: start;
	gap: 34px 40px;
	margin-bottom: 90px;
}

/* Each item spans two shared rows - one for the labels, one for the values - so
   every value starts on the same line as its neighbours even when a label wraps.
   Without this, "Consultation & aftercare" going to two lines at narrow widths
   pushes its value down while the item beside it stays put, which is the same
   ragged baseline this rail was built to remove. The item overrides the row gap
   within its own span, so label-to-value stays tight while the gap between the
   two rows of facts stays open. Browsers without subgrid fall back to each item
   sizing itself, which is the previous behaviour rather than a broken one. */
.about_page .about_fact {
	position: relative;
	display: grid;
	grid-row: span 2;
	grid-template-rows: subgrid;
	gap: 8px;
	padding-top: 20px;
	border-top: 1px solid var(--theme-color-bd_color);
}

.about_page .about_fact::before {
	content: "";
	position: absolute;
	top: -1px;
	left: 0;
	width: 34px;
	height: 1px;
	background-color: var(--theme-color-link);
}

/* A true eyebrow now: small, tracked and uppercase, so it introduces the value
   instead of competing with it. At 15px sentence case it sat in the same
   register as body copy, which left the pair with no hierarchy. */
.about_page .about_fact_label {
	display: block;
	align-self: start;
	color: var(--theme-color-meta);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.1em;
	line-height: 1.4;
	text-transform: uppercase;
}

/* Sized to hold the longest value, "RN Prescriber", on one line at desktop.
   The old ceiling of 46px is a numeral size - fine for the invented metrics
   this row replaced, wrong for word values. It forced that one item onto two
   lines while the other three stayed single-line, so the row had no shared
   baseline and read as a fault rather than a set. */
.about_page .about_fact_value {
	display: block;
	color: var(--theme-color-title);
	font-family: var(--theme-font-h1_font-family);
	font-size: clamp(23px, 2.1vw, 31px);
	line-height: 1.25;
	text-wrap: balance;
}

/* ---------- Heading + body + photo split ---------- */

/* stretch, so both columns share one height. The photograph is a tall
   portrait and the copy is two short paragraphs, so left to themselves the
   image stood roughly three times the height of the text beside it. */
.about_page .about_split {
	display: grid;
	grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
	gap: 60px;
	align-items: stretch;
	margin-bottom: 90px;
}

.about_page .about_split_no_media {
	grid-template-columns: minmax(0, 1fr);
	max-width: 44em;
}

/* Copy sits centred in whatever height the row settles at. */
.about_page .about_split_body {
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.about_page .about_split_body p:last-child {
	margin-bottom: 0;
}

/* The image is positioned absolutely inside the figure, so it contributes no
   intrinsic height of its own - the row is sized by the copy and the
   min-height below, and the photograph then fills exactly that box. Whichever
   side is taller, the two columns always finish level. */
.about_page .about_split_media {
	position: relative;
	overflow: hidden;
	margin: 0;
	min-height: clamp(360px, 33vw, 520px);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
}

.about_page .about_split_media img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Bias the crop upwards - the subject's face sits in the top third, and a
	   centred crop on a landscape-ish box would cut it. */
	object-position: center 28%;
}

/* ---------- Meet the team ---------- */

/* Three people in two shapes, because they are two different things to a
   client: Jill treats and has a biography, Kieren and Maisie assist and share
   one note. A single grid of identical cards would have flattened that, and
   would also have set two hundred words of Jill's biography inside a card the
   width of a portrait.

   So: the same split as Millicent's section above, mirrored - her photograph is
   on the right, Jill's is on the left - and then a quiet two-up row underneath.
   The mirroring is what stops two biographies in a row reading as a template. */
.about_page .about_team {
	margin-bottom: 90px;
}

.about_page .about_team_head {
	max-width: 24em;
	margin-bottom: 45px;
}

.about_page .about_team_lead {
	display: grid;
	grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
	gap: 60px;
	align-items: stretch;
	margin-bottom: 70px;
}

.about_page .about_team_lead_no_media {
	grid-template-columns: minmax(0, 1fr);
	max-width: 44em;
}

/* Same absolute-inside-a-min-height trick as .about_split_media: the portrait
   contributes no intrinsic height, so the row is sized by the biography beside
   it and the two columns always finish level however long the copy runs. */
.about_page .about_team_lead_media {
	position: relative;
	overflow: hidden;
	margin: 0;
	min-height: clamp(380px, 34vw, 560px);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
}

.about_page .about_team_lead_media img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* The client replaced the old close-up with a standing portrait against a
	   plain wall. She is centred horizontally in it now, so the 32% that used
	   to pull her back into frame would push her out of it instead. Her head
	   runs from 37% to 58% of the frame's height with a lot of empty wall above
	   - 44% puts her face just above the middle of the box and keeps her hands
	   inside the bottom edge on the tall end of the min-height clamp. */
	object-position: center 44%;
}

.about_page .about_team_lead_body {
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.about_page .about_team_name {
	margin: 0 0 6px;
	font-size: clamp(24px, 2.2vw, 30px);
	line-height: 1.25;
}

/* The letters after the name. Smaller, tracked out and in the meta colour, so
   the qualifications read as credentials rather than as a subtitle competing
   with the name above them. */
.about_page .about_team_credentials {
	margin: 0 0 22px;
	color: var(--theme-color-meta);
	font-size: 13px;
	letter-spacing: 0.04em;
	line-height: 1.5;
	text-transform: uppercase;
}

.about_page .about_team_lead_body p:last-child {
	margin-bottom: 0;
}

/* The shared note, then the pair. Held to a reading measure and centred over
   the two cards below it. */
.about_page .about_team_support_text {
	max-width: 46em;
	margin: 0 auto 35px;
	text-align: center;
}

.about_page .about_team_grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 30px;
	max-width: 760px;
	margin: 0 auto;
}

.about_page .about_team_member {
	margin: 0;
	text-align: center;
}

/* 4:5, the same proportion the photographs were cropped to on the way in, so
   nothing is cropped a second time here. */
.about_page .about_team_member_media {
	overflow: hidden;
	margin-bottom: 18px;
	aspect-ratio: 4 / 5;
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
}

.about_page .about_team_member_media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 22%;
	transition: transform .6s cubic-bezier(.2, .6, .2, 1);
}

.about_page .about_team_member:hover .about_team_member_media img {
	transform: scale(1.04);
}

.about_page .about_team_member_body {
	padding: 0;
}

.about_page .about_team_member_name {
	margin: 0 0 4px;
	font-size: clamp(18px, 1.5vw, 21px);
	line-height: 1.3;
}

.about_page .about_team_member_role {
	margin: 0;
	color: var(--theme-color-meta);
	font-size: 13px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
	.about_page .about_team_member:hover .about_team_member_media img {
		transform: none;
	}
}

/* ---------- Oversized watermark word ---------- */

/* container-type makes the word size itself against this box rather than the
   viewport. The box is not the viewport - .alignfull leaves an 8px gutter each
   side, and on desktop 100vw also counts the scrollbar - so vw sizing was
   always measuring against something wider than the space the word actually
   has. */
.about_page .about_watermark {
	container-type: inline-size;
	overflow: hidden;
	margin-bottom: 90px;
	line-height: 1;
	text-align: center;
	/* Decorative only, and hidden from assistive tech in the markup. */
	user-select: none;
}

/* Set as one line that must fit the width, so the size is a ratio, not a guess.
   "AESTHETICS" in Trirong at this tracking measures 6.27x its own font-size, so
   anything above 15.9% of the box overflows. The old 17vw was past that at every
   width, and the 80px floor was worse: on a 320px phone it forced a 501px word
   into a 320px box, which is why the ends were being cut off on small screens.
   15% leaves about 6% of slack for the fallback face if Trirong is slow.

   No floor. A watermark that will not fit is not a watermark, it is a stray
   letter at each edge. */
.about_page .about_watermark span {
	display: block;
	color: var(--theme-color-bg_color_2);
	font-family: var(--theme-font-h1_font-family);
	font-size: min(15vw, 260px);
	font-size: min(15cqw, 260px);
	letter-spacing: 0.02em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* ---------- Heading one side, body the other ---------- */

.about_page .about_intro_split {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: 50px 60px;
	align-items: start;
	margin-bottom: 50px;
}

.about_page .about_intro_split_body p:last-child {
	margin-bottom: 0;
}

/* ---------- Staggered photo row ---------- */

.about_page .about_gallery {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 25px;
	align-items: start;
	margin-bottom: 90px;
}

.about_page .about_gallery_item {
	margin: 0;
}

/* One shared ratio and no vertical offsets, so tops and bottoms line up. */
.about_page .about_gallery_link {
	position: relative;
	display: block;
	overflow: hidden;
	aspect-ratio: 4 / 5;
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
}

.about_page .about_gallery_link img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .6s ease;
}

.about_page .about_gallery_link:hover img,
.about_page .about_gallery_link:focus-visible img {
	transform: scale(1.05);
}

/* Hover: the photo keeps its own colour - only a ringed plus floats over it,
   with the faintest scrim so the white ring reads on a light image. */
.about_page .about_gallery_zoom {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	opacity: 0;
	background-color: rgba(0, 0, 0, 0.08);
	transition: opacity .35s ease;
}

.about_page .about_gallery_link:hover .about_gallery_zoom,
.about_page .about_gallery_link:focus-visible .about_gallery_zoom {
	opacity: 1;
}

/* The ring */
.about_page .about_gallery_zoom::before {
	content: '';
	width: 74px;
	height: 74px;
	border: 2px solid rgba(255, 255, 255, 0.9);
	border-radius: 50%;
	transform: scale(0.8);
	transition: transform .35s ease;
}

.about_page .about_gallery_link:hover .about_gallery_zoom::before,
.about_page .about_gallery_link:focus-visible .about_gallery_zoom::before {
	transform: scale(1);
}

/* The plus: the horizontal bar is the element itself, the vertical bar is a
   centred background stripe, so it needs no extra markup. */
.about_page .about_gallery_zoom::after {
	content: '';
	position: absolute;
	width: 22px;
	height: 2px;
	background-color: #ffffff;
	background-image: linear-gradient(#ffffff, #ffffff);
	background-position: center;
	background-repeat: no-repeat;
	background-size: 2px 22px;
}

/* ---------- Where our clients travel from ---------- */

/* Text on the left, map on the right, and the map is the narrower column: the
   UK is a tall, thin shape, so giving it half the width would have left a
   column of white either side of it and pushed the section past a screen and a
   half. 1.15fr/0.85fr lets the outline fill its column at a sensible height.

   align-items: center rather than stretch - the list of places is much shorter
   than the map is tall, and topping it out left it floating against the
   Scottish highlands. */
.about_page .about_map {
	display: grid;
	grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
	gap: clamp(30px, 5vw, 70px);
	align-items: center;
	margin-bottom: 90px;
}

.about_page .about_map_text {
	margin: 0 0 26px;
	max-width: 46ch;
}

/* The places, as text. A wrapping row of chips rather than a bulleted list:
   twelve place names in a column is a long thin list nobody reads, and as
   chips they read as a group at a glance, which is the point the section is
   making. list-style is dropped but the <ul> stays - it is a list, and a
   screen reader should still say how many are in it. */
.about_page .about_map_places {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.about_page .about_map_place {
	padding: 8px 16px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: 100px;
	background-color: var(--theme-color-bg_color);
	font-size: 14px;
	line-height: 1.4;
	color: var(--theme-color-text);
}

/* Clients from outside the UK. Set apart from the plotted places rather than
   mixed in with them: these have no dot on the artwork, and a chip that looks
   identical to Lincoln invites the reader to hunt the map for a dot that is
   not there. Outlined in the accent instead of filled, so the group reads as
   related but separate.

   Colours come from the THEME's accent tokens, not from a named palette
   colour, so this component follows whatever palette the site is running -
   the current rose, or a replacement - without being edited. The text step is
   --theme-color-hover rather than --theme-color-link for the usual reason on
   this site: the lighter accent does not clear AA at label size. */
.about_page .about_map_further_title {
	margin: 22px 0 10px;
	font-size: 13px;
	line-height: 1.4;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--theme-color-title);
}

.about_page .about_map_place_further {
	border-color: var(--theme-color-link);
	background-color: transparent;
	color: var(--theme-color-hover);
}

/* The clinic itself, marked the same way it is on the map. */
.about_page .about_map_place_home {
	border-color: var(--mda-button);
	background-color: var(--mda-button);
	color: #ffffff;
	font-weight: 500;
}

.about_page .about_map_place_note {
	opacity: 0.72;
	font-size: 13px;
}

.about_page .about_map_figure {
	display: flex;
	justify-content: center;
}

/* Capped in height rather than width: the column is the constraint on a wide
   screen and the viewport is on a narrow one, and a 760-unit-tall outline will
   happily run off the bottom of a laptop if only its width is bounded. */
.about_page .about_map_svg {
	display: block;
	width: 100%;
	max-width: 420px;
	max-height: 70vh;
	height: auto;
}

.about_page .about_map_land {
	fill: var(--theme-color-bg_color_2);
	stroke: var(--theme-color-bd_color);
	stroke-width: 1.2;
	stroke-linejoin: round;
}

.about_page .about_map_dot {
	fill: var(--theme-color-link);
}

.about_page .about_map_dot_home {
	fill: var(--mda-button);
}

/* A soft ring around Louth so the clinic reads as the centre of the cluster
   rather than as one more dot in it. */
.about_page .about_map_halo {
	fill: var(--theme-color-link);
	opacity: 0.16;
}

.about_page .about_map_label {
	font-family: inherit;
	font-size: 17px;
	font-weight: 500;
	fill: var(--theme-color-title);
}

@media (max-width: 900px) {
	.about_page .about_map {
		grid-template-columns: minmax(0, 1fr);
	}
	/* Map first on a phone: it is the thing the section is for, and it says
	   what the heading says faster than the paragraph does. */
	.about_page .about_map_figure {
		order: -1;
	}
	.about_page .about_map_svg {
		max-width: 320px;
		max-height: 60vh;
	}
}

/* ---------- What we stand for ---------- */

.about_page .about_values {
	margin-bottom: 90px;
	text-align: center;
}

/* No width cap on the heading: at 52px, 24em forced "The standard we hold
   ourselves to" onto three lines in the middle of a full-width section. It is
   a centred heading with nothing beside it, so it can have the room. */
.about_page .about_values_head {
	margin: 0 auto 55px;
}

.about_page .about_values_grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 45px 40px;
	text-align: center;
}

/* Cards sit on the tinted panel colour so they read against the page, with
   the icon bubble inverted to the page colour so it stays visible on top. */
.about_page .about_value {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 42px 28px 38px;
	border: 1px solid transparent;
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
	transition: transform .35s ease, border-color .35s ease, box-shadow .35s ease;
}

/* Hover comes from the shared card rule at the foot of this file. */

.about_page .about_value_icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 62px;
	height: 62px;
	margin-bottom: 22px;
	border-radius: 50%;
	background-color: var(--theme-color-bg_color);
	color: var(--theme-color-link);
	transition: background-color .35s ease, color .35s ease;
}

.about_page .about_value:hover .about_value_icon {
	background-color: var(--theme-color-link);
	color: var(--theme-color-bg_color);
}

/* The icon itself turns a full revolution on hover. */
.about_page .about_value_icon svg {
	transition: transform .7s ease;
}

.about_page .about_value:hover .about_value_icon svg {
	transform: rotate(360deg);
}

.about_page .about_value_icon svg {
	width: 26px;
	height: 26px;
}

.about_page .about_value_title {
	margin-top: 0;
	margin-bottom: 0.6em;
	font-size: 19px;
	line-height: 1.3;
}

.about_page .about_value_text {
	margin-bottom: 0;
}

/* ---------- Closing call to action ---------- */

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

@media (max-width: 1023px) {
	.about_page .about_facts {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
	.about_page .about_split,
	.about_page .about_team_lead {
		gap: 40px;
	}
	.about_page .about_gallery {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
	.about_page .about_values_grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
	/* Below this width the two hero columns each get too narrow to read, so
	   the copy goes under the headline rather than beside it. */
	.about_page .about_hero {
		grid-template-columns: minmax(0, 1fr);
		gap: 0;
	}
	.about_page .about_hero_head {
		grid-column: 1;
		margin-bottom: 28px;
	}
	.about_page .about_hero_title {
		max-width: 15em;
	}
	.about_page .about_hero_text {
		grid-column: 1;
		max-width: 42em;
	}
}

@media (max-width: 767px) {
	.about_page .about_hero {
		padding-top: 10px;
		margin-bottom: 40px;
	}
	.about_page .about_hero_title {
		margin-bottom: 24px;
		max-width: none;
	}
	.about_page .about_hero_text {
		font-size: 16px;
	}
	.about_page .about_hero_media,
	.about_page .about_facts,
	.about_page .about_split,
	.about_page .about_team,
	.about_page .about_watermark,
	.about_page .about_gallery,
	.about_page .about_values {
		margin-bottom: 55px;
	}
	.about_page .about_split,
	.about_page .about_team_lead {
		grid-template-columns: minmax(0, 1fr);
		gap: 30px;
	}
	/* Photo above the copy on narrow screens, and shorter - stacked, it no
	   longer has to match anything, so a full-height portrait would push the
	   copy most of a screen down the page. */
	.about_page .about_split_media,
	.about_page .about_team_lead_media {
		order: -1;
		min-height: 0;
		aspect-ratio: 4 / 3;
	}
	.about_page .about_team_head {
		margin-bottom: 30px;
	}
	.about_page .about_team_lead {
		margin-bottom: 45px;
	}
	/* The pair stay two across rather than stacking. They are name-and-face
	   cards with two lines of text under them, not content - one per screen
	   would turn a footnote into two full scrolls. */
	.about_page .about_team_grid {
		gap: 18px;
	}
	.about_page .about_team_support_text {
		margin-bottom: 28px;
		text-align: left;
	}
	.about_page .about_intro_split {
		grid-template-columns: minmax(0, 1fr);
		gap: 25px;
		margin-bottom: 35px;
	}
	.about_page .about_gallery {
		gap: 15px;
	}
	.about_page .about_value {
		padding: 34px 24px 30px;
	}
	.about_page .about_values_grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 35px;
	}
}


/* Gallery lightbox (js/about-gallery.js)
   ------------------------------------------------------------
   Built in the child theme because the parent ships none. The markup is
   created by the script, so none of this applies until the overlay opens.
------------------------------------------------------------ */

body.mda_lightbox_lock {
	overflow: hidden;
}

.mda_lightbox {
	position: fixed;
	inset: 0;
	z-index: 100000;
	display: flex;
	align-items: center;
	justify-content: center;
	visibility: hidden;
	opacity: 0;
	padding: 40px 90px;
	background-color: rgba(20, 18, 17, 0.92);
	transition: opacity .3s ease, visibility .3s ease;
}

.mda_lightbox_open {
	visibility: visible;
	opacity: 1;
}

.mda_lightbox_figure {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 18px;
	margin: 0;
	max-width: 100%;
	max-height: 100%;
}

/* pan-y pinch-zoom hands horizontal drags to js/about-gallery.js so they can be
   read as swipes, while leaving vertical panning and pinch-to-zoom to the
   browser - a visitor must still be able to zoom into a treatment photograph.
   Without this the browser claims the horizontal gesture first and the swipe
   never reaches the script.

   The transition is on transform only. The image follows the finger during a
   drag and springs back when it is released, and animating anything else here
   would fight the src swap. */
.mda_lightbox_image {
	display: block;
	max-width: 100%;
	/* Leave room for the caption underneath. */
	max-height: calc(100vh - 160px);
	width: auto;
	height: auto;
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: rgba(255, 255, 255, 0.06);
	touch-action: pan-y pinch-zoom;
	transition: transform .25s ease;
	/* Stops the long-press "save image" drag turning into a text selection
	   halfway through a swipe. */
	user-select: none;
	-webkit-user-drag: none;
}

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

.mda_lightbox_caption {
	display: flex;
	align-items: center;
	gap: 14px;
	color: rgba(255, 255, 255, 0.85);
	font-size: 15px;
	line-height: 1.4;
	text-align: center;
}

.mda_lightbox_counter {
	color: rgba(255, 255, 255, 0.5);
	font-size: 13px;
	white-space: nowrap;
}

/* ---------- Controls ---------- */

/* z-index because these are written before the figure in the markup and, at
   equal stacking, the later element wins. On a wide screen it never showed:
   the arrows sit outside the picture and nothing overlaps them. On a phone the
   picture fills the width and the arrows land on top of it, so the image
   painted straight over them - present in the DOM, invisible and untappable,
   which is why the gallery looked like it had no controls on mobile. */
.mda_lightbox_close,
.mda_lightbox_nav {
	position: absolute;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	padding: 0;
	border: none;
	border-radius: 50%;
	background-color: rgba(255, 255, 255, 0.12);
	color: #ffffff;
	cursor: pointer;
	transition: background-color .25s ease;
}

.mda_lightbox_close:hover,
.mda_lightbox_nav:hover,
.mda_lightbox_close:focus-visible,
.mda_lightbox_nav:focus-visible {
	background-color: var(--theme-color-link);
}

.mda_lightbox_close {
	top: 25px;
	right: 25px;
}

/* The X, drawn from one element with two crossed bars. */
.mda_lightbox_close span {
	position: relative;
	width: 18px;
	height: 18px;
}

.mda_lightbox_close span::before,
.mda_lightbox_close span::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 0;
	width: 100%;
	height: 2px;
	margin-top: -1px;
	background-color: currentColor;
}

.mda_lightbox_close span::before {
	transform: rotate(45deg);
}

.mda_lightbox_close span::after {
	transform: rotate(-45deg);
}

.mda_lightbox_prev {
	top: 50%;
	left: 25px;
	margin-top: -24px;
}

.mda_lightbox_next {
	top: 50%;
	right: 25px;
	margin-top: -24px;
}

/* Chevrons: a rotated corner of a square. */
.mda_lightbox_nav span {
	width: 11px;
	height: 11px;
	border-top: 2px solid currentColor;
	border-right: 2px solid currentColor;
}

.mda_lightbox_prev span {
	transform: rotate(-135deg);
	margin-left: 4px;
}

.mda_lightbox_next span {
	transform: rotate(45deg);
	margin-right: 4px;
}

/* A single image needs no previous/next. */
.mda_lightbox_single .mda_lightbox_nav {
	display: none;
}

@media (max-width: 767px) {
	.mda_lightbox {
		padding: 70px 15px;
	}
	.mda_lightbox_image {
		max-height: calc(100vh - 220px);
	}
	.mda_lightbox_close {
		top: 15px;
		right: 15px;
	}
	.mda_lightbox_prev {
		left: 15px;
	}
	.mda_lightbox_next {
		right: 15px;
	}

	/* Here the controls sit on the photograph rather than on the backdrop
	   beside it, and a 12% white wash disappears over a pale one. A dark disc
	   with a soft ring reads on any image without hiding much of it. */
	.mda_lightbox_close,
	.mda_lightbox_nav {
		background-color: rgba(20, 18, 17, 0.55);
		box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.25);
		backdrop-filter: blur(2px);
	}

	.mda_lightbox_caption {
		flex-direction: column;
		gap: 6px;
	}
}

/* Respect a reduced-motion preference for the page's hover animations. */
@media (prefers-reduced-motion: reduce) {
	.about_page .about_gallery_link img,
	.about_page .about_value,
	.about_page .about_value_icon,
	.about_page .about_value_icon svg,
	.mda_lightbox {
		transition: none;
	}
	.about_page .about_value:hover .about_value_icon svg {
		transform: none;
	}
}


/* Our Treatments page (template-treatments.php)
   ------------------------------------------------------------
   Shares the About page's hero, section-title and CTA styles (the template
   carries .about_page alongside .treatments_page), so only the price list
   itself is styled here.
------------------------------------------------------------ */

.treatments_page .treatments_menu {
	margin-bottom: 90px;
}

/* The cap used to sit on the whole block, which forced a 52px heading to wrap
   after two words while two thirds of the page sat empty beside it. The
   heading now runs its natural width and only the prose below is held to a
   reading measure - which is what the cap was for in the first place. */
.treatments_page .treatments_menu_head {
	margin-bottom: 55px;
}

.treatments_page .treatments_menu_note {
	max-width: 38em;
	margin: 22px 0 0;
	color: var(--theme-color-meta);
	font-size: 15px;
}

/* stretch, not start: cards in the same row run to a common height, so their
   bottom edges line up instead of the shorter one leaving a void beside its
   neighbour. */
.treatments_page .treatments_groups {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 30px;
	align-items: stretch;
}

/* A flex column so the note inside can be pushed to the card's foot. */
.treatments_page .treatments_group {
	display: flex;
	flex-direction: column;
	padding: 38px 34px;
	border: 1px solid transparent;
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
	transition: border-color .35s ease, box-shadow .35s ease;
}

/* A final card with no partner would otherwise sit in the left column with
   empty space beside it. Spanning the full width reads as deliberate. */
.treatments_page .treatments_group:last-child:nth-child(odd) {
	grid-column: 1 / -1;
}

/* Hover comes from the shared card rule at the foot of this file. */

.treatments_page .treatments_group_title {
	margin: 0 0 22px;
	padding-bottom: 18px;
	border-bottom: 1px solid var(--theme-color-bd_color);
	font-size: 22px;
	line-height: 1.25;
}

/* The list itself carries the column track, and each row adopts it with
   subgrid. That is what makes the price column line up down the whole card
   rather than each row sizing itself independently - every name starts at the
   same x, every price ends at the same x. */
.treatments_page .treatments_rows {
	display: grid;
	grid-template-columns: minmax(7em, 1fr) auto;
	list-style: none;
	margin: 0;
	padding: 0;
}

.treatments_page .treatments_row {
	display: grid;
	grid-column: 1 / -1;
	grid-template-columns: subgrid;
	align-items: baseline;
	gap: 6px 20px;
	padding: 13px 0;
	border-bottom: 1px solid var(--theme-color-bd_color);
}

/* Where subgrid isn't available the row falls back to the previous flex
   arrangement: still name-left / prices-right, just sized per row. */
@supports not (grid-template-columns: subgrid) {
	.treatments_page .treatments_rows {
		display: block;
	}
	.treatments_page .treatments_row {
		display: flex;
		flex-wrap: wrap;
		justify-content: space-between;
	}
}

.treatments_page .treatments_row:last-child {
	border-bottom: none;
	padding-bottom: 0;
}

.treatments_page .treatments_row_name {
	grid-column: 1;
	color: var(--theme-color-title);
	font-size: 16px;
	line-height: 1.4;
}

/* Chips stay on the name's line and wrap within their own column when there
   are three or four of them, so the behaviour is the same in every card
   instead of some rows pushing the chips onto a line of their own. */
.treatments_page .treatments_row_options {
	grid-column: 2;
	display: flex;
	flex-wrap: wrap;
	gap: 6px 10px;
	justify-content: flex-end;
}

/* Chips sit on a tinted card, so an untinted fill alone left them barely
   distinguishable from it. A hairline gives each one an edge, which is what
   makes a price read as a price rather than as loose text. */
.treatments_page .treatments_option,
.treatments_page .treatments_row_price {
	display: inline-flex;
	align-items: baseline;
	gap: 7px;
	padding: 5px 13px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: 100px;
	background-color: #ffffff;
	white-space: nowrap;
	transition: border-color .25s ease, background-color .25s ease, transform .25s ease, box-shadow .25s ease;
}

.treatments_page .treatments_option_label {
	color: var(--theme-color-meta);
	font-size: 13px;
}

/* The deeper rose, not the brand rose: #B76E79 on white is 3.6:1 and fails AA
   at this size, #9F5A64 is 5.1:1 and passes. Same hue, legible price. */
.treatments_page .treatments_option_price,
.treatments_page .treatments_row_price {
	color: var(--theme-color-hover);
	font-size: 15px;
	font-weight: 500;
	white-space: nowrap;
}

/* A row with one price rather than chips lands in the same column and finishes
   on the same right edge, so £200 and £275 line up with the chip rows. */
.treatments_page .treatments_row_price {
	grid-column: 2;
	justify-self: end;
	text-align: right;
}

/* Hover sits on the price chip itself, not on the row.

   The row used to take a translucent white fill, which washed a pale band
   across the tinted card and read as a rendering fault rather than as feedback
   - the row is not clickable, so there was nothing for it to be feedback about.
   The chip is the thing being looked at, so the chip is the thing that responds.

   Pointer-only: :hover on a touch screen sticks after a tap. */
@media (hover: hover) {
	/* Hovering anywhere along the line lights its own prices, so with eight
	   treatments in a card it is unambiguous which price belongs to the name
	   the pointer is on. The row itself still takes no fill - that was the
	   white band - it only passes the state down to its chips. */
	.treatments_page .treatments_row:hover .treatments_option,
	.treatments_page .treatments_row:hover .treatments_row_price,
	.treatments_page .treatments_option:hover,
	.treatments_page .treatments_row_price:hover {
		transform: translateY(-1px);
		border-color: var(--theme-color-hover);
		background-color: rgba(159, 90, 100, 0.06);
		box-shadow: 0 6px 14px rgba(159, 90, 100, 0.16);
	}
}

/* Treatment areas listed without individual prices */
.treatments_page .treatments_tags {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* A hairline at rest so the chip keeps its edge when the fill changes on
   hover - without it the border appearing on hover made the chip jump a pixel
   wider. */
.treatments_page .treatments_tag {
	padding: 6px 14px;
	border: 1px solid transparent;
	border-radius: 100px;
	background-color: var(--theme-color-bg_color);
	color: var(--theme-color-title);
	font-size: 14px;
	line-height: 1.4;
	transition: border-color .25s ease, background-color .25s ease, transform .25s ease, box-shadow .25s ease;
}

/* Same response as the price chips, so every chip on this page behaves alike.
   These are list items rather than links - nothing here is clickable - so the
   effect is doing the same job it does on the prices: marking what the pointer
   is on in a card that can carry a dozen of them. */
@media (hover: hover) {
	.treatments_page .treatments_tag:hover {
		transform: translateY(-1px);
		border-color: var(--theme-color-hover);
		background-color: rgba(159, 90, 100, 0.06);
		box-shadow: 0 6px 14px rgba(159, 90, 100, 0.16);
	}
}

/* Pinned to the foot of the card, so notes line up across a row instead of
   sitting wherever their own content happens to end. The gap above comes from
   padding, because an auto margin collapses to nothing when there is no slack
   to absorb and the note would then touch the last price row. */
.treatments_page .treatments_group_note {
	margin: auto 0 0;
	padding-top: 20px;
	color: var(--theme-color-meta);
	font-size: 14px;
	line-height: 1.5;
}

@media (max-width: 1023px) {
	.treatments_page .treatments_groups {
		grid-template-columns: minmax(0, 1fr);
	}
	/* One column: every card is already full width, so the last-card span
	   has nothing to do. */
	.treatments_page .treatments_group:last-child:nth-child(odd) {
		grid-column: auto;
	}
}

@media (max-width: 767px) {
	.treatments_page .treatments_menu {
		margin-bottom: 55px;
	}
	.treatments_page .treatments_menu_head {
		margin-bottom: 35px;
	}
	.treatments_page .treatments_group {
		padding: 28px 22px;
	}
	/* At phone width a name plus four chips cannot share a line, so the row
	   stacks: name on its own line, chips beneath it, left aligned. Applied
	   to every card so the behaviour stays consistent. */
	.treatments_page .treatments_rows {
		display: block;
	}
	.treatments_page .treatments_row {
		display: flex;
		flex-wrap: wrap;
		align-items: baseline;
		justify-content: space-between;
	}
	.treatments_page .treatments_row_name {
		width: 100%;
	}
	.treatments_page .treatments_row_options {
		justify-content: flex-start;
	}
	.treatments_page .treatments_row_price {
		justify-self: auto;
	}
}


/* Gallery page (template-gallery.php)
   ------------------------------------------------------------
   Before/after photographs keep their own proportions - many are side-by-side
   composites, and cropping them to a uniform tile would cut half the
   comparison away. A CSS column layout lets each keep its natural height.
------------------------------------------------------------ */

/* ---------- Instagram panel ---------- */

/* Sits between the hero and the photographs, because that is where the client
   asked for it to be unmissable. It is the only filled element on a page that
   is otherwise a white grid on cream, which is what makes it read first.

   Filled, not tinted: a pale panel on a pale page is a box, a saturated one is
   an interruption, and the whole point of this block is to interrupt.

   ON THE COLOUR, because it has changed once already and should not change
   again by accident.

   It was built charcoal, during the short window when the whole site's accent
   had been switched to monochrome. That was reverted - the monochrome is scoped
   to the header now - so a charcoal panel was the last piece of a palette the
   rest of the site no longer uses, and it read as a hole in the page rather
   than as part of the brand.

   It is --theme-color-hover (#9F5A64), NOT --theme-color-link (#B76E79), and
   that is a legibility decision rather than a taste one. The brand rose carries
   white text at 3.8:1, which fails WCAG AA - and this panel is carrying a
   21px heading and 15px body copy in white, both of which need 4.5:1. The
   deeper rose reaches 5.1:1 and passes. Same hue, same family as the buttons
   and the price figures elsewhere on the site, legible.

   The same trade-off is written up against the cookie banner further down this
   file, and it is why several components here reach past --theme-color-link for
   Matches --theme-color-meta, the same color used by the hero title lead
   ("Every face is different,") above. */
.gallery_page .gallery_instagram {
	display: flex;
	align-items: center;
	gap: clamp(18px, 2.5vw, 34px);
	margin-bottom: 55px;
	padding: clamp(24px, 3vw, 38px) clamp(24px, 3.4vw, 46px);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-meta);
	color: #ffffff;
}

.gallery_page .gallery_instagram_icon {
	display: inline-flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 62px;
	height: 62px;
	border-radius: 50%;
	/* A hairline ring rather than a filled disc: filled, it became a second
	   button competing with the real one at the other end of the panel.
	   0.38 rather than the 0.28 it carried on the charcoal ground - the rose is
	   a lighter field, so the same alpha all but disappeared on it. */
	border: 1px solid rgba(255, 255, 255, 0.38);
	color: #ffffff;
}

.gallery_page .gallery_instagram_icon svg {
	width: 28px;
	height: 28px;
}

.gallery_page .gallery_instagram_body {
	flex: 1 1 auto;
	min-width: 0;
}

.gallery_page .gallery_instagram_title {
	margin: 0 0 6px;
	color: #ffffff;
	font-size: clamp(21px, 2vw, 28px);
	line-height: 1.25;
}

/* Solid white, not the 0.78 alpha it had on charcoal. Dimmed white over the
   rose lands at 3.8:1 - the exact failure the rose ground was chosen to avoid,
   reintroduced one property lower down. The hierarchy between this and the
   heading above it is carried by size and typeface instead, which is where it
   should have been carried anyway: a 15px sans paragraph under a 28px serif
   heading does not need to be faded to read as secondary. */
.gallery_page .gallery_instagram_text {
	max-width: 46em;
	margin: 0;
	color: #ffffff;
	font-size: 15px;
	line-height: 1.6;
	text-align: left;
}

/* White pill on the rose panel, inverting on hover. Only two colours are in
   play - the panel's rose and white - so the button belongs to the block rather
   than being a third colour introduced to make it stand out. The label takes
   the panel's own rose at 5.1:1 on white. */
.gallery_page .gallery_instagram_button {
	display: inline-flex;
	flex: none;
	align-items: baseline;
	gap: 8px;
	padding: 15px 28px;
	border: 1px solid #ffffff;
	border-radius: 100px;
	background-color: #ffffff;
	color: var(--theme-color-hover);
	font-size: 15px;
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color .3s ease, color .3s ease, transform .3s ease;
}

.gallery_page .gallery_instagram_button:hover,
.gallery_page .gallery_instagram_button:focus-visible {
	transform: translateY(-2px);
	background-color: transparent;
	color: #ffffff;
}

.gallery_page .gallery_instagram_button:focus-visible {
	outline: 2px solid #ffffff;
	outline-offset: 3px;
}

/* The handle, smaller than the label inside the button. It is there so the
   destination is named on a printed page and recognisable to anyone who already
   follows; "Follow" is the label.

   It used to be dimmed to 0.6 to make that hierarchy. Two points smaller does
   the same job and keeps the contrast: at 0.6 over white the rose fell to
   2.4:1, and the handle is 13px, which is exactly the size that cannot afford
   it. Size alone now. */
.gallery_page .gallery_instagram_handle {
	font-size: 13px;
}

@media (prefers-reduced-motion: reduce) {
	.gallery_page .gallery_instagram_button:hover,
	.gallery_page .gallery_instagram_button:focus-visible {
		transform: none;
	}
}

.gallery_page .gallery_filters {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-bottom: 70px;
}

.gallery_page .gallery_filter {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	padding: 10px 18px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: 100px;
	color: var(--theme-color-title);
	font-size: 15px;
	line-height: 1.4;
	transition: border-color .3s ease, background-color .3s ease, color .3s ease;
}

.gallery_page .gallery_filter:hover {
	border-color: var(--theme-color-link);
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-link);
}

.gallery_page .gallery_filter_count {
	color: var(--theme-color-meta);
	font-size: 13px;
}

.gallery_page .gallery_section {
	margin-bottom: 80px;
	/* Clear the theme's fixed header when a jump link lands here. */
	scroll-margin-top: 120px;
}

.gallery_page .gallery_section_head {
	max-width: 40em;
	margin-bottom: 35px;
}

.gallery_page .gallery_section_text {
	margin-bottom: 0;
	color: var(--theme-color-text);
}

/* A real grid, not CSS columns. Columns fill top-to-bottom and then jump to
   the next column, so nothing lines up across a row and the reading order runs
   down the page instead of across it. */
.gallery_page .gallery_grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 25px;
}

.gallery_page .gallery_item {
	margin: 0;
}

/* Square tiles, so every row aligns on both axes. */
.gallery_page .gallery_item_link {
	aspect-ratio: 1 / 1;
	border: 1px solid var(--theme-color-bd_color);
	background-color: var(--theme-color-bg_color_2);
}

/* 'cover', so the photograph fills its tile. Most of these files are square and
   are unaffected; the handful that are not were being letterboxed by 'contain',
   which left a band of panel colour across the top and bottom of the card and
   read as a photograph that had failed to load rather than as a frame. Centred,
   so the crop comes off both edges evenly rather than taking one end whole. */
.gallery_page .gallery_item_link img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}

/* The opt-out, for a photograph that a square crop would ruin - see
   clean_child_gallery_uncropped_images() in template-gallery.php. */
.gallery_page .gallery_item_link_whole img {
	object-fit: contain;
}

.gallery_page .gallery_empty {
	margin-bottom: 70px;
	color: var(--theme-color-meta);
}

@media (max-width: 1023px) {
	.gallery_page .gallery_grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 20px;
	}
	.gallery_page .gallery_filters {
		margin-bottom: 50px;
	}
	/* The button drops under the copy, and the icon goes with the heading, so
	   the three parts become two rows rather than three squeezed columns. */
	.gallery_page .gallery_instagram {
		flex-wrap: wrap;
	}
	.gallery_page .gallery_instagram_body {
		flex: 1 1 260px;
	}
	.gallery_page .gallery_instagram_button {
		flex: 0 0 auto;
		margin-left: auto;
	}
}

@media (max-width: 767px) {
	/* Two columns still, not one: these are before/after pairs, and at one
	   per row on a phone the page becomes an endless scroll. */
	.gallery_page .gallery_grid {
		gap: 12px;
	}
	.gallery_page .gallery_section {
		margin-bottom: 55px;
	}
	/* Stacked and left-aligned. The icon disc goes: at this width it costs a
	   whole row for decoration, and the heading names Instagram anyway. */
	.gallery_page .gallery_instagram {
		flex-direction: column;
		align-items: stretch;
		gap: 18px;
		margin-bottom: 40px;
	}
	.gallery_page .gallery_instagram_icon {
		display: none;
	}
	/* Full width, so the one thing the panel is for is a full-width target
	   rather than a pill floating at the end of a paragraph. */
	.gallery_page .gallery_instagram_button {
		justify-content: center;
		margin-left: 0;
	}
}


/* Book Now page (template-book.php)
------------------------------------------------------------ */

.book_page .book_panel {
	max-width: 40em;
	margin: 40px auto 60px;
	padding: 60px 50px;
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
	text-align: center;
}

.book_page .book_title {
	margin: 0 0 0.6em;
	font-size: clamp(30px, 3.6vw, 46px);
	line-height: 1.15;
}

.book_page .book_text {
	max-width: 30em;
	margin: 0 auto 2em;
	font-size: 18px;
}

.book_page .book_button {
	margin: 0;
}

/* ---------- "Pick whichever suits you" ----------

   Shown only while there is no booking URL to forward to. Four cards, each one
   a way of reaching the clinic, laid out full content width rather than inside
   the narrow .book_panel the redirect screen uses.

   The cards themselves are the site's own card, not a new one: the same panel
   fill, token radius, hairline-on-hover and circular rose icon tile that
   .about_value, .treatments_group and .home_promise already use. They were
   built dark first, which read as a slab dropped in from another site - the
   only dark grounds here are the full-bleed call-to-action band and the
   footer, and both earn it by running edge to edge. */

.book_page .book_ways_head {
	max-width: 34em;
	margin: 20px 0 45px;
}

.book_page .book_ways_title {
	margin: 0 0 0.5em;
	font-size: clamp(30px, 3.6vw, 46px);
	line-height: 1.15;
}

.book_page .book_ways_text {
	margin: 0;
	color: var(--theme-color-text);
	font-size: 18px;
	line-height: 1.7;
}

/* Heads the card row. Set below the <h1> rather than level with it, so the two
   read as page title then section title instead of competing. */
.book_page .book_ways_subtitle {
	margin: 0 0 30px;
	font-size: clamp(24px, 2.6vw, 34px);
	line-height: 1.2;
}

/* auto-fit rather than a fixed four, so the row reflows on its own as the
   viewport narrows and the cards never fall below a readable measure. */
.book_page .book_ways {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(265px, 1fr));
	gap: 24px;
	align-items: stretch;
}

/* Column layout with the actions pushed to the bottom by margin-top: auto, so
   every button in the row sits on the same line however long its card's copy
   runs. Fill, radius and the transparent border that the shared hover rule at
   the foot of this file colours in are all as .about_value and
   .treatments_group - this is the same card, laid out differently. */
.book_page .book_way {
	display: flex;
	flex-direction: column;
	padding: 38px 28px 34px;
	border: 1px solid transparent;
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
}

/* One step lighter than the card, so the tile reads as a well rather than as a
   sticker - the same relationship .about_value_icon has with its own card. */
.book_page .book_way_icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 52px;
	height: 52px;
	margin-bottom: 24px;
	border-radius: 50%;
	background-color: var(--theme-color-bg_color);
	color: var(--theme-color-link);
	transition: background-color .35s ease, color .35s ease, transform .35s ease;
}

.book_page .book_way:hover .book_way_icon {
	transform: rotate(-8deg) scale(1.06);
	background-color: var(--theme-color-link);
	color: #ffffff;
}

/* The theme sets h3 at 35px, which is a section heading, not a card heading.
   Two of these titles run to two lines at 20px and would run to three at the
   theme size. */
.book_page .book_way_title {
	margin: 0 0 0.55em;
	color: var(--theme-color-title);
	font-size: 20px;
	line-height: 1.3;
}

.book_page .book_way_text {
	margin: 0;
	line-height: 1.75;
}

.book_page .book_way_actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: auto;
	padding-top: 30px;
}

/* Two buttons on one line rather than stacked.

   The wrapping flex row could not hold them: with four cards across, a card is
   about 246px wide inside its own padding, and two pills at the size the other
   cards use want roughly 255px - so the second dropped to its own line and the
   pair read as a list rather than as a choice between two platforms.

   Grid, so the two share the width instead of each asking for what it wants,
   and they come out the same size as each other whatever their labels say. The
   type and padding come down a step to fit: at 14px the wider of the two labels
   needs about 111px of pill, against the 119px a column gets at full width.

   auto-fit rather than a hard repeat(2): below about 240px of card there is
   genuinely no room for two, and this drops them back to one column on its own
   instead of clipping a label against a fixed track. The 116px floor is that
   111px plus a margin for a font that measures a little wider than Work Sans -
   the fallback face while the webfont loads, most likely. */
.book_page .book_way_actions_pair {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(116px, 1fr));
	gap: 8px;
}

.book_page .book_way_actions_pair .book_way_button {
	gap: 6px;
	min-width: 0;
	padding: 11px 10px;
	font-size: 14px;
	white-space: nowrap;
}

.book_page .book_way_actions_pair .book_way_button_icon svg {
	width: 16px;
	height: 16px;
}

/* The site's pill link, as on the Contact page's socials and the Gallery's
   jump links: hairline outline, filling to the panel colour and turning rose on
   hover. Outlined rather than solid because these are alternatives to each
   other, not a primary action and a secondary one. */
.book_page .book_way_button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 11px 20px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: 100px;
	background-color: transparent;
	color: var(--theme-color-title);
	font-family: inherit;
	font-size: 15px;
	font-weight: 500;
	line-height: 1.4;
	text-decoration: none;
	cursor: pointer;
	transition: border-color .3s ease, background-color .3s ease, color .3s ease;
}

/* Fills to bg_color, not bg_color_2 - the card is already bg_color_2, and a
   hover that matches the surface it sits on is no hover at all. */
.book_page .book_way_button:hover,
.book_page .book_way_button:focus-visible {
	border-color: var(--theme-color-link);
	background-color: var(--theme-color-bg_color);
	color: var(--theme-color-link);
}

.book_page .book_way_button_icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--theme-color-link);
}

.book_page .book_way_button_icon svg {
	width: 17px;
	height: 17px;
}

/* The placeholder button. Dropped to the meta grey and not-allowed so it reads
   as a state rather than as a control someone has failed to click; :disabled
   already takes it out of the tab order, so the hover rule above is overridden
   here to stop it pretending to respond. */
.book_page .book_way_button_soon,
.book_page .book_way_button_soon:hover,
.book_page .book_way_button_soon:focus-visible {
	border-color: var(--theme-color-bd_color);
	background-color: transparent;
	color: var(--theme-color-meta);
	cursor: not-allowed;
}

.book_page .book_note {
	margin: 40px 0 0;
	color: var(--theme-color-meta);
	font-size: 14px;
}

/* ---------- The enquiry form on this page ----------

   The form itself is the shared component from inc/enquiry-form.php and carries
   its own styling through .contact_form_wrap; only its placement on this page
   is set here. Capped at a comfortable measure rather than run the full content
   width, where the two-column field grid stretches to a point that makes a
   short label look stranded at the left of its own row. */

.book_page .book_enquiry {
	max-width: 54em;
	margin: clamp(60px, 7vw, 100px) 0 20px;
	scroll-margin-top: 120px;
}

.book_page .book_enquiry_heading {
	margin: 0 0 30px;
	font-size: clamp(24px, 2.6vw, 34px);
	line-height: 1.2;
}

@media (max-width: 767px) {
	.book_page .book_panel {
		margin: 20px auto 40px;
		padding: 38px 22px;
	}
	.book_page .book_ways_head {
		margin-bottom: 32px;
	}
	.book_page .book_way {
		padding: 30px 22px 26px;
	}
	.book_page .book_way_actions {
		padding-top: 26px;
	}
	/* Full width each, so two pills on one line never squeeze to a few
	   characters plus an ellipsis on a narrow phone. */
	.book_page .book_way_actions .book_way_button {
		flex: 1 1 100%;
	}
}


/* Scroll reveal (js/reveal.js)
   ------------------------------------------------------------
   The hidden starting state is printed inline in the head by
   clean_child_reveal_head() - it has to land before first paint or elements
   flash in and then vanish to animate back. This file only carries the
   transition and the finished state.

   Movement is deliberately small: 22-28px and a fade. Large slides, scaling
   and rotation draw attention to the animation instead of the content, and on
   a clinic site that reads as gimmicky rather than considered. The easing is
   a decelerating curve, so everything arrives softly rather than stopping
   dead.
------------------------------------------------------------ */

.mda_reveal_on .about_hero > *,
.mda_reveal_on .about_hero_media,
.mda_reveal_on .about_fact,
.mda_reveal_on .about_split_body,
.mda_reveal_on .about_split_media,
.mda_reveal_on .about_team_head,
.mda_reveal_on .about_team_lead_body,
.mda_reveal_on .about_team_lead_media,
.mda_reveal_on .about_team_support_text,
.mda_reveal_on .about_team_member,
.mda_reveal_on .about_watermark,
.mda_reveal_on .about_intro_split_head,
.mda_reveal_on .about_intro_split_body,
.mda_reveal_on .about_gallery_item,
.mda_reveal_on .about_values_head,
.mda_reveal_on .about_value,
.mda_reveal_on .mda_cta_inner > *,
.mda_reveal_on .treatments_menu_head,
.mda_reveal_on .treatments_group,
.mda_reveal_on .gallery_instagram,
.mda_reveal_on .gallery_filters,
.mda_reveal_on .gallery_section_head,
.mda_reveal_on .gallery_item,
.mda_reveal_on .book_panel > *,
.mda_reveal_on .book_ways_head,
.mda_reveal_on .book_ways_subtitle,
.mda_reveal_on .book_way,
.mda_reveal_on .book_enquiry_heading,
.mda_reveal_on .contact_details,
.mda_reveal_on .contact_form_wrap,
.mda_reveal_on .contact_map,
.mda_reveal_on .faq_group,
.mda_reveal_on .testimonials_source_head,
.mda_reveal_on .testimonials_page .mda_review,
.mda_reveal_on .testimonials_empty,
.mda_reveal_on .mda_instagram_title,
.mda_reveal_on .mda_instagram_item,
.mda_reveal_on .footer_millicent .mda_footer_col {
	transition: opacity .75s cubic-bezier(.22, .61, .36, 1),
	            transform .75s cubic-bezier(.22, .61, .36, 1);
	will-change: opacity, transform;
}

/* Photographs settle a little more slowly than text - the eye reads a moving
   image for longer, so matching the text timing makes them feel abrupt. */
.mda_reveal_on .about_hero_media,
.mda_reveal_on .about_split_media,
.mda_reveal_on .about_team_lead_media,
.mda_reveal_on .about_team_member,
.mda_reveal_on .about_gallery_item,
.mda_reveal_on .gallery_item,
.mda_reveal_on .contact_map,
.mda_reveal_on .mda_instagram_item {
	transition-duration: 1s;
}

/* Once an element has arrived, will-change is dropped: leaving it on keeps a
   compositor layer alive for the life of the page for no benefit. The opacity
   and transform need no rule here - the head's hidden state is scoped to
   :not(.mda_is_revealed), so it simply stops applying. */
.mda_reveal_on .mda_is_revealed {
	will-change: auto;
}

/* A photograph eases down from very slightly oversized as it arrives, which
   reads as the image settling rather than sliding. Scoped the same way, so
   once revealed the tile's own hover scaling has the property to itself. */
.mda_reveal_on .about_hero_media img,
.mda_reveal_on .about_split_media img,
.mda_reveal_on .about_team_lead_media img,
.mda_reveal_on .about_team_member_media img,
.mda_reveal_on .about_gallery_item img,
.mda_reveal_on .gallery_item img,
.mda_reveal_on .mda_instagram_item img {
	transition: transform 1.4s cubic-bezier(.22, .61, .36, 1);
}

.mda_reveal_on .about_hero_media:not(.mda_is_revealed) img,
.mda_reveal_on .about_split_media:not(.mda_is_revealed) img,
.mda_reveal_on .about_team_lead_media:not(.mda_is_revealed) img,
.mda_reveal_on .about_team_member:not(.mda_is_revealed) .about_team_member_media img,
.mda_reveal_on .about_gallery_item:not(.mda_is_revealed) img,
.mda_reveal_on .gallery_item:not(.mda_is_revealed) img,
.mda_reveal_on .mda_instagram_item:not(.mda_is_revealed) img {
	transform: scale(1.05);
}

/* Belt and braces: the head script already declines to arm any of this when
   reduced motion is requested, but if the class is ever forced on, nothing
   should move. */
@media (prefers-reduced-motion: reduce) {
	.mda_reveal_on .about_hero > *,
	.mda_reveal_on .about_hero_media,
	.mda_reveal_on .about_fact,
	.mda_reveal_on .about_split_body,
	.mda_reveal_on .about_split_media,
	.mda_reveal_on .about_team_head,
	.mda_reveal_on .about_team_lead_body,
	.mda_reveal_on .about_team_lead_media,
	.mda_reveal_on .about_team_support_text,
	.mda_reveal_on .about_team_member,
	.mda_reveal_on .about_watermark,
	.mda_reveal_on .about_intro_split_head,
	.mda_reveal_on .about_intro_split_body,
	.mda_reveal_on .about_gallery_item,
	.mda_reveal_on .about_values_head,
	.mda_reveal_on .about_value,
	.mda_reveal_on .mda_cta_inner > *,
	.mda_reveal_on .treatments_menu_head,
	.mda_reveal_on .treatments_group,
	.mda_reveal_on .gallery_instagram,
	.mda_reveal_on .gallery_filters,
	.mda_reveal_on .gallery_section_head,
	.mda_reveal_on .gallery_item,
	.mda_reveal_on .book_panel > *,
	.mda_reveal_on .book_ways_head,
	.mda_reveal_on .book_ways_subtitle,
	.mda_reveal_on .book_way,
	.mda_reveal_on .book_enquiry_heading,
	.mda_reveal_on .contact_details,
	.mda_reveal_on .contact_form_wrap,
	.mda_reveal_on .contact_map,
	.mda_reveal_on .faq_group,
	.mda_reveal_on .testimonials_source_head,
	.mda_reveal_on .testimonials_page .mda_review,
	.mda_reveal_on .testimonials_empty,
		.mda_reveal_on .mda_instagram_title,
	.mda_reveal_on .mda_instagram_item,
	.mda_reveal_on .footer_millicent .mda_footer_col {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}
	.mda_reveal_on .about_hero_media img,
	.mda_reveal_on .about_split_media img,
	.mda_reveal_on .about_team_lead_media img,
	.mda_reveal_on .about_team_member_media img,
	.mda_reveal_on .about_gallery_item img,
	.mda_reveal_on .gallery_item img,
	.mda_reveal_on .mda_instagram_item img {
		transform: none !important;
		transition: none !important;
	}
}


/* Justified body copy, sitewide
   ------------------------------------------------------------
   Every run of flowing prose is justified with hyphenation switched on.
   Justifying without hyphens forces the browser to stretch word spacing to
   fill each line, which opens visible rivers of white space down a narrow
   column; letting it hyphenate keeps the spacing even and both edges clean.

   Headings, labels, price chips, buttons and navigation are deliberately not
   included - justification only makes sense on multi-line prose.

   Centred blocks (the About value cards, the closing calls to action, the
   Book Now panel) are also left alone: text-align can only hold one value, so
   justifying them would mean giving up the centring the design relies on.
------------------------------------------------------------ */

.about_page .about_hero_text p,
.about_page .about_split_body p,
.about_page .about_intro_split_body p,
.contact_page .contact_intro p,
.treatments_page .treatments_menu_note,
.treatments_page .treatments_group_note,
.gallery_page .gallery_section_text,
.faq_page .faq_item_answer p,
.legal_page .legal_intro p,
.legal_page .legal_section > p,
.legal_page .legal_subsection p,
.legal_page .legal_list li {
	text-align: justify;
	hyphens: auto;
	-webkit-hyphens: auto;
	/* Left to itself the browser will break almost anything - "pur-pose",
	   "set-ting", "deliv-ered" - which is uglier than the loose word spacing
	   it is trying to avoid. This only allows a break in words of 8 letters
	   or more, keeping at least 4 letters before the hyphen and 3 after, so
	   only genuinely long words like "consulta-tion" ever split. */
	hyphenate-limit-chars: 8 4 3;
	-webkit-hyphenate-limit-before: 4;
	-webkit-hyphenate-limit-after: 3;
	/* Never more than two hyphenated lines in a row. */
	hyphenate-limit-lines: 2;
	-webkit-hyphenate-limit-lines: 2;
}

@media (max-width: 767px) {
	/* Below this the measure is too short for justification to do anything but
	   open gaps between words, so every one of them goes back to ragged. */
	.about_page .about_hero_text p,
	.about_page .about_split_body p,
	.about_page .about_intro_split_body p,
	.contact_page .contact_intro p,
	.treatments_page .treatments_menu_note,
	.treatments_page .treatments_group_note,
	.gallery_page .gallery_section_text,
	.faq_page .faq_item_answer p,
	.legal_page .legal_intro p,
	.legal_page .legal_section > p,
	.legal_page .legal_subsection p,
	.legal_page .legal_list li {
		text-align: left;
		hyphens: manual;
		-webkit-hyphens: manual;
	}
}


/* Legal pages (template-privacy.php, template-cookies.php)
   ------------------------------------------------------------
   An editorial hero, then a contents column beside the document. Legal text is
   read in two ways - straight through, or hunting for one section - so the
   layout serves both: the measure stays at reading width, and the contents nav
   sticks alongside so the reader always knows where they are and can jump.

   Below 1023px the nav stops being a sidebar and becomes a card of links above
   the text, because a sticky rail on a phone is just something in the way.
------------------------------------------------------------ */

/* ---------- Hero ---------- */

/* Same reasoning as the home page: these pages hide the theme's centred title
   band and open with their own hero, so the space it would have occupied is
   just a gap under the menu. */
.legal_page .legal_hero {
	max-width: 46em;
	margin-bottom: 70px;
	padding-top: clamp(20px, 3vw, 40px);
}

body.page-template-template-privacy .page_content_wrap,
body.page-template-template-cookies .page_content_wrap {
	padding-top: 0;
}

.legal_page .legal_eyebrow {
	display: block;
	margin-bottom: 20px;
	color: var(--theme-color-link);
	font-size: 13px;
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.legal_page .legal_hero_title {
	margin: 0 0 0.5em;
	font-size: clamp(34px, 4.3vw, 58px);
	line-height: 1.14;
	letter-spacing: -0.01em;
}

.legal_page .legal_intro p {
	margin-bottom: 0.8em;
	color: var(--theme-color-title);
	font-size: 19px;
	line-height: 1.7;
}

.legal_page .legal_intro p:last-child {
	margin-bottom: 0;
}

/* The date as a quiet pill rather than a line of prose: it is the first thing
   a reader checks on a policy and the last thing they want to read a sentence
   about. */
.legal_page .legal_updated_top {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	margin: 32px 0 0;
	padding: 9px 18px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: 100px;
	color: var(--theme-color-meta);
	font-size: 14px;
	line-height: 1.4;
}

.legal_page .legal_updated_dot {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background-color: var(--theme-color-link);
	/* A slow pulse, so the "this is current" signal is felt rather than read. */
	animation: mda_pulse 2.6s ease-in-out infinite;
}

@keyframes mda_pulse {
	0%, 100% {
		opacity: 1;
		transform: scale(1);
	}
	50% {
		opacity: 0.45;
		transform: scale(0.82);
	}
}

/* ---------- Contents nav beside the document ---------- */

/* The document column is capped at reading measure rather than filling the
   page, so the pair is centred instead of being pinned left with a screen of
   empty paper down the right-hand side. */
.legal_page .legal_layout {
	display: grid;
	grid-template-columns: minmax(0, 240px) minmax(0, 42em);
	justify-content: center;
	gap: 70px;
	align-items: start;
}

/* Sticks below the pinned header rather than at the very top, or the first
   entry hides behind the menu bar. */
.legal_page .legal_toc {
	position: sticky;
	top: calc(var(--mda-header-h, 96px) + 30px);
	padding: 28px 24px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color_2);
}

.legal_page .legal_toc_title {
	margin: 0 0 16px;
	color: var(--theme-color-meta);
	font-size: 12px;
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.legal_page .legal_toc_list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.legal_page .legal_toc_item + .legal_toc_item {
	margin-top: 2px;
}

/* The left border is the position indicator: transparent at rest, coloured on
   the section you are reading. Padding stays put so nothing shifts when it
   lights up. */
.legal_page .legal_toc_link {
	display: block;
	padding: 6px 0 6px 14px;
	border-left: 2px solid transparent;
	color: var(--theme-color-text);
	font-size: 14px;
	line-height: 1.45;
	text-decoration: none;
	transition: color .25s ease, border-color .25s ease, transform .25s ease;
}

.legal_page .legal_toc_link:hover,
.legal_page .legal_toc_link:focus-visible {
	color: var(--theme-color-link);
	border-left-color: var(--theme-color-bd_color);
	transform: translateX(3px);
}

.legal_page .legal_toc_item_current .legal_toc_link {
	color: var(--theme-color-title);
	border-left-color: var(--theme-color-link);
	font-weight: 500;
}

/* ---------- The document ---------- */

/* ~70 characters a line. Long legal prose set the full width of the page is
   the single most common reason nobody reads it. The cap is on the grid
   column above; this is the fallback for browsers that ignore it. */
.legal_page .legal_body {
	max-width: 42em;
}

.legal_page .legal_section + .legal_section {
	margin-top: 55px;
	padding-top: 55px;
	border-top: 1px solid var(--theme-color-bd_color);
}

.legal_page .legal_section_title {
	margin: 0 0 0.7em;
	font-size: clamp(22px, 2.4vw, 28px);
	line-height: 1.25;
}

/* The number sits above the heading as a small marker, so a reader scanning
   for "section 9" has something to scan for. */
.legal_page .legal_section_number {
	display: block;
	margin-bottom: 10px;
	color: var(--theme-color-link);
	font-size: 13px;
	font-weight: 500;
	letter-spacing: 0.1em;
}

.legal_page .legal_lead {
	color: var(--theme-color-title);
	font-size: 17px;
}

.legal_page .legal_subsection {
	margin-top: 28px;
}

.legal_page .legal_subsection_title {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px 14px;
	margin: 0 0 0.6em;
	font-size: 18px;
	line-height: 1.35;
}

/* Cookie categories are cards, because the answer a reader wants ("is this one
   on?") is a property of the whole block, not of a sentence inside it. */
.legal_page .legal_subsection_carded {
	padding: 26px 28px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color);
	transition: transform .35s ease, border-color .35s ease, box-shadow .35s ease;
}

.legal_page .legal_subsection_carded:hover {
	transform: translateY(-4px);
	border-color: var(--theme-color-link);
	box-shadow: 0 16px 36px rgba(0, 0, 0, 0.06);
}

.legal_page .legal_subsection_carded p:last-child,
.legal_page .legal_subsection_carded .legal_list:last-child {
	margin-bottom: 0;
}

/* ---------- Status badges ---------- */

.legal_page .legal_badge {
	display: inline-flex;
	align-items: center;
	padding: 4px 12px;
	border-radius: 100px;
	font-size: 12px;
	font-weight: 500;
	line-height: 1.5;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* Set in the link colour rather than a green borrowed from nowhere: this is
   the only palette the site has, and "on" should read as the brand's yes. */
.legal_page .legal_badge_on {
	border: 1px solid var(--theme-color-link);
	color: var(--theme-color-link);
}

.legal_page .legal_badge_off {
	border: 1px solid var(--theme-color-bd_color);
	color: var(--theme-color-meta);
}

.legal_page .legal_badge_partial {
	border: 1px solid var(--theme-color-bd_color);
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-title);
}

/* ---------- Lists and links ---------- */

.legal_page .legal_list {
	margin: 0 0 1.5em;
	padding-left: 1.3em;
	list-style: disc;
}

.legal_page .legal_list li {
	margin-bottom: 0.5em;
	line-height: 1.7;
}

.legal_page .legal_list li:last-child {
	margin-bottom: 0;
}

.legal_page .legal_list strong {
	color: var(--theme-color-title);
}

/* Links inside legal prose need to be obviously clickable - these pages are
   where someone goes looking for the ICO or a browser help page. */
.legal_page .legal_body a {
	color: var(--theme-color-link);
	text-decoration: underline;
	text-underline-offset: 0.15em;
	transition: color .25s ease;
}

.legal_page .legal_body a:hover {
	color: var(--theme-color-hover);
}

.legal_page .legal_updated {
	margin: 55px 0 0;
	padding-top: 25px;
	border-top: 1px solid var(--theme-color-bd_color);
	color: var(--theme-color-meta);
	font-size: 14px;
}

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

@media (max-width: 1023px) {
	/* The rail becomes a card above the text. Sticky is dropped with it: on a
	   short screen a pinned nav eats the space the document needs. */
	.legal_page .legal_layout {
		grid-template-columns: minmax(0, 1fr);
		gap: 40px;
	}
	.legal_page .legal_toc {
		position: static;
	}
	.legal_page .legal_toc_list {
		display: flex;
		flex-wrap: wrap;
		gap: 4px 8px;
	}
	.legal_page .legal_toc_item + .legal_toc_item {
		margin-top: 0;
	}
	.legal_page .legal_toc_link {
		padding: 6px 12px;
		border-left: none;
		border-radius: 100px;
		background-color: var(--theme-color-bg_color);
	}
	.legal_page .legal_toc_link:hover,
	.legal_page .legal_toc_link:focus-visible {
		transform: none;
	}
	.legal_page .legal_toc_item_current .legal_toc_link {
		background-color: var(--theme-color-link);
		color: #ffffff;
	}
	.legal_page .legal_body {
		max-width: none;
	}
}

@media (max-width: 767px) {
	.legal_page .legal_hero {
		margin-bottom: 45px;
	}
	.legal_page .legal_intro p {
		font-size: 17px;
	}
	.legal_page .legal_section + .legal_section {
		margin-top: 40px;
		padding-top: 40px;
	}
	.legal_page .legal_subsection_carded {
		padding: 22px 20px;
	}
	.legal_page .legal_updated {
		margin-top: 40px;
	}
}


/* Home page (front-page.php)
   ------------------------------------------------------------
   The theme demo's beauty-clinic home page, rebuilt in CSS grid: an image
   cluster with the oversized headline beneath it, a row of promises, three
   service cards, a price extract, the story split, a portfolio strip, reviews,
   and a closing call to action over a photograph.

   Every section is a grid that collapses to one column on a phone, and every
   interactive thing on the page has a hover state - see the "Hover states"
   block at the end of this file for the ones shared with the rest of the site.
------------------------------------------------------------ */

/* The theme reserves a deep band under the header for the centred page title.
   This page opens with its own hero instead, so that reserved space is just a
   screen of nothing between the menu and the first line of copy. */
/* The home page opens with a full-height photograph that the header stripe
   floats over, so the header comes out of the flow and the content starts at
   the very top of the window. */
body.home .top_panel {
	position: absolute;
	z-index: 20;
	top: 0;
	right: 0;
	left: 0;
	background-color: transparent;
}

/* The banner has to start at the very top of the window, so every wrapper
   between the body and it gives up its top padding on this page only. */
body.home .page_content_wrap,
body.home .page_content_wrap .content_wrap,
body.home .page_content_wrap .content {
	padding-top: 0;
	margin-top: 0;
}

body.home .page_content_wrap {
	/* The closing call to action is a full-bleed band and the Instagram row
	   below it is another, so the theme's usual bottom padding just opens a
	   gap between two things that should meet. */
	padding-bottom: 0;
}

/* No padding above the banner - it starts where the window starts. Every
   section after it gets the usual rhythm from the rule below. */
.home_page {
	padding-top: 0;
}

.home_page > section:not(.home_banner) + section {
	margin-top: clamp(70px, 9vw, 130px);
}

.home_page .home_banner + section {
	margin-top: clamp(60px, 7vw, 110px);
}

.home_page .home_eyebrow {
	display: block;
	margin-bottom: 20px;
	color: var(--theme-color-link);
	font-size: 13px;
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.home_page .home_section_head {
	margin-bottom: 45px;
}

/* Heading on the left, "see everything" link on the right, baseline-aligned. */
.home_page .home_section_head_split {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 20px 40px;
}

.home_page .home_section_title {
	margin: 0;
	font-size: clamp(30px, 3.6vw, 46px);
	line-height: 1.15;
}

/* Text link with a rule that draws itself in from the left on hover. */
.home_page .home_link {
	position: relative;
	display: inline-block;
	padding-bottom: 3px;
	color: var(--theme-color-title);
	font-size: 15px;
	font-weight: 500;
	text-decoration: none;
	white-space: nowrap;
}

.home_page .home_link::after {
	content: '';
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	height: 1px;
	background-color: var(--theme-color-link);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform .35s ease;
}

.home_page .home_link:hover,
.home_page .home_link:focus-visible {
	color: var(--theme-color-link);
}

.home_page .home_link:hover::after,
.home_page .home_link:focus-visible::after {
	transform: scaleX(1);
}

/* ---------- Full-bleed banner ---------- */

/* True edge to edge. The theme's own .alignfull leaves an 8px gutter each side,
   which is right for a map or a quote block sitting inside a page, and wrong
   for the photograph the page opens on. */
.home_page .home_banner.alignfull {
	width: 100vw;
	max-width: 100vw;
	margin-right: calc(-50vw + 50%);
	margin-left: calc(-50vw + 50%);
}

.home_page .home_banner {
	position: relative;
	display: flex;
	overflow: hidden;
	/* Tall enough to be the whole screen, capped so it does not become absurd
	   on a tall monitor. */
	min-height: min(100vh, 940px);
	background-color: var(--theme-color-title);
}

/* The photographs sit side by side in one scrolling strip rather than stacked
   and crossfading, so the visitor can move through them themselves: a swipe on
   a phone, two fingers on a trackpad, shift-wheel on a mouse, or the arrow
   keys once the strip has focus. This is the browser's own scrolling, so the
   momentum and the snapping are native and cost nothing, and it all works with
   the script in js/home-banner.js blocked or still loading. */
.home_page .home_banner_track {
	position: absolute;
	inset: 0;
	display: flex;
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	/* A swipe that runs off the end of the strip must not be handed to the
	   page behind it, which on a phone browser is the pull-to-refresh or the
	   back gesture. */
	overscroll-behavior-x: contain;
	/* The strip is the photograph, so the scrollbar is not furniture the page
	   should show. The controls and the snapping are the affordance instead. */
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.home_page .home_banner_track::-webkit-scrollbar {
	display: none;
}

/* The strip is focusable - it has to be, or a keyboard cannot reach the
   photographs - so it needs a focus ring, and one that reads over a
   photograph rather than a hairline that vanishes into it. */
.home_page .home_banner_track:focus-visible {
	outline: 2px solid #ffffff;
	outline-offset: -6px;
}

/* Mandatory snapping fights scrollLeft being set by hand, so the drag handler
   turns it off for the length of the gesture. */
.home_page .home_banner_track.is_dragging {
	scroll-snap-type: none;
	cursor: grabbing;
}

.home_page .home_banner_slide {
	position: relative;
	flex: 0 0 100%;
	width: 100%;
	height: 100%;
	scroll-snap-align: center;
	scroll-snap-stop: always;
}

/* A real <img>, not a CSS background: a background image is invisible to
   search engines and screen readers, and cannot be given a priority hint.
   object-position is set per image in the markup, because the frame each one
   is cropped into is not the shape any of them were taken in. */
.home_page .home_banner_media {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Otherwise a click-drag across the photograph starts the browser's own
	   image drag, ghost and all, and cancels the gesture. */
	-webkit-user-drag: none;
	user-select: none;
}

/* Two washes, each doing one job: the first grounds the row along the bottom,
   the second darkens the left so the headline holds against whatever the
   photograph is doing there. Angled rather than flat, so the right-hand side -
   the part worth looking at - stays clear. */
.home_page .home_banner::after {
	content: '';
	position: absolute;
	inset: 0;
	/* Both washes sit over the strip, so neither may take the swipe. */
	pointer-events: none;
	background:
		linear-gradient(180deg, rgba(0, 0, 0, 0) 55%, rgba(0, 0, 0, 0.45) 100%),
		linear-gradient(100deg, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0.34) 42%, rgba(0, 0, 0, 0) 72%);
}

.home_page .home_banner_inner {
	position: relative;
	z-index: 2;
	/* The headline covers the whole band, so it would otherwise swallow every
	   swipe and drag meant for the photographs underneath it. */
	pointer-events: none;
	display: flex;
	flex-direction: column;
	/* The headline is the only thing in here now. Centred, not space-between:
	   one child against space-between sits at the top of a full-height band
	   with half a screen of nothing under it. */
	justify-content: center;
	width: 100%;
	/* Equal top and bottom, so 'center' lands on the middle of the picture
	   rather than below it. The value is the clearance the floating header
	   stripe needs - it is out of the flow, so nothing else holds the copy off
	   the top of the band on a short viewport. */
	padding: clamp(150px, 21vh, 250px) clamp(24px, 4vw, 75px);
}

.home_page .home_banner_title {
	max-width: 15em;
	margin: 0;
	color: #ffffff;
	font-size: clamp(34px, 5.2vw, 76px);
	font-weight: 400;
	line-height: 1.14;
}

/* With no photograph bundled the washes have nothing to sit on, so the band
   keeps the theme's dark tone and the same white type. */
.home_page .home_banner_no_media::after {
	background: none;
}

/* ---------- Banner controls ---------- */

/* Built by js/home-banner.js, never by the template: a dot that cannot move
   anything is worse than no dot, so nothing is shown to a visitor whose
   browser did not run the script. The strip still scrolls for them.

   Hidden outright on a laptop or a desktop: there the photograph is the whole
   screen and controls painted over it are furniture, and a mouse or trackpad
   can already move the strip - drag it, scroll it sideways, or tab to it and
   use the arrow keys. The dots come back below, on the screens where a swipe
   needs something to say it is a swipe. */
.home_page .home_banner_nav {
	display: none;
	position: absolute;
	z-index: 3;
	right: clamp(24px, 4vw, 75px);
	bottom: clamp(28px, 5vh, 56px);
	left: clamp(24px, 4vw, 75px);
	align-items: center;
	justify-content: center;
	gap: 18px;
	/* The row runs the width of the band, so only the dots themselves may take
	   a pointer - the gaps between them belong to the photograph, and to the
	   swipe the visitor started there. */
	pointer-events: none;
}

.home_page .home_banner_dot {
	pointer-events: auto;
}

.home_page .home_banner_dots {
	display: flex;
	align-items: center;
	gap: 10px;
}

/* 8px of dot inside a 24px target: the dot is the mark, the padding is what a
   thumb actually has to hit. */
.home_page .home_banner_dot {
	position: relative;
	flex: 0 0 auto;
	width: 24px;
	height: 24px;
	min-width: 0;
	padding: 0;
	border: none;
	border-radius: 999px;
	background: none;
	box-shadow: none;
	cursor: pointer;
}

/* The dots sit on a photograph, so the ring is the only thing that can be
   relied on to show where the keyboard is. */
.home_page .home_banner_dot:focus-visible {
	outline: 2px solid #ffffff;
	outline-offset: 2px;
}

.home_page .home_banner_dot::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 8px;
	height: 8px;
	margin: -4px 0 0 -4px;
	border-radius: 999px;
	background-color: rgba(255, 255, 255, 0.45);
	transition: width .3s ease, margin-left .3s ease, background-color .3s ease;
}

.home_page .home_banner_dot:hover::after,
.home_page .home_banner_dot:focus-visible::after {
	background-color: rgba(255, 255, 255, 0.8);
}

/* The one you are on stretches into a bar rather than only changing colour,
   which stays legible over a pale part of a photograph. */
.home_page .home_banner_dot.is_current::after {
	width: 26px;
	margin-left: -13px;
	background-color: #ffffff;
}

/* Reduced motion: the strip never advances on its own - the script checks the
   same query and simply never starts its timer - and the moves the visitor
   asks for themselves jump rather than glide. What is left is a strip of
   photographs that only ever moves when it is told to. */
@media (prefers-reduced-motion: reduce) {
	.home_page .home_banner_track {
		scroll-behavior: auto;
	}
	.home_page .home_banner_dot::after {
		transition: none;
	}
}

/* The banner is the first thing on screen, so it arrives on load rather than
   on scroll: it can never be scrolled into view, and scroll-reveal would leave
   it blank until something moved. */
.home_page .home_banner_title {
	animation: mda_banner_in .9s cubic-bezier(.2, .6, .2, 1) both;
}

@keyframes mda_banner_in {
	from {
		opacity: 0;
		transform: translateY(26px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

/* ---------- The four promises ---------- */

.home_page .home_promises {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 24px;
}

.home_page .home_promise {
	padding: 36px 28px 32px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--theme-color-bg_color);
	transition: transform .35s ease, border-color .35s ease, box-shadow .35s ease;
}

/* Hover comes from the shared card rule at the foot of this file. */

.home_page .home_promise_icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	margin-bottom: 22px;
	border-radius: 50%;
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-link);
	transition: background-color .35s ease, color .35s ease, transform .35s ease;
}

/* Monochrome on hover, at the client's request: the four promises are the
   first thing under the banner and four rose discs lighting up across the row
   pulled the eye away from the words they belong to. Black is the same gesture
   without the colour, and matches the buttons. */
.home_page .home_promise:hover .home_promise_icon {
	transform: rotate(-8deg) scale(1.06);
	background-color: var(--mda-button);
	color: #ffffff;
}

.home_page .home_promise_title {
	margin: 0 0 0.5em;
	font-size: 19px;
	line-height: 1.3;
}

.home_page .home_promise_text {
	margin: 0;
	font-size: 15px;
	line-height: 1.65;
}

/* ---------- Signature treatments ---------- */

.home_page .home_services_grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 40px 34px;
}

.home_page .home_service_media {
	display: block;
	overflow: hidden;
	margin-bottom: 26px;
	border-radius: var(--theme-var-global-border-radius, 10px);
}

/* object-position sits above centre because these are faces. The source files
   are tight portrait crops - the top of the head is already at the edge of the
   photograph - so a centred cover crop takes the forehead off before it takes
   anything unimportant. Biasing to 30% spends the loss on the shoulder at the
   bottom instead, where there is nothing to see. */
.home_page .home_service_media img {
	display: block;
	width: 100%;
	height: clamp(260px, 26vw, 360px);
	object-fit: cover;
	object-position: center 30%;
	transition: transform 1.2s cubic-bezier(.2, .6, .2, 1);
}

.home_page .home_service_media:hover img,
.home_page .home_service_media:focus-visible img {
	transform: scale(1.06);
}

.home_page .home_service_title {
	margin: 0 0 0.5em;
	font-size: 23px;
	line-height: 1.25;
}

.home_page .home_service_text {
	margin: 0 0 18px;
	line-height: 1.7;
}

/* ---------- Portfolio strip ---------- */

/* Five photographs, the first one twice the height of the rest - the demo's
   asymmetric grid, which stops the strip reading as a contact sheet. */
.home_page .home_portfolio_grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	grid-auto-rows: clamp(130px, 14vw, 200px);
	gap: 18px;
}

.home_page .home_portfolio_item {
	display: block;
	overflow: hidden;
	border-radius: var(--theme-var-global-border-radius, 10px);
}

.home_page .home_portfolio_item:first-child {
	grid-row: span 2;
	grid-column: span 2;
}

.home_page .home_portfolio_item img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 1.2s cubic-bezier(.2, .6, .2, 1), opacity .4s ease;
}

.home_page .home_portfolio_item:hover img,
.home_page .home_portfolio_item:focus-visible img {
	transform: scale(1.07);
	opacity: 0.88;
}

/* ---------- Reviews: a self-scrolling wall of real Google reviews ---------- */

/* The summary chip, linking out so anyone can check the reviews are real. */
.mda_reviews_summary {
	display: inline-flex;
	align-items: center;
	gap: 14px;
	padding: 12px 20px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: 100px;
	background-color: #ffffff;
	text-decoration: none;
	transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease;
}

.mda_reviews_summary:hover,
.mda_reviews_summary:focus-visible {
	transform: translateY(-2px);
	border-color: var(--theme-color-hover);
	box-shadow: 0 10px 24px rgba(0, 0, 0, 0.07);
}

.mda_reviews_score {
	color: var(--theme-color-title);
	font-size: 26px;
	line-height: 1;
}

.mda_reviews_summary_body {
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.mda_reviews_count {
	color: var(--theme-color-meta);
	font-size: 13px;
	line-height: 1.3;
}

/* Sits where the stars sit in the Google chip. Facebook publishes a percentage
   who recommend, not a rating out of five, so the chip says what the number
   means instead of drawing five stars beside a figure that is not one. Line
   height matches the 15px star row it replaces, so the two chips sit level when
   they appear one under the other on the Testimonials page. */
.mda_reviews_recommend {
	color: var(--theme-color-title);
	font-size: 13px;
	letter-spacing: 0.04em;
	line-height: 15px;
	text-transform: uppercase;
}

/* Google's own star gold. Everything else on this page is the clinic's palette,
   but a review star that is not gold reads as a decoration rather than a
   rating. */
.mda_stars {
	display: inline-flex;
	gap: 2px;
	line-height: 0;
}

.mda_star {
	fill: #FBBC04;
}

.mda_star_empty {
	fill: var(--theme-color-bd_color);
}

/* The rail breaks out of the page gutters so cards run off both edges - it
   should read as a continuing wall, not a widget in a box. */
.home_page .mda_reviews {
	width: 100vw;
	max-width: 100vw;
	margin-right: calc(-50vw + 50%);
	margin-left: calc(-50vw + 50%);
	overflow: hidden;
	/* Fades the cards out at both ends instead of cutting them dead. */
	-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);
}

.mda_reviews_track {
	display: flex;
	gap: 24px;
	width: max-content;
	padding: 10px clamp(12px, 2vw, 24px);
	/* Duration scales with the number of cards, so adding reviews keeps the
	   same reading speed rather than making the wall race. */
	animation: mda_reviews_scroll 90s linear infinite;
}

/* Pause when a visitor shows interest - hovering, or tabbing into a card's
   link. Motion that will not stop while you are trying to read is the most
   common complaint about a marquee. */
.mda_reviews:hover .mda_reviews_track,
.mda_reviews:focus-within .mda_reviews_track {
	animation-play-state: paused;
}

/* Exactly half the track is the duplicate, so -50% lands on the copy of the
   first card and the loop is seamless. */
@keyframes mda_reviews_scroll {
	from {
		transform: translateX(0);
	}
	to {
		transform: translateX(-50%);
	}
}

.mda_review {
	display: flex;
	flex: 0 0 auto;
	flex-direction: column;
	width: clamp(280px, 27vw, 380px);
	margin: 0;
	padding: 30px 30px 26px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: #ffffff;
	transition: border-color .3s ease, box-shadow .3s ease;
}

.mda_review:hover {
	border-color: var(--theme-color-hover);
	box-shadow: 0 16px 36px rgba(0, 0, 0, 0.07);
}

.mda_review_head {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-bottom: 14px;
}

/* The reviewer's initial. Google shows a photograph, which is theirs and not
   ours to copy onto another website. */
.mda_review_avatar {
	display: inline-flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 50%;
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-hover);
	font-size: 17px;
	line-height: 1;
}

.mda_review_who {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.mda_review_author {
	color: var(--theme-color-title);
	font-size: 16px;
	font-weight: 500;
	line-height: 1.3;
}

.mda_review_meta,
.mda_review_date {
	color: var(--theme-color-meta);
	font-size: 12.5px;
	line-height: 1.4;
}

.mda_review_rating {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 14px;
}

/* A <blockquote>, because that is what a quoted review is - but the theme
   styles blockquotes as a grey panel with a quote mark and 40px of padding,
   which turned each card into a box inside a box. Reset to plain text. */
/* The panel styling is switched off in the markup with the theme's own
   is-style-plain class; this is just the type. */
.home_page .mda_review blockquote.mda_review_text {
	margin: 0;
	padding: 0;
	border: none;
	background: none;
	color: var(--theme-color-text);
	font-size: 15px;
	font-style: normal;
	line-height: 1.7;
	/* Left-aligned deliberately: the site justifies body copy, which opens
	   rivers in a column this narrow. */
	text-align: left;
}

.home_page .mda_review blockquote.mda_review_text::before,
.home_page .mda_review blockquote.mda_review_text::after {
	content: none;
}

.mda_review_text p {
	margin: 0 0 0.8em;
}

.mda_review_text p:last-child {
	margin-bottom: 0;
}

.mda_reviews_note {
	margin: 28px 0 0;
	color: var(--theme-color-meta);
	font-size: 13px;
	text-align: center;
}

.mda_reviews_note a {
	color: var(--theme-color-hover);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

/* Reduced motion: the wall stops moving and becomes a row the visitor scrolls
   themselves, which is the same content under their own control. */
@media (prefers-reduced-motion: reduce) {
	.home_page .mda_reviews {
		overflow-x: auto;
	}
	.mda_reviews_track {
		animation: none;
	}
}

/* Phones: the same escape hatch, and for a related reason.

   The client reported that the Google reviews could not be read on a phone at
   all, only on a laptop. The marquee is why. Three things that are individually
   fine combine badly on a small screen: the rail is 100vw and breaks out of the
   gutters with negative margins, it carries a mask-image, and its track runs an
   infinite translateX. A mask on a box whose child is running a composited
   transform is exactly the combination that mobile WebKit is known to render as
   an empty layer - and when it does not, an 18-card track crawling past a 360px
   window shows a third of one review at a time, which is unreadable even when
   it is visible.

   So below the tablet breakpoint the animation is dropped and the rail becomes
   a scroll-snapping row the thumb controls, with no mask. Same markup, same
   cards, same content - the phone gets the version it can actually use, and
   scroll-snap is the browser's own, so this costs no JavaScript.

   The Testimonials page is the full answer to that report: every review, in a
   static single column, nothing moving and nothing clipped. This is the fix for
   the home page's strip. */
@media (max-width: 767px) {
	.home_page .mda_reviews {
		-webkit-mask-image: none;
		        mask-image: none;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		/* The rail is its own scroller now, so it needs the page gutter back
		   as padding - without it the first card starts hard against the
		   screen edge. */
		scroll-padding-left: 15px;
	}
	/* The scrollbar would sit under the cards as a grey bar on cream. */
	.home_page .mda_reviews::-webkit-scrollbar {
		display: none;
	}
	.home_page .mda_reviews {
		scrollbar-width: none;
	}
	.home_page .mda_reviews_track {
		animation: none;
		padding: 10px 15px;
	}
	.home_page .mda_review {
		/* Near enough the full width, with the next card just showing - which
		   is what tells a thumb there is more to the right. */
		width: 86vw;
		max-width: 340px;
		scroll-snap-align: start;
	}
	/* Half the track is an aria-hidden duplicate that exists only so the
	   animation can loop seamlessly. With no animation it is nine more cards
	   to swipe past for nothing. */
	.home_page .mda_reviews_track .mda_review[aria-hidden="true"] {
		display: none;
	}
}


/* Testimonials page (template-testimonials.php)
   ------------------------------------------------------------
   The home page's reviews are a marquee. This is the opposite: every review in
   full, static, in an order that can actually be followed.

   WHY TWO COLUMNS AND NOT THREE, AND WHY A GRID AND NOT CSS COLUMNS

   This was built with `column-count: 3` first, which is the obvious answer -
   the reviews are wildly different lengths and multicol packs ragged content
   without leaving holes. It reads badly for two reasons that only show up with
   real copy in it:

   1. Multicol flows top-to-bottom, then across. Review 1 is top-left and
      review 2 is *below* it, so the eye, which goes left to right, reads 1
      then 4 then 7. With nine cards of different heights there is no way to
      tell where you are. A grid flows across then down, which is the order
      people actually read in.
   2. Three columns on a 1290px page is a 400px card, and after padding that
      is about 44 characters a line. These reviews are four to eight sentences
      of running prose, and 44 characters turns every one of them into a narrow
      ragged strip. Two columns give roughly 70 characters - inside the 45-75
      band that prose is comfortable at.

   The cost of a grid is that a short card leaves space under it rather than the
   next card sliding up. align-items:start keeps each card its own height, so
   what is left is a gap between self-contained panels, which reads as spacing
   rather than as a hole. That is the right trade: the layout is slightly less
   tightly packed and the page is readable, which is the entire point of it.

   The card itself is the same .mda_review component as the home page, so the
   two cannot drift apart on how a review looks - but it is laid out for this
   context: one attribution row instead of two stacked ones (see
   clean_child_testimonial_card()), more padding, and larger, looser type,
   because here the review is the content and there it is a passing glimpse.
------------------------------------------------------------ */

/* ---------- Faces Consent band ---------- */

/* The clinic's standing on the platform it books through, above the two review
   lists. One dark band rather than a card, because everything under it is a
   pale card and a third pale card would have disappeared into the row.

   Laid out as a row that wraps rather than a grid: the logo and the two figures
   are three items of very different widths, and a grid would either strand the
   logo in a column of its own on a tablet or leave the figures stretched apart
   on a wide screen. */
.testimonials_page .testimonials_faces {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: clamp(22px, 3.4vw, 48px);
	margin-bottom: 70px;
	padding: clamp(26px, 3.2vw, 40px) clamp(26px, 3.6vw, 48px);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: var(--mda-footer-bg);
	color: #ffffff;
	text-decoration: none;
	transition: transform .35s ease, box-shadow .35s ease;
}

@media (hover: hover) {
	.testimonials_page a.testimonials_faces:hover,
	.testimonials_page a.testimonials_faces:focus-visible {
		transform: translateY(-4px);
		box-shadow: 0 18px 40px rgba(0, 0, 0, 0.18);
	}
}

/* The wordmark is a flat blue on transparent and sits on near-black here, which
   is its own brand's colour on its own ground - so it is left alone rather than
   knocked out to white. It carries a white chip instead, which is how the mark
   appears on the platform itself and keeps it legible without altering it. */
.testimonials_page .testimonials_faces_logo {
	flex: 0 0 auto;
	width: clamp(150px, 15vw, 210px);
	height: auto;
	padding: 14px 18px;
	border-radius: 8px;
	background-color: #ffffff;
}

.testimonials_page .testimonials_faces_logo_text {
	font-size: 26px;
	font-weight: 700;
	color: #2F32F5;
	letter-spacing: -0.5px;
}

.testimonials_page .testimonials_faces_stats {
	display: flex;
	flex: 1 1 320px;
	flex-wrap: wrap;
	gap: clamp(20px, 3vw, 44px);
}

.testimonials_page .testimonials_faces_stat {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-width: 0;
}

.testimonials_page .testimonials_faces_figure {
	display: flex;
	align-items: center;
	gap: 10px;
	font-family: var(--theme-font-h1_font-family, inherit);
	font-size: clamp(26px, 3vw, 34px);
	line-height: 1.1;
	color: #ffffff;
}

/* The stars keep the Google gold they carry everywhere else on the site
   (.mda_star). It is the one colour a visitor reads as a rating rather than as
   decoration, it is the same mark as on the cards below, and gold on near-black
   is the strongest that pairing gets. */
.testimonials_page .testimonials_faces_figure .mda_stars {
	display: inline-flex;
	align-items: center;
	gap: 2px;
}

.testimonials_page .testimonials_faces_label {
	font-size: 14px;
	line-height: 1.5;
	color: var(--mda-footer-text);
}

@media (max-width: 575px) {
	.testimonials_page .testimonials_faces_stats {
		flex-direction: column;
	}
}

@media (prefers-reduced-motion: reduce) {
	.testimonials_page a.testimonials_faces:hover {
		transform: none;
	}
}

.testimonials_page .testimonials_source {
	margin-bottom: 90px;
}

.testimonials_page .testimonials_source_head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 20px 40px;
	margin-bottom: 40px;
}

.testimonials_page .testimonials_source_text {
	margin: 8px 0 0;
	color: var(--theme-color-meta);
	font-size: 14px;
	text-align: left;
}

/* align-items:start is the whole rule. Without it every card in a row stretches
   to the tallest one in that row, so a two-line review sits in a panel sized
   for an eight-line one and the page fills with empty boxes. With it each card
   is exactly as tall as its own words. */
.testimonials_page .testimonials_grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 28px;
	align-items: start;
}

/* The base .mda_review is built for the marquee: a fixed-width flex item that
   does not shrink, sized to 380px at most. Here it fills its grid cell. */
.testimonials_page .mda_review {
	width: auto;
	max-width: none;
	margin: 0;
	padding: 34px 36px 32px;
}

/* ---------- The card's attribution row ---------- */

/* Who on the left, when and how they rated on the right, on one line with a
   hairline under it. The home page stacks these as two rows; at this width
   they fit on one, which puts the review itself roughly 60px higher up the
   card and makes the quote the first thing the eye lands on.

   flex-wrap, because "Local Guide - 8 reviews - 12 photos" against a date is
   more than a narrow card can hold on one line. When it wraps, the rating
   drops under the name rather than squeezing it. */
.testimonials_page .mda_review_top {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 12px 20px;
	margin-bottom: 22px;
	padding-bottom: 18px;
	border-bottom: 1px solid var(--theme-color-bd_color);
}

/* Both halves of the row lose the margins they carry on the home page - the
   row itself owns the spacing here. */
.testimonials_page .mda_review_head,
.testimonials_page .mda_review_rating {
	margin-bottom: 0;
}

/* Stars and date stack, right-aligned, so the row reads name-left /
   rating-right rather than as four things in a line. */
.testimonials_page .mda_review_rating {
	flex-direction: column;
	align-items: flex-end;
	gap: 5px;
}

/* ---------- The review itself ---------- */

/* Bigger and looser than the home page's 15/1.7. That card is a glimpse going
   past in a marquee; this one is the thing the visitor opened the page for, so
   it is set at a reading size. 16.5px over a ~70 character measure is the same
   setting the legal pages use for long-form copy. */
.testimonials_page .mda_review blockquote.mda_review_text {
	margin: 0;
	padding: 0;
	border: none;
	background: none;
	color: var(--theme-color-text);
	font-size: 16.5px;
	font-style: normal;
	line-height: 1.75;
	/* Left-aligned, not justified like the rest of the site's body copy:
	   these are short paragraphs with emoji and no hyphenation, and justifying
	   them opens rivers. */
	text-align: left;
}

.testimonials_page .mda_review blockquote.mda_review_text::before,
.testimonials_page .mda_review blockquote.mda_review_text::after {
	content: none;
}

/* Facebook replaced star ratings with recommend / don't-recommend in 2018, so
   a Facebook card has no stars to show. This chip goes in their place rather
   than inventing five of them. */
.testimonials_page .mda_review_recommends {
	display: inline-flex;
	align-items: center;
	padding: 4px 11px;
	border-radius: 100px;
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-title);
	font-size: 12px;
	letter-spacing: 0.03em;
	line-height: 1.4;
	text-transform: uppercase;
}

/* ---------- Facebook, with nothing to show yet ---------- */

/* Stands in for the card grid until real recommendations are supplied. Same
   panel shape as the Gallery's Instagram block, one tone quieter: this is a
   "here is where they are" note, not the page's call to action. */
.testimonials_page .testimonials_empty {
	display: flex;
	align-items: center;
	gap: clamp(18px, 2.5vw, 30px);
	padding: clamp(24px, 3vw, 36px) clamp(24px, 3.4vw, 42px);
	border: 1px solid var(--theme-color-bd_color);
	border-radius: var(--theme-var-global-border-radius, 10px);
	background-color: #ffffff;
}

/* Rose, matching the Gallery's Instagram panel - the two are the same idiom
   (an iconed panel that hands the visitor off to a social platform) and were
   both built charcoal in the same sitting, when the site's accent was briefly
   monochrome. They follow the brand together now. */
.testimonials_page .testimonials_empty_icon {
	display: inline-flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border-radius: 50%;
	background-color: var(--theme-color-bg_color_2);
	color: var(--theme-color-hover);
}

.testimonials_page .testimonials_empty_icon svg {
	width: 24px;
	height: 24px;
}

.testimonials_page .testimonials_empty_body {
	flex: 1 1 auto;
	min-width: 0;
}

.testimonials_page .testimonials_empty_title {
	margin: 0 0 6px;
	font-size: clamp(19px, 1.6vw, 23px);
	line-height: 1.3;
}

.testimonials_page .testimonials_empty_text {
	max-width: 46em;
	margin: 0;
	color: var(--theme-color-text);
	font-size: 15px;
	line-height: 1.6;
	text-align: left;
}

/* Filled rose with white text, inverting on hover - the same button the CTA
   bands use at the foot of every other page, so a visitor meets one button
   shape on this site rather than two. --theme-color-hover, not the lighter
   brand rose, for the contrast reason written up against the Gallery panel. */
.testimonials_page .testimonials_empty_button {
	display: inline-flex;
	flex: none;
	align-items: center;
	padding: 14px 26px;
	border: 1px solid var(--mda-button);
	border-radius: 100px;
	background-color: var(--mda-button);
	color: #ffffff;
	font-size: 15px;
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color .3s ease, color .3s ease, transform .3s ease;
}

.testimonials_page .testimonials_empty_button:hover,
.testimonials_page .testimonials_empty_button:focus-visible {
	transform: translateY(-2px);
	background-color: transparent;
	color: var(--mda-button);
}

.testimonials_page .mda_reviews_note {
	text-align: left;
}

@media (prefers-reduced-motion: reduce) {
	.testimonials_page .testimonials_empty_button:hover,
	.testimonials_page .testimonials_empty_button:focus-visible {
		transform: none;
	}
}

@media (max-width: 1023px) {
	/* One column from here down, and capped.

	   Capped, because a single full-width card on a 1000px tablet is a 900px
	   line of text - about 115 characters, which is roughly twice a comfortable
	   measure and the point at which the eye loses the start of the next line.
	   720px holds it near 70 characters, the same as the two-column desktop
	   layout, so the reading experience does not change at the breakpoint -
	   only the number of cards across. */
	.testimonials_page .testimonials_grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 22px;
		max-width: 720px;
		margin-right: auto;
		margin-left: auto;
	}
	.testimonials_page .testimonials_source {
		margin-bottom: 65px;
	}
	.testimonials_page .testimonials_empty {
		flex-wrap: wrap;
	}
	.testimonials_page .testimonials_empty_button {
		margin-left: auto;
	}
}

@media (max-width: 767px) {
	/* Full width again - the cap is doing nothing at this size, and the column
	   is already narrower than the measure it was protecting.

	   This is the whole point of the page on a phone: nothing moving, nothing
	   clipped, nothing sideways. Just the reviews, one under another, at the
	   size they are meant to be read at. */
	.testimonials_page .testimonials_grid {
		gap: 18px;
		max-width: none;
	}
	.testimonials_page .mda_review {
		padding: 26px 24px 24px;
	}
	/* Name above, rating below, both left-aligned: at this width the two
	   halves wrap anyway, and a right-aligned rating under a left-aligned name
	   reads as a mistake rather than as a column. */
	.testimonials_page .mda_review_top {
		margin-bottom: 18px;
		padding-bottom: 15px;
	}
	.testimonials_page .mda_review_rating {
		flex-direction: row;
		align-items: center;
		gap: 10px;
	}
	.testimonials_page .mda_review blockquote.mda_review_text {
		font-size: 16px;
		line-height: 1.7;
	}
	.testimonials_page .testimonials_source_head {
		margin-bottom: 28px;
	}
	.testimonials_page .testimonials_empty {
		flex-direction: column;
		align-items: stretch;
		gap: 16px;
	}
	.testimonials_page .testimonials_empty_icon {
		display: none;
	}
	.testimonials_page .testimonials_empty_button {
		justify-content: center;
		margin-left: 0;
	}
}

/* ---------- Closing call to action ---------- */

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

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

@media (max-width: 767px) {
	.home_page .home_banner {
		min-height: min(100vh, 720px);
	}
	/* Dots, and only here. A phone swipes the strip, so the dots are not the
	   control so much as the notice: they are what says there is more than one
	   photograph and that it moves. */
	.home_page .home_banner_nav {
		display: flex;
	}
	.home_page .home_banner_inner {
		padding-top: clamp(120px, 18vh, 170px);
		padding-bottom: clamp(120px, 18vh, 170px);
	}
	.home_page .home_promises,
	.home_page .home_services_grid {
		grid-template-columns: minmax(0, 1fr);
	}
	/* Two across rather than the asymmetric four, with the first still leading. */
	.home_page .home_portfolio_grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		grid-auto-rows: 140px;
	}
	/* One card per row here, so the picture is roughly 350px wide against a
	   260px fixed height - a 1.35 landscape window onto a square photograph,
	   which throws away a quarter of its height and takes the face with it.
	   Letting the frame match the source keeps the whole crop the photographer
	   framed. The fixed height stays on wider screens, where three cards sit
	   side by side and the frame is already near square. */
	.home_page .home_service_media img {
		height: auto;
		aspect-ratio: 1 / 1;
	}
}


/* Hover states shared across the site
   ------------------------------------------------------------
   Everything clickable answers to the pointer. The page-specific components
   carry their own states above; this is for the parts that come from the
   parent theme's markup, which has none of its own worth keeping.
------------------------------------------------------------ */

/* Main menu: the rule grows from the centre rather than appearing at full
   width, so the movement reads as a response to the pointer. */
.sc_layouts_menu_nav > li > a {
	position: relative;
	transition: color .3s ease;
}

/* The rule is positioned against the link box, not the text, and that box is
   59px tall against a ~27px line - so a small 'bottom' parks it near the foot
   of the header rather than under the word. 10px closes most of that gap while
   still clearing the descenders on "Gallery" and "Contact Us". */
.sc_layouts_menu_nav > li > a::after {
	content: '';
	position: absolute;
	right: 0;
	bottom: 10px;
	left: 0;
	height: 1px;
	background-color: var(--theme-color-link);
	transform: scaleX(0);
	transition: transform .35s ease;
}

.sc_layouts_menu_nav > li > a:hover::after,
.sc_layouts_menu_nav > li.current-menu-item > a::after {
	transform: scaleX(1);
}

/* The mobile menu button and any other iconed link in the header. */
.sc_layouts_iconed_text_link {
	transition: color .3s ease, transform .3s ease;
}

.sc_layouts_iconed_text_link:hover {
	color: var(--theme-color-link);
	transform: scale(1.1);
}

/* Footer links, wherever they appear. */
.footer_millicent a {
	transition: color .3s ease, opacity .3s ease;
}

/* Anything that lifts, zooms or slides on hover stays put for a visitor who
   has asked for less movement. Their transitions are cut to nothing rather
   than removed, so the end state is still applied and nothing looks broken. */
@media (prefers-reduced-motion: reduce) {
	.home_page *,
	.legal_page *,
	.sc_layouts_menu_nav > li > a::after,
	.sc_layouts_logo img {
		transition-duration: .01ms !important;
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
	}
	.home_page .home_promise:hover,
	.legal_page .legal_subsection_carded:hover {
		transform: none;
	}
	.home_page .home_service_media:hover img,
	.home_page .home_portfolio_item:hover img {
		transform: none;
	}
}


/* Cookie consent (inc/consent.php, js/consent.js)
   ------------------------------------------------------------
   A banner along the foot of the window and a preferences dialog over it.

   On colour: the brand rose (--theme-color-link, #B76E79) carries white text
   at 3.8:1, which fails WCAG AA for the button labels here. The darker tone
   the theme already uses for hover (--theme-color-hover, #9F5A64) reaches
   5.1:1 and passes, so the consent buttons are built on that and darken
   further on hover. Same palette, legible for everyone.
------------------------------------------------------------ */

.mda_consent[hidden],
.mda_consent_banner[hidden],
.mda_consent_overlay[hidden] {
	display: none;
}

/* ---------- Banner ---------- */

/* Pinned to the bottom edge, so two device realities apply.

   The home indicator on a modern iPhone occupies the bottom of the screen and
   swallows taps meant for whatever sits under it - the Reject button, in this
   layout. env(safe-area-inset-bottom) lifts the padding clear of it, and
   resolves to 0 everywhere else, so max() keeps the normal spacing.

   The height cap is for landscape phones: at 360px tall the banner and its
   three stacked buttons are taller than the window, and without a scroll there
   is no way to reach Reject at all. */
.mda_consent_banner {
	position: fixed;
	/* Same reason as the dialog below: over the theme's 8000 header, under the
	   dialog the banner itself opens. */
	z-index: 8900;
	right: 0;
	bottom: 0;
	left: 0;
	/* border-box, or the cap below applies to the content alone and the 32px of
	   padding and the border are added outside it - which is how a banner
	   capped at 317px still measured 350px on a 360px-tall screen. */
	box-sizing: border-box;
	overflow-y: auto;
	max-height: 80vh;
	max-height: 80dvh;
	padding: clamp(16px, 2vw, 24px);
	padding-bottom: max(clamp(16px, 2vw, 24px), env(safe-area-inset-bottom));
	border-top: 1px solid var(--theme-color-bd_color);
	background-color: #ffffff;
	box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.12);
	animation: mda_consent_up .35s ease both;
}

@keyframes mda_consent_up {
	from {
		transform: translateY(100%);
	}
	to {
		transform: translateY(0);
	}
}

.mda_consent_banner_inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 20px clamp(24px, 3vw, 50px);
	max-width: 1290px;
	margin: 0 auto;
}

.mda_consent_banner_copy {
	flex: 1 1 420px;
	min-width: 0;
}

.mda_consent_title {
	margin: 0 0 8px;
	font-size: 19px;
	line-height: 1.3;
}

/* The heading takes focus when the banner appears, so a screen reader lands on
   it rather than on whatever came before. It is not interactive, so it must
   not look interactive - only the focus ring appears. */
.mda_consent_title:focus {
	outline: none;
}

.mda_consent_title:focus-visible {
	outline: 2px solid var(--theme-color-hover);
	outline-offset: 4px;
}

.mda_consent_text {
	margin: 0;
	font-size: 15px;
	line-height: 1.65;
}

.mda_consent_text a {
	color: var(--theme-color-hover);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

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

/* Accept, Reject and Manage are one size and one shape. The first two share a
   fill; the third is outlined so it reads as "go elsewhere" rather than as a
   quieter version of a choice. Nothing here is dimmed or shrunk to nudge. */
.mda_consent_actions {
	display: flex;
	flex: 0 1 auto;
	flex-wrap: wrap;
	gap: 10px;
}

.mda_consent_button {
	flex: 1 1 auto;
	min-width: 160px;
	padding: 14px 24px;
	border: 2px solid var(--mda-button);
	border-radius: 8px;
	background-color: var(--mda-button);
	color: #ffffff;
	font-family: inherit;
	font-size: 15px;
	font-weight: 500;
	line-height: 1.3;
	text-align: center;
	cursor: pointer;
	transition: background-color .25s ease, border-color .25s ease, color .25s ease, transform .25s ease;
}

.mda_consent_button:hover {
	transform: translateY(-2px);
	border-color: var(--mda-button-hover);
	background-color: var(--mda-button-hover);
	color: #ffffff;
}

/* Accept and Reject keep the same box, the same weight and the same size - only
   the fill differs, and the outlined one is no quieter than the filled one.
   tests/consent.test.mjs measures that pair and fails if they drift apart. */
.mda_consent_button_alt {
	background-color: transparent;
	color: var(--mda-button);
}

.mda_consent_button_alt:hover {
	background-color: transparent;
	border-color: var(--mda-button-hover);
	color: var(--mda-button-hover);
}

/* One visible focus style for every control in here, never removed. */
.mda_consent button:focus-visible,
.mda_consent a:focus-visible,
.mda_consent input:focus-visible,
.mda_consent_link:focus-visible {
	outline: 3px solid var(--theme-color-title);
	outline-offset: 2px;
}

/* ---------- Preferences dialog ---------- */

/* Above the parent theme's header, which carries z-index 8000. At 1200 the
   header painted straight over the top of this dialog, hiding its title and its
   close button - so the one control that dismisses it was behind the logo. A
   modal has to be above the furniture. */
.mda_consent_overlay {
	position: fixed;
	z-index: 9000;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(12px, 3vw, 40px);
	background-color: rgba(20, 20, 20, 0.55);
}

/* The page behind must not scroll while the dialog is open. */
body.mda_consent_open {
	overflow: hidden;
}

.mda_consent_modal {
	display: flex;
	flex-direction: column;
	width: min(680px, 100%);
	max-height: min(86vh, 760px);
	border-radius: 14px;
	background-color: #ffffff;
	box-shadow: 0 30px 70px rgba(0, 0, 0, 0.3);
	animation: mda_consent_in .3s ease both;
}

@keyframes mda_consent_in {
	from {
		opacity: 0;
		transform: translateY(16px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.mda_consent_modal_head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 24px clamp(20px, 3vw, 32px);
	border-bottom: 1px solid var(--theme-color-bd_color);
}

.mda_consent_close {
	width: 40px;
	height: 40px;
	padding: 0;
	border: none;
	border-radius: 50%;
	background-color: transparent;
	color: var(--theme-color-title);
	font-size: 26px;
	line-height: 1;
	cursor: pointer;
	transition: background-color .25s ease;
}

.mda_consent_close:hover {
	background-color: var(--theme-color-bg_color_2);
}

.mda_consent_modal_body {
	overflow-y: auto;
	padding: 24px clamp(20px, 3vw, 32px);
}

.mda_consent_list {
	margin: 22px 0 0;
	padding: 0;
	list-style: none;
}

.mda_consent_item + .mda_consent_item {
	margin-top: 14px;
}

.mda_consent_item {
	padding: 18px 20px;
	border: 1px solid var(--theme-color-bd_color);
	border-radius: 10px;
}

.mda_consent_item_head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
}

.mda_consent_item_text {
	margin: 8px 0 0;
	font-size: 14px;
	line-height: 1.6;
}

.mda_consent_always {
	color: var(--theme-color-hover);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* ---------- Toggles ---------- */

/* A real checkbox, moved off-screen rather than display:none, so it keeps its
   place in the tab order and its state is announced. The track is decoration
   and is hidden from screen readers in the markup. */
.mda_consent_switch {
	display: flex;
	align-items: center;
	gap: 12px;
	cursor: pointer;
}

.mda_consent_switch_input {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.mda_consent_switch_track {
	position: relative;
	flex: none;
	width: 48px;
	height: 28px;
	border: 2px solid var(--theme-color-meta);
	border-radius: 100px;
	background-color: #ffffff;
	transition: background-color .25s ease, border-color .25s ease;
}

.mda_consent_switch_track::after {
	content: '';
	position: absolute;
	top: 3px;
	left: 3px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background-color: var(--theme-color-meta);
	transition: transform .25s ease, background-color .25s ease;
}

.mda_consent_switch_input:checked + .mda_consent_switch_track {
	border-color: var(--theme-color-hover);
	background-color: var(--theme-color-hover);
}

.mda_consent_switch_input:checked + .mda_consent_switch_track::after {
	transform: translateX(20px);
	background-color: #ffffff;
}

.mda_consent_switch_input:disabled + .mda_consent_switch_track {
	opacity: 0.65;
	cursor: not-allowed;
}

/* The checkbox is off-screen, so its focus ring has to be drawn on the track. */
.mda_consent_switch_input:focus-visible + .mda_consent_switch_track {
	outline: 3px solid var(--theme-color-title);
	outline-offset: 3px;
}

.mda_consent_switch_label {
	font-size: 16px;
	font-weight: 500;
}

.mda_consent_modal_foot {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	padding: 20px clamp(20px, 3vw, 32px);
	border-top: 1px solid var(--theme-color-bd_color);
	background-color: var(--theme-color-bg_color);
	border-radius: 0 0 14px 14px;
}

.mda_consent_modal_foot .mda_consent_button {
	flex: 1 1 150px;
}

/* ---------- The "Cookie Settings" link in the footer ---------- */

/* A button by function, a link by appearance: it opens a dialog, so it must be
   a <button> for the keyboard and for screen readers, but it sits in a list of
   links and should look like its neighbours. */
.mda_consent_link {
	padding: 0;
	border: none;
	background: none;
	color: inherit;
	font: inherit;
	text-decoration: none;
	cursor: pointer;
}

/* It is a real <button>, so the parent theme's generic button styling reaches
   it on hover and painted a solid rose pill (rgb(159, 90, 100)) around the
   words - which looked like a stray button dropped into a row of plain text
   links. These declarations keep the background off and give it the same hover
   its neighbours in that list have: the text simply brightens to white.

   background-color needs !important because the parent sets it on button:hover
   with !important of its own. */
.mda_consent_link:hover,
.mda_consent_link:focus {
	background: none !important;
	background-color: transparent !important;
	color: #ffffff;
	text-decoration: none;
}

/* ---------- Blocked third-party embeds ---------- */

.mda_embed {
	display: flex;
	width: 100%;
	height: 100%;
	min-height: inherit;
}

.mda_embed iframe {
	display: block;
	width: 100%;
	height: 100%;
	min-height: inherit;
	border: none;
}

.mda_embed_placeholder {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	width: 100%;
	padding: clamp(24px, 4vw, 50px);
	background-color: var(--theme-color-bg_color_2);
	text-align: center;
}

.mda_embed_title {
	margin: 0 0 8px;
	color: var(--theme-color-title);
	font-size: 17px;
	font-weight: 500;
}

.mda_embed_text {
	max-width: 46em;
	margin: 0 0 20px;
	font-size: 15px;
	line-height: 1.6;
}

.mda_embed_actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px;
	margin: 0;
}

/* Black, like every other button. These two sit on the map placeholder. */
.mda_embed_load,
.mda_embed_settings {
	padding: 12px 22px;
	border: 2px solid var(--mda-button);
	border-radius: 8px;
	background-color: var(--mda-button);
	color: #ffffff;
	font-family: inherit;
	font-size: 15px;
	line-height: 1.3;
	cursor: pointer;
	transition: background-color .25s ease, border-color .25s ease, color .25s ease;
}

.mda_embed_settings {
	background-color: transparent;
	color: var(--mda-button);
}

.mda_embed_load:hover {
	border-color: var(--mda-button-hover);
	background-color: var(--mda-button-hover);
}

.mda_embed_settings:hover {
	border-color: var(--mda-button-hover);
	color: var(--mda-button-hover);
}

.mda_embed_load:focus-visible,
.mda_embed_settings:focus-visible {
	outline: 3px solid var(--theme-color-title);
	outline-offset: 2px;
}

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

@media (max-width: 767px) {
	.mda_consent_banner {
		max-height: 88vh;
		overflow-y: auto;
	}
	.mda_consent_banner_inner {
		flex-direction: column;
		align-items: stretch;
	}
	/* Full width and stacked, all three the same. Narrowing "Reject all" to
	   fit it beside "Accept all" is exactly the nudge that is not allowed. */
	.mda_consent_actions {
		flex-direction: column;
	}
	.mda_consent_button {
		width: 100%;
		min-width: 0;
	}
	.mda_consent_modal {
		max-height: 92vh;
	}
	.mda_consent_modal_foot {
		flex-direction: column;
	}

	/* flex:1 1 150px is written for a row, where it shares the width. Turning
	   the footer into a column turns that grow factor vertical, so on a 320px
	   screen "Accept all" and "Reject all" stretched to about 160px tall each,
	   swallowed the dialog's height and pushed the actual cookie toggles off
	   the bottom - the one thing the dialog exists to show. */
	.mda_consent_modal_foot .mda_consent_button {
		flex: 0 0 auto;
		width: 100%;
	}

	/* min-height:0 lets this shrink below its content and scroll. Without it a
	   flex child refuses to go under its content height, so the list pushed the
	   dialog past the screen instead of scrolling inside it. */
	.mda_consent_modal_body {
		flex: 1 1 auto;
		min-height: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.mda_consent_banner,
	.mda_consent_modal {
		animation: none;
	}
	.mda_consent_button:hover {
		transform: none;
	}
	.mda_consent_switch_track,
	.mda_consent_switch_track::after {
		transition: none;
	}
}


/* Closing call-to-action band (clean_child_cta_band)
   ------------------------------------------------------------
   One component for the block every page ends with. It replaced four
   near-identical implementations - .about_cta on About, Treatments and
   Gallery, .faq_cta on FAQs and .home_cta on the home page - which had drifted
   into four different paddings and three different button styles.

   Full-bleed, over a photograph, with a wash so white type holds against
   whatever the picture is doing underneath.
------------------------------------------------------------ */

.mda_cta {
	position: relative;
	padding: clamp(64px, 8vw, 130px) clamp(24px, 4vw, 60px);
	background-color: var(--theme-color-title);
	background-position: center;
	background-size: cover;
	text-align: center;
}

/* True edge to edge. The theme's own .alignfull leaves an 8px gutter, which is
   right for a quote block inside a page and wrong for a full-width band.

   box-sizing matters here and is not inherited from anywhere: this section
   computes as content-box, so `width: 100vw` was sizing the *content* to the
   full viewport and then adding the horizontal padding on top - 57.6px a side
   at 1440px, giving a 1539px band in a 1440px window. That single declaration
   was the only cause of horizontal scroll on every page carrying this band. */
.mda_cta.alignfull {
	box-sizing: border-box;
	width: 100vw;
	max-width: 100vw;
	margin-right: calc(-50vw + 50%);
	margin-left: calc(-50vw + 50%);
}

.mda_cta::before {
	content: '';
	position: absolute;
	inset: 0;
	background:
		linear-gradient(180deg, rgba(0, 0, 0, 0.42) 0%, rgba(0, 0, 0, 0.58) 100%);
}

/* With no photograph bundled the band keeps the theme's dark tone and the
   same white type, so a missing file degrades rather than breaks. */
.mda_cta_no_media::before {
	display: none;
}

.mda_cta_inner {
	position: relative;
	max-width: 44em;
	margin: 0 auto;
}

.mda_cta_eyebrow {
	display: block;
	margin-bottom: 20px;
	color: rgba(255, 255, 255, 0.82);
	font-size: 13px;
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.mda_cta_title {
	margin: 0 0 0.45em;
	color: #ffffff;
	font-size: clamp(30px, 4vw, 52px);
	line-height: 1.15;
}

.mda_cta_text {
	margin: 0 0 34px;
	color: rgba(255, 255, 255, 0.9);
	font-size: 18px;
	line-height: 1.7;
	/* The band is centred, so the prose is too - and justification, which the
	   site applies to body copy elsewhere, would open rivers in it. */
	text-align: center;
}

.mda_cta_text a {
	color: #ffffff;
	text-decoration: underline;
	text-underline-offset: 0.15em;
	transition: opacity .25s ease;
}

.mda_cta_text a:hover {
	opacity: 0.75;
}

.mda_cta_actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 14px;
}

/* border-box because this button stretches to the column width on narrow
   screens: as content-box its 34px side padding and 2px border were added
   outside that width, pushing it 72px past the band and taking the page with
   it. */
.mda_cta_button {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	max-width: 100%;
	padding: 16px 34px;
	border: 2px solid var(--mda-button);
	border-radius: 100px;
	background-color: var(--mda-button);
	color: #ffffff;
	font-size: 15px;
	font-weight: 500;
	line-height: 1.3;
	text-align: center;
	text-decoration: none;
	transition: transform .3s ease, background-color .3s ease, border-color .3s ease, color .3s ease, box-shadow .3s ease;
}

.mda_cta_button:hover,
.mda_cta_button:focus-visible {
	transform: translateY(-3px);
	border-color: var(--mda-button-hover);
	background-color: var(--mda-button-hover);
	color: #ffffff;
	box-shadow: 0 16px 32px rgba(0, 0, 0, 0.28);
}

/* On the closing band the buttons sit on a photograph, and the photographs on
   this site are mostly dark - black scrubs, black gloves, dim treatment rooms.
   A black button on that is a white label floating in the picture: the label
   stays perfectly readable (19.5:1) but the button loses its shape, and the
   shape is what tells somebody it can be pressed.

   So on this band, and only here, the filled button keeps its black fill and
   borrows the ring the outlined one already wears. The two then read as a
   matched pair - same size, same ring, one filled and one not - instead of one
   button and one hole. Everywhere else on the site buttons sit on white or
   cream and need no ring. */
.mda_cta .mda_cta_button {
	border-color: rgba(255, 255, 255, 0.55);
}

.mda_cta .mda_cta_button:hover,
.mda_cta .mda_cta_button:focus-visible {
	border-color: #ffffff;
}

.mda_cta_button_alt {
	border-color: rgba(255, 255, 255, 0.55);
	background-color: transparent;
}

.mda_cta_button_alt:hover,
.mda_cta_button_alt:focus-visible {
	border-color: #ffffff;
	background-color: #ffffff;
	color: var(--theme-color-title);
}

.mda_cta_button:focus-visible {
	outline: 3px solid #ffffff;
	outline-offset: 3px;
}

@media (max-width: 767px) {
	.mda_cta_text {
		font-size: 16px;
	}
	.mda_cta_actions {
		flex-direction: column;
	}
	.mda_cta_button {
		width: 100%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.mda_cta_button:hover {
		transform: none;
	}
}


/* The parent theme's buttons
   ------------------------------------------------------------
   .sc_button_default is the parent theme's own button, and it takes its fill
   from the theme options rather than from this file - so the Send Message
   button on Contact Us stayed rose while every button written here went black.
   The options are stored in the database, which means a rebuild or a theme
   re-import loses them; the rule below does not.

   Scoped to the child theme's own contexts rather than applied to every
   .sc_button on the site, so a button inside a plugin's markup (WooCommerce,
   a form builder) is left to that plugin's styling.
------------------------------------------------------------ */

.contact_form_wrap .contact_form_button,
.contact_page .sc_button_default,
.book_page .sc_button_default,
.home_page .sc_button_default {
	border-color: var(--mda-button);
	background-color: var(--mda-button);
	color: #ffffff;
	transition: background-color .3s ease, border-color .3s ease, transform .3s ease, box-shadow .3s ease;
}

/* The parent sets the hover colour with !important (skins/default/css/style.css),
   so the label needs it back or it washes out to the link colour on a black
   fill - unreadable, on the one button that sends the enquiry. */
.contact_form_wrap .contact_form_button:hover,
.contact_form_wrap .contact_form_button:focus-visible,
.contact_page .sc_button_default:hover,
.contact_page .sc_button_default:focus-visible,
.book_page .sc_button_default:hover,
.book_page .sc_button_default:focus-visible,
.home_page .sc_button_default:hover,
.home_page .sc_button_default:focus-visible {
	transform: translateY(-2px);
	border-color: var(--mda-button-hover);
	background-color: var(--mda-button-hover);
	color: #ffffff !important;
	box-shadow: 0 10px 22px rgba(0, 0, 0, 0.22);
}

@media (prefers-reduced-motion: reduce) {
	.contact_form_wrap .contact_form_button:hover,
	.contact_page .sc_button_default:hover,
	.book_page .sc_button_default:hover,
	.home_page .sc_button_default:hover {
		transform: none;
	}
}


/* Touch targets
   ------------------------------------------------------------
   Below the tablet breakpoint the site is being driven by a thumb, and a thumb
   is not a mouse pointer: the controls below all measured between 20px and
   42px tall, under the 44px that WCAG 2.5.5 asks for and under the size at
   which people stop mis-tapping.

   Only standalone controls are listed. Links sitting inside a sentence are
   deliberately left alone - they are exempt from the target-size rules, and
   padding them to 44px would wreck the line spacing of the paragraph they sit
   in.
------------------------------------------------------------ */

@media (max-width: 1023px) {

	/* The burger is the only way into the menu on a phone, and it measured
	   33px. Nothing else on the site matters more to get right. */
	.mda_bar_burger .sc_layouts_item_link {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-width: 44px;
		min-height: 44px;
	}

	.mda_bar_icon {
		width: 44px;
		height: 44px;
	}

	.sc_layouts_logo {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	.footer_millicent .mda_footer_social {
		width: 44px;
		height: 44px;
	}

	/* Wraps the agency logo, so it has no text to give it height of its own. */
	.footer_millicent .mda_footer_credit_link {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	.contact_page .contact_social_link,
	.gallery_page .gallery_filter {
		min-height: 44px;
	}

	/* Tap-to-call and tap-to-email are the two things this page exists for, and
	   the phone number was a 24px line of text. The padding is cancelled by an
	   equal negative margin, so the hit area grows to 44px without moving the
	   label above it or opening a gap in the row. */
	.contact_page a.contact_details_value {
		display: inline-block;
		padding: 10px 0;
		margin: -10px 0;
	}

	/* The comment form's checkboxes render at the browser default of 13px, which
	   is a hard target to hit with a thumb. 22px is as large as a checkbox can
	   go before it stops reading as one; the label beside it is clickable too,
	   so the combined target clears the minimum comfortably. */
	.comments_form_wrap input[type="checkbox"],
	.comments_form_wrap input[type="radio"] {
		width: 22px;
		height: 22px;
	}

	/* Standalone share buttons on posts, as opposed to the inline meta links
	   beside them, which are exempt as text within a sentence. */
	.social_item {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-width: 44px;
		min-height: 44px;
	}

	/* 20.3px line box, so 12px each side clears 44px with a pixel to spare. */
	.legal_page .legal_toc_link {
		display: block;
		padding-top: 12px;
		padding-bottom: 12px;
	}

	/* Parent-theme control, so it is sized here rather than in the parent. */
	.trx_addons_scroll_to_top {
		width: 44px;
		height: 44px;
	}

	/* The theme sets these at 15px. iOS Safari zooms the page whenever a
	   focused field is under 16px, which throws the layout sideways mid-form
	   and does not zoom back out. 16px is the threshold, not a preference. */
	.contact_form_wrap .contact_form_row input,
	.contact_form_wrap .contact_form_row textarea,
	.contact_form_wrap .contact_form_row select {
		font-size: 16px;
	}
}

/* Visible only while focused, but when it is visible it is a real control and
   is the first thing a keyboard or switch user lands on. */
.skip-link.clean_skip_link:focus {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}


/* Mobile menu drawer
   ------------------------------------------------------------
   The drawer itself is the parent theme's, opened from .mda_bar_burger. Only
   two things are corrected here.

   First, Book Now. In the desktop bar it is a filled pill - it is the one
   thing the site is pointing at - but the same menu item arrives in the drawer
   as plain text in a list of seven, so on a phone the primary call to action
   was the least prominent item on screen. clean_child_mark_menu_cta() puts
   .mda_menu_cta on the item in both places, so it can be given equivalent
   weight here.

   Second, tap heights: the drawer's items measured under 44px.
------------------------------------------------------------ */

.menu_mobile .menu_mobile_nav > li > a {
	display: flex;
	align-items: center;
	min-height: 48px;
}

.menu_mobile .menu_mobile_nav > li.mda_menu_cta {
	margin-top: 18px;
}

/* The same pill as the desktop bar. It was still rose here while the bar was
   black, so the one button the site points at looked like two different
   buttons depending on the width of the screen. */
.menu_mobile .menu_mobile_nav > li.mda_menu_cta > a {
	justify-content: center;
	padding: 12px 28px;
	border-radius: 100px;
	background-color: var(--theme-color-hover);
	color: #ffffff !important;
	transition: background-color .3s ease;
}

/* The colour needs !important for the same reason it does in the header bar:
   the parent sets .menu_mobile_nav > li > a with its own !important colour. */
.menu_mobile .menu_mobile_nav > li.mda_menu_cta > a:hover,
.menu_mobile .menu_mobile_nav > li.mda_menu_cta > a:focus-visible {
	background-color: var(--mda-accent-deep);
	color: #ffffff !important;
}

/* The close control measured 45px wide but sat on a 6px icon; give the whole
   thing a proper target. */
.menu_mobile .menu_mobile_close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 48px;
	min-height: 48px;
}

/* Seven items plus the call to action can exceed a short landscape screen, and
   the drawer had no way to reach the ones below the fold.

   Scoped to .opened, and that is not optional. The closed drawer is not
   display:none - the parent leaves it as a visible, zero-height block and
   collapses it another way - so padding applied unconditionally gives it a
   48px body that paints its cream background across the top of every page,
   over the pinned header. */
.menu_mobile.opened .menu_mobile_inner {
	overflow-y: auto;
	max-height: 100vh;
	max-height: 100dvh;
	padding-top: max(24px, env(safe-area-inset-top));
	padding-bottom: max(24px, env(safe-area-inset-bottom));
}


/* Card hover
   ------------------------------------------------------------
   One definition for every card on the site. There are four of them - the About
   values, the Treatments groups, the Book Now options and the home Promises -
   and each had drifted to its own hover: lifts of 0px, 4px and 6px, two
   different shadow opacities, and one card with no shadow at all. Same shape,
   same tinted background, four different responses to the same gesture.

   The values below are the settled ones. Change them here and every card
   follows; that is the point of the rule existing.

   Border uses --theme-color-hover (#9F5A64) rather than --theme-color-link
   (#B76E79): at one pixel against the cream card fill the lighter rose barely
   registers, and the deeper plum is the same tone the buttons and the header
   icons settle on, so a hover reads as one language across the site.

   Guarded by (hover: hover) because :hover sticks after a tap on a touch
   screen, leaving a card looking permanently picked.
------------------------------------------------------------ */

.about_page .about_value,
.treatments_page .treatments_group,
.book_page .book_way,
.contact_page .contact_hours,
.home_page .home_promise {
	transition: transform .35s ease, border-color .35s ease, box-shadow .35s ease;
}

@media (hover: hover) {
	.about_page .about_value:hover,
	.treatments_page .treatments_group:hover,
	.book_page .book_way:hover,
	.contact_page .contact_hours:hover,
	.home_page .home_promise:hover {
		transform: translateY(-6px);
		border-color: var(--theme-color-hover);
		box-shadow: 0 18px 40px rgba(0, 0, 0, 0.07);
	}

	/* The home promises are the exception, at the client's request: their hover
	   is monochrome, icon and border together. Half a rose hover - black disc,
	   rose keyline - would read as an oversight rather than a decision. */
	.home_page .home_promise:hover {
		border-color: var(--mda-button);
	}
}

/* The lift is the part that has to go; the border and shadow still mark the
   card without moving it. */
@media (prefers-reduced-motion: reduce) {
	.about_page .about_value:hover,
	.treatments_page .treatments_group:hover,
	.book_page .book_way:hover,
	.contact_page .contact_hours:hover,
	.home_page .home_promise:hover {
		transform: none;
	}
	/* The icons turn and tilt as well, and that is movement too. */
	.book_page .book_way:hover .book_way_icon,
	.contact_page .contact_details_item:hover .contact_details_icon,
	.contact_page .contact_hours:hover .contact_hours_icon svg {
		transform: none;
	}
}
