/*
Theme Name: Tarot with Gord
Theme URI: https://tarotwithgord.com
Author: Tarot with Gord
Description: The block theme for tarotwithgord.com. Replaces Neve and Otter. The design system lives in theme.json; content structure lives in the TWG Core plugin, never here, so this theme can be swapped without taking the content with it.
Version: 1.7.0
Requires at least: 6.5
Tested up to: 6.8
Requires PHP: 7.4
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: tarot-with-gord
Tags: block-patterns, full-site-editing, custom-colors, custom-menu
*/

/*
 * Almost nothing belongs in this file. theme.json is the source of truth for
 * colour, type, spacing and buttons. Only add a rule here when the block editor
 * genuinely offers no way to express it.
 */

/* ---------------------------------------------------------------------------
 * Neve variable compatibility. DO NOT REMOVE.
 *
 * Six live plugin files carry 151 references to Neve's `--nv-*` custom
 * properties: the member hub, the journal, the Noticing Tool, the account area,
 * the help centre and the spread canvas. Neve defines them today. Neve is
 * deactivated at cut-over, and on that day every one of those references would
 * resolve to nothing and the whole members' area would render without its
 * colours.
 *
 * These aliases hold the SAME values Neve holds today, so no plugin has to
 * change and nothing looks different. They are a bridge, not a second palette:
 * the four values above are the only colours on this site.
 * ------------------------------------------------------------------------- */
:root {
	--nv-primary-accent: var(--wp--preset--color--rust);
	--nv-secondary-accent: var(--wp--preset--color--copper);
	--nv-text-color: var(--wp--preset--color--beige);
	--nv-text-dark-bg: var(--wp--preset--color--abyss);
	--nv-site-bg: var(--wp--preset--color--abyss);
	--nv-light-bg: var(--wp--preset--color--beige,#d6c9ae);
	--primarybtnbg: var(--wp--preset--color--rust);
	--primarybtncolor: var(--wp--preset--color--abyss);
}

/* Skip link, which theme.json cannot style. */
.skip-link:focus {
	background-color: var(--wp--preset--color--rust);
	color: var(--wp--preset--color--abyss);
	outline-offset: 2px;
}

/* The opt-out used by the auto-linker. Kept here so the class exists in the
   theme's own stylesheet and never depends on a plugin being active. */
.no-autolink a[data-twg-autolink] {
	pointer-events: none;
}

/* ---------------------------------------------------------------------------
   THE TEMPLATE PART WRAPPER, AND WHY THE STICKY HEADER DID NOT STICK

   WordPress ALWAYS wraps a template part in an element of its own. There is no
   attribute that switches the wrapper off: `render_block_core_template_part()`
   uses `tagName` if given, and otherwise the `area_tag` for the part's area,
   which is `header` for a header area and `footer` for a footer area. Both of
   our areas are declared in theme.json, so removing `tagName` from the
   template-part call changes nothing at all. Measured, not assumed.

   That wrapper is exactly as tall as the header inside it, 126px. A sticky
   element can only travel inside its containing block, so the header had 0px
   of travel and scrolled away with the page: after scrollTo(0,1200) its top
   was measured at -1200 while `position` still computed to `sticky`.

   `display: contents` removes the wrapper's box from the layout without
   removing the element, so the header's containing block becomes
   `.wp-site-blocks`, which is the full height of the document. The header then
   sticks. Verified on staging at 1440px and 390px: top stays at 0 after
   scrolling 1200px, against -1200 before.

   The sticky itself deliberately stays where it is, on the Group block in
   parts/header.html, so it remains a switch Gord can turn off in the editor
   rather than something welded on in CSS here.

   The parts' own outer Group blocks are now `div`s (they were `header` and
   `footer`), so the wrapper is the only landmark. The page previously carried
   two <header> and two <footer> elements.
--------------------------------------------------------------------------- */
.wp-site-blocks > header.wp-block-template-part,
.wp-site-blocks > footer.wp-block-template-part {
	display: contents;
}

/* ---------------------------------------------------------------------------
   THE MENU COLLAPSES AT 782px, NOT AT WORDPRESS'S 600px

   Gord, 3 August: "yeah menu for tablets." With the menu showing on desktop,
   the seven top-level items wrapped onto THREE rows between 600px and 780px and
   the header grew from 125px to 163px. Measured in a same-origin iframe at 390,
   700, 900 and 1240, not guessed at.

   The cause is that core collapses this nav at 600px and the rest of this site
   switches at 782px, and core's 600 is not a setting anywhere. So the four core
   rules are reversed for the band in between. THEY WERE READ OFF THE SERVED
   `style.min.css` RATHER THAN REMEMBERED, because they carry `:not()` guards
   that a from-memory version would have missed and it would have failed
   silently:

     @media (min-width: 600px){
       .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open){ display:block; ... }
       .wp-block-navigation__responsive-container-open:not(.always-shown){ display:none }
     }

   `hidden-by-default` and `always-shown` are what core puts on the markup when
   the overlay is set to "always", so the guards must be repeated here or this
   would also fight a nav that was deliberately set to always-overlay.

   If a WordPress update moves or renames these, the symptom is a tablet header
   with three rows of links again, not a broken page.
--------------------------------------------------------------------------- */
/* ⛔ THE TOP OF THIS BAND WAS 781px AND IS NOW 1150px, 19 August.

   Gord: "make the menu not run fucking two rows... Everything should be on one
   row apart from the fucking social icons."

   Measured rather than guessed: the eight top-level items need about 914px at
   the normal size and still about 842px at the smallest readable size with the
   gaps closed up, and the nav only ever gets the width left over once the logo
   has had its share. Below roughly 1150px that width is not there, so the menu
   button is the only honest answer. Above it the block below shrinks the text
   and the gaps to fit. */
@media (min-width: 600px) and (max-width: 1150px){
	.wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open){
		display: none;
	}
	.wp-block-navigation__responsive-container-open:not(.always-shown){
		display: flex;
	}
}

/* ---------------------------------------------------------------------------
   AND ABOVE 1150, ONE ROW, ALWAYS

   `flex-wrap: nowrap` is the part that actually guarantees it. The clamps just
   make sure that nowrap never turns into an overflow. Submenus are put back to
   wrapping, because they are a dropdown and have their own width.
--------------------------------------------------------------------------- */
@media (min-width: 1151px){
	header .wp-block-navigation{
		font-size: clamp(0.75rem, 0.57vw + 0.095rem, 0.95rem);
	}
	header .wp-block-navigation .wp-block-navigation__container{
		flex-wrap: nowrap;
		gap: clamp(0.5rem, 0.7vw, 1.1rem);
	}
	header .wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation__container{
		flex-wrap: wrap;
	}
	header .wp-block-navigation .wp-block-navigation-item__content{
		white-space: nowrap;
	}
}

/* ---------------------------------------------------------------------------
   MENU HOVER: COPPER, TOP LEVEL AND SUBMENUS ALIKE

   Gord, 3 August: "menu needs copper hover and submenus need to be rust/copper
   too like their parent items." There were NO hover rules on the navigation at
   all, anywhere, which is why nothing happened when you moved the mouse over it.
   Checked by walking every stylesheet on the page for a `:hover` selector
   mentioning `navigation`, and finding none.

   Rust comes from the block's own colour setting rather than from here, and the
   submenus follow it because the nav's overlay text colour is now rust as well,
   which is the same setting core applies to a submenu panel. So this file only
   has to own the hover, which is the one part no block setting can express.

   `wp-block-navigation-item__content` is the class core puts on the thing you
   actually click, whether it renders as a link or as a button, so one selector
   covers a plain item, a submenu parent, and a child inside the panel.

   `:focus-visible` is in there deliberately: somebody tabbing through the menu
   should get the same signal as somebody with a mouse, and it costs one word.
--------------------------------------------------------------------------- */
.wp-site-blocks header .wp-block-navigation .wp-block-navigation-item__content:where(:hover, :focus-visible),
.wp-site-blocks header .wp-block-navigation .wp-block-navigation-item__content:where(:hover, :focus-visible) .wp-block-navigation-item__label{
	color: var(--wp--preset--color--copper);
}

/* The little chevron on a submenu parent follows the label rather than staying
   rust while the word next to it turns copper. */
.wp-site-blocks header .wp-block-navigation .wp-block-navigation-item:hover > .wp-block-navigation-submenu__toggle .wp-block-navigation__submenu-icon,
.wp-site-blocks header .wp-block-navigation .wp-block-navigation-item:hover > .wp-block-navigation-item__content .wp-block-navigation__submenu-icon{
	color: var(--wp--preset--color--copper);
	fill: currentColor;
}

/* ---------------------------------------------------------------------------
   BLOCK STYLES
   The named choices registered in functions.php. Each is something Gord can
   pick in the editor rather than something baked into a template.
--------------------------------------------------------------------------- */

/* Outline button. theme.json owns the filled one; this is the pair.
   The rules that USED to sit here forced the background transparent, which is
   why picking a colour for it in the editor did nothing. They have moved, and
   changed, down to "THE OUTLINE BUTTON STANDS ON ITS OWN GROUND". Nothing
   should set an outline button's background above that point. */

/* Heading with the rule under it. Tight to the heading, because a hairline
   floating below reads as an unrelated divider. */
.is-style-twg-ruled {
	padding-bottom: 0.55rem;
	border-bottom: 3px solid var(--wp--preset--color--rust);
	margin-bottom: var(--wp--preset--spacing--40);
}

/* Artwork: contained, never cropped, and never framed. A border round a
   cut-out or a transparent PNG draws a box around nothing. */
.wp-block-image.is-style-twg-contain img {
	object-fit: contain;
	width: 100%;
	height: auto;
	background: transparent;
	border: 0;
}

/* The card frame. Carries its own text colour, because a card sits on Abyss
   AND on beige, and without this the copy inherits the section's colour and
   disappears the moment the card lands on the beige ground. */
.wp-block-group.is-style-twg-card {
	background-color: var(--wp--preset--color--abyss);
	color: var(--wp--preset--color--beige);
	border: 1px solid var(--wp--preset--color--rust);
	border-radius: 15px;
	padding: var(--wp--preset--spacing--30);
}
/* ---------------------------------------------------------------------------
   THE CARD'S INK. READ THE COMMENT BEFORE CHANGING THE SELECTOR.

   14 August. Gord on their phone: "the tiles that we've got where the section
   background is beige but the tile background is abyss, the text seems to also
   be abyss which means that it's not legible to people." Measured on the home
   page: contrast 1.00. The text was exactly the colour of the box.

   THE CARD WAS ALWAYS DECLARING THE RIGHT INK. IT WAS LOSING.

   `:where()` contributes ZERO specificity, so the old rule below weighed only
   what `.wp-block-group.is-style-twg-card` weighs, 0-2-0. The rule beating it
   is core's own:

     .has-beige-background-color :where(p, li, blockquote, dd, dt, figcaption)
       :not([class*="has-"][class*="-color"])

   which looks weaker and is not, because `:not()` DOES take the specificity of
   its argument, and `[class*="has-"][class*="-color"]` is two attribute
   selectors. So that rule weighs 0-3-0 and wins every time a card sits inside a
   beige section. Which is most of them.

   THIS IS THE SECOND TIME THIS EXACT TRAP HAS BEEN HIT. On 6 August it turned
   all ten /blog/ card titles invisible and the fix that went in covered LINKS
   ONLY, which is why body text was still doing it eight days later on tiles,
   spread pages, the testimonials archive and the book sections. Same rule, same
   failure, four more places.

   So: `:is()` instead of `:where()`, and the same `:not()` on our side, giving
   0-4-0. It beats core, and it still steps aside for any element that has been
   given an explicit colour class in the editor.

   HEADINGS STAY RUST. Rust on the card's abyss ground is 4.9:1 and fine. The
   ink question for headings on LIGHT grounds is handled by --twg-heading-ink
   further down, which a card re-declares so a card inside a beige section keeps
   its rust rather than taking beige's answer.
--------------------------------------------------------------------------- */
.wp-block-group.is-style-twg-card :is(p, li, blockquote, dd, dt, figcaption, cite):not([class*="has-"][class*="-color"]) {
	color: var(--wp--preset--color--beige);
}
.edd-blocks__download.edd-blocks__download :is(p, li, blockquote, dd, dt, figcaption, cite):not([class*="has-"][class*="-color"]) {
	color: var(--wp--preset--color--beige);
}
.wp-block-group.is-style-twg-card :where(h1, h2, h3, h4, h5, h6) {
	color: var(--wp--preset--color--rust);
}

/* Buttons on a phone: one per line, same width, label centred. Left to size
   themselves they step down the page in a ragged staircase. */
@media (max-width: 781px) {
	.wp-block-buttons { flex-direction: column; align-items: stretch; }
	.wp-block-buttons > .wp-block-button { width: 100%; }
	.wp-block-button__link { width: 100%; text-align: center; }
}

/* ---------------------------------------------------------------------------
   BUTTONS

   theme.json's generated CSS is not specific enough to win against core's own
   button rules on every surface, so the spec is restated here. Nothing in this
   file targets Otter: the pages are rebuilt off Otter's markup, not propped up
   with a stylesheet that reimplements it.
--------------------------------------------------------------------------- */
.wp-block-button .wp-block-button__link,
.entry-content .wp-block-button__link,
a.wp-element-button {
	background-color: var(--wp--preset--color--rust);
	border: 3px solid var(--wp--preset--color--abyss);
	border-radius: 30px;
	color: var(--wp--preset--color--abyss);
	padding: 12px 22px;
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 900;
	font-size: 0.95rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	line-height: 1.15;
	text-decoration: none;
}
.wp-block-button .wp-block-button__link:hover,
.entry-content .wp-block-button__link:hover,
a.wp-element-button:hover {
	background-color: var(--wp--preset--color--copper);
	border-color: var(--wp--preset--color--abyss);
	color: var(--wp--preset--color--abyss);
}

/* The outline variant, including Otter's own is-style-outline, is defined in
   full under "THE OUTLINE BUTTON STANDS ON ITS OWN GROUND" further down. It
   used to be restated here as transparent-with-rust, which is the pair of rules
   that stopped the editor's own background colour from ever taking effect. */


/* ---------------------------------------------------------------------------
   PATTERN SUPPORT
--------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   POSTER HEADLINE

   The hero itself is built in the block editor with core blocks, so it is
   Gord's to change. The only thing CSS has to do is the outlined lettering,
   which no core block can express. It is a named block style, so it is a
   choice on any heading rather than something welded to one section.
--------------------------------------------------------------------------- */
.is-style-twg-poster-title{
	line-height: 0.88;
	letter-spacing: -0.05em;
	/* 7px to 9px on Gord's ask, 3 August: with the veil off the heading has to
	   carry itself over the photograph, and 7px was not quite holding it. */
	-webkit-text-stroke: 9px var(--wp--preset--color--abyss);
	paint-order: stroke fill;
}

@media (max-width: 900px){
	.is-style-twg-poster-title{
		-webkit-text-stroke: 5px var(--wp--preset--color--abyss);
	}
}

/* Card tiles in a row share a height, so a row reads as a row rather than a
   ragged staircase, and the buttons line up along the bottom. */
.wp-block-columns > .wp-block-column > .wp-block-group.is-style-twg-card,
.wp-block-group.is-layout-grid > .wp-block-group.is-style-twg-card {
	height: 100%;
	display: flex;
	flex-direction: column;
}
/* Tile artwork stays a sensible size instead of swallowing the card. */
.wp-block-group.is-style-twg-card > .wp-block-image img { max-height: 190px; width: auto; margin-inline: auto; }
.wp-block-group.is-style-twg-card > .wp-block-buttons { margin-top: auto; }

/* ---------------------------------------------------------------------------
   FOOTER
--------------------------------------------------------------------------- */
.twg-footer-list{ list-style: none; padding-left: 0; margin: 0; }
.twg-footer-list li{ margin-bottom: 0.5rem; line-height: 1.35; }
.twg-footer-list a{ text-decoration: none; }
.twg-footer-list a:hover{ text-decoration: underline; }
.twg-footer-legal{ padding-top: var(--wp--preset--spacing--10); }
.twg-footer-legal p{ margin: 0; }
.twg-footer-legal a{ text-decoration: none; }

/* ---------------------------------------------------------------------------
   ONE FAQ, DRAWN ONE WAY, AND THE ONE WAY IS THE LIST

   ⛔ READ THIS BEFORE CHANGING ANYTHING BELOW. I GOT IT BACKWARDS ONCE ALREADY.

   14 August. Gord: "FAQ sections still seem to not be consistent at all between
   pages and post types... I've seen about three different versions." Right, and
   the cause is two implementations rather than two designs: TWG Core prints
   `twg_ui_disclosure()`, and some pages carry core's own Details block saved into
   their content.

   I first read "inconsistent" as "make them all the card" and turned both into
   bordered abyss panels. Gord, on seeing it: "the FAQs all look wrong now... none
   of these look like the one that I liked."

   ➡️ THE ONE GORD LIKES IS THE LIST, and it is the treatment this file already
   had: no panel, no border box, a hairline between each question, the question
   in Raleway 900 reading dark on the beige band, and a rust plus on the right
   that becomes a minus when it opens.

   ➡️ SO BOTH IMPLEMENTATIONS ARE DRAWN AS THE LIST. TWG Core paints its own card
   ground on `.twg-disclosure`, so that is explicitly unpainted here. The two
   selectors are kept side by side on every rule on purpose: a rule that lands on
   one and not the other is exactly how three looks happened.
--------------------------------------------------------------------------- */
.wp-block-details,
.twg-disclosures .twg-disclosure{
	background: none;
	border: 0;
	border-top: 1px solid rgba(184, 124, 0, 0.35);
	border-radius: 0;
	padding: var(--wp--preset--spacing--10) 0;
	margin: 0;
	overflow: visible;
	color: inherit;
}
.wp-block-details:last-of-type,
.twg-disclosures .twg-disclosure:last-of-type{
	border-bottom: 1px solid rgba(184, 124, 0, 0.35);
}
.twg-disclosures{ display: block; }

.wp-block-details > summary,
.twg-disclosures .twg-disclosure > .twg-disclosure__summary{
	list-style: none;
	cursor: pointer;
	display: block;
	background: none;
	padding: 0 2.5rem 0 0;
	position: relative;
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 900;
	font-size: 1.2rem;
	line-height: 1.3;
	color: var(--wp--preset--color--rust);
}
.wp-block-details > summary::-webkit-details-marker,
.twg-disclosures .twg-disclosure > .twg-disclosure__summary::-webkit-details-marker{ display: none; }
.wp-block-details > summary::marker,
.twg-disclosures .twg-disclosure > .twg-disclosure__summary::marker{ content: ""; }

/* The question inside the component sits in a heading. It takes the summary's
   type rather than a size of its own, so the two are the same line. */
.twg-disclosures .twg-disclosure .twg-disclosure__h{
	font-family: inherit;
	font-weight: inherit;
	font-size: inherit;
	line-height: inherit;
	color: inherit;
	margin: 0;
}

/* ⛔ THE MARKER IS A PLUS AND NOTHING ELSE. TWG Core draws a chevron on this
   same spot out of two borders and a rotate. Both were landing at once, so a
   phone showed a rotated corner with a plus inside it, which is the odd glyph
   Gord photographed on 14 August. The borders, the box and the rotate are
   explicitly cancelled here so whichever order the two files load in, one
   marker comes out. Do not remove these four resets. */
.wp-block-details > summary::after,
.twg-disclosures .twg-disclosure > .twg-disclosure__summary::after{
	content: "+";
	position: absolute;
	right: 0;
	top: 50%;
	width: auto;
	height: auto;
	border: 0;
	transform: translateY(-50%);
	font-size: 1.6rem;
	line-height: 1;
	color: var(--wp--preset--color--rust);
}
.wp-block-details[open] > summary::after,
.twg-disclosures .twg-disclosure[open] > .twg-disclosure__summary::after{
	content: "\2013";
	border: 0;
	transform: translateY(-50%);
}
.wp-block-details[open] > summary,
.twg-disclosures .twg-disclosure[open] > .twg-disclosure__summary{ margin-bottom: var(--wp--preset--spacing--10); }

/* The answer. No card padding, because there is no card. */
.wp-block-details > :not(summary),
.twg-disclosures .twg-disclosure .twg-disclosure__body{
	padding: 0;
	color: inherit;
}

/* THE INK, AND IT FOLLOWS THE BAND NOW BECAUSE THE FAQ NO LONGER PAINTS ITS OWN
   GROUND. On the beige bands these sit on, rust measures about 2.2 to 1, so the
   question reads abyss and only the plus stays rust. */
.has-beige-background-color .wp-block-details > summary,
.has-beige-background-color .twg-disclosures .twg-disclosure > .twg-disclosure__summary,
.has-beige-background-color .twg-disclosures .twg-disclosure .twg-disclosure__h{
	color: var(--wp--preset--color--abyss);
}

/* The logo. Served from the Optimole CDN, because staging's own uploads folder
   is missing the file. */
.twg-logo{ margin: 0; }
.twg-logo img{ display: block; height: auto; max-width: 200px; }
@media (max-width: 600px){ .twg-logo img{ max-width: 150px; } }

/* ---------------------------------------------------------------------------
   THE ONE-WORD MENU

   The trigger is the word MENU, not a hamburger. Core will render an icon
   unless hasIcon is false, and the label inherits the body colour, so both
   have to be set.
--------------------------------------------------------------------------- */
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-open:not(.has-text-color){
	font-family: var(--wp--preset--font-family--raleway) !important;
	font-weight: 900 !important;
	font-size: 0.95rem !important;
	text-transform: uppercase;
	letter-spacing: 0.2em;
	color: var(--wp--preset--color--rust) !important;
	fill: var(--wp--preset--color--rust);
	background: transparent;
	padding: 0;
}
.wp-block-navigation__responsive-container-open::after{
	content: "";
	display: block;
	height: 3px;
	margin-top: 0.35rem;
	background: var(--wp--preset--color--rust);
}
.wp-block-navigation__responsive-container-open:hover,
.wp-block-navigation__responsive-container-open:hover::after{
	color: var(--wp--preset--color--copper) !important;
	background-color: var(--wp--preset--color--copper);
}
.wp-block-navigation__responsive-container-open:hover{ background: transparent; }
.wp-block-navigation__responsive-container-close{
	color: var(--wp--preset--color--rust) !important;
	fill: var(--wp--preset--color--rust);
}

/* ---------------------------------------------------------------------------
   THE VEIL

   A colour wash between a group's background image and its contents. Core
   gives Cover an overlay but not Group, and a section with a photograph behind
   the copy needs one or the text stops being readable, particularly on a phone
   where the image sits directly under the words.

   Strength is chosen in Styles (Veil 25/40/60/80). Colour is chosen with the
   group's ordinary Background colour picker, so any palette colour works.
   With no colour set it falls back to Abyss.
--------------------------------------------------------------------------- */
[class*="is-style-twg-veil"],
.twg-veil{
	position: relative;
	isolation: isolate;
	--twg-veil-color: var(--twg-ground, var(--wp--preset--color--abyss));
}
[class*="is-style-twg-veil"]::before,
.twg-veil::before{
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background-color: var(--twg-veil-color);
}
[class*="is-style-twg-veil"] > *,
.twg-veil > *{
	position: relative;
	z-index: 1;
}

/* Colour, taken from the group's own background colour. */
[class*="is-style-twg-veil"].has-beige-background-color{ --twg-veil-color: var(--wp--preset--color--beige); }
[class*="is-style-twg-veil"].has-rust-background-color{ --twg-veil-color: var(--wp--preset--color--rust); }
[class*="is-style-twg-veil"].has-copper-background-color{ --twg-veil-color: var(--wp--preset--color--copper); }
[class*="is-style-twg-veil"].has-abyss-background-color{ --twg-veil-color: var(--wp--preset--color--abyss); }

/* Strength. */
/* Strength is held in a custom property rather than written straight into the
   opacity, because the entrance below has to animate FROM nothing TO whichever
   strength is picked, and keyframes cannot read a value out of another rule.
   With the property, one set of keyframes serves every strength. */
.is-style-twg-veil-25{ --twg-veil-strength: 0.25; }
.is-style-twg-veil-30{ --twg-veil-strength: 0.30; }
.is-style-twg-veil-40{ --twg-veil-strength: 0.40; }
.is-style-twg-veil-60{ --twg-veil-strength: 0.60; }
.is-style-twg-veil-80{ --twg-veil-strength: 0.80; }

[class*="is-style-twg-veil"]::before,
/* THE MOBILE VALUE FALLS BACK TO THE DESKTOP ONE, AND THAT NESTED FALLBACK IS
   THE WHOLE MECHANISM. Gord, 3 August, asked for the veil to be settable
   separately on a phone, and chose "blank means the same as desktop" over two
   independent numbers. `var(--a, var(--b, default))` says exactly that in CSS,
   so there is no JavaScript deciding it and no value written onto a section
   until somebody deliberately moves the mobile slider. Every existing page
   therefore behaves identically to before this shipped. */
/* THE DEFAULT IS 0, NOT 0.25, AND CHANGING IT FIXED A REAL FAULT.
   The `twg-veil` class is written by the sliders, and the mobile slider writes
   it on its own. So a section with a veil on a phone and none on desktop
   carried the class with no desktop value on it, fell through to this default,
   and kept a quarter-strength veil on desktop that nothing in the editor could
   turn off. Gord hit exactly that on the home page hero on 4 August, turned the
   veil off, and it stayed on.
   A missing value now means what it says: none. Nothing is lost, because the
   named Veil block styles above all set their own strength, and the slider now
   always writes an explicit number when one has been chosen. */
.twg-veil::before{ opacity: var(--twg-veil-strength, 0); }

@media (max-width: 781px){
	.twg-veil::before{
		opacity: var(--twg-veil-strength-mobile, var(--twg-veil-strength, 0));
	}
}

/* On a phone the veil deepens over the bottom third.

   The buttons sit at the foot of the section, right over the busiest part of
   the photograph, and a flat veil strong enough to carry them makes the whole
   picture muddy. This adds a second layer, masked so it is invisible until 70%
   down and then ramps in, taking roughly a 60% veil to 80% at the very bottom.
   Desktop is left alone: the copy and the picture sit side by side there, so
   there is nothing to rescue. */
@media (max-width: 781px){
	[class*="is-style-twg-veil"]::after,
	.twg-veil::after{
		content: "";
		position: absolute;
		inset: 0;
		z-index: 0;
		pointer-events: none;
		background-color: var(--twg-veil-color);
		opacity: 0.5;
		-webkit-mask-image: linear-gradient(to bottom, transparent 70%, #000 100%);
		mask-image: linear-gradient(to bottom, transparent 70%, #000 100%);
	}
}

/* ---------------------------------------------------------------------------
   A VEIL THAT FADES OFF THE PHOTOGRAPH

   The flat veil solves legibility and costs the picture. Gord, 3 August: with
   the veil off "the picture pops" but the copy cannot be read; with it on the
   copy reads but "the image just looks dull". Both are true, because the veil
   covers the whole band including the part with nothing on it.

   On desktop the copy sits left and the photograph sits bottom right, so the
   veil only has work to do on the left. This masks it: full strength across the
   copy, gone by the time it reaches the figure. The picture is then untouched.

   PLAIN UTILITY CLASS, NOT A BLOCK STYLE, and deliberately so. Block styles are
   pick-one-only in the editor and this section already uses a Veil style, so a
   fading veil as a style would mean choosing between strength and fade. As a
   class it combines with any of them. Add it under
   Advanced > Additional CSS classes:  twg-veil-fade

   Mobile is left exactly as it was. There the copy sits over the picture with
   nowhere else to go, so there is nothing to fade towards, and the bottom ramp
   above is already doing the real work.
--------------------------------------------------------------------------- */
@media (min-width: 782px){
	[class*="is-style-twg-veil"].twg-veil-fade::before,
	.twg-veil.twg-veil-fade::before{
		-webkit-mask-image: linear-gradient(to right, #000 0%, #000 38%, transparent 72%);
		mask-image: linear-gradient(to right, #000 0%, #000 38%, transparent 72%);
	}
}

/* ---------------------------------------------------------------------------
   WHAT COLOUR IS THE GROUND, AND WHAT COLOUR GOES ON IT

   Gord, 3 August: "this needs to just be a standing rule everywhere." Never
   beige lettering on rust or copper. Abyss on rust, Abyss on copper. Rust is
   fine on beige and on Abyss.

   Two inherited custom properties carry it. A section states its ground once,
   and everything nested inside can read it without knowing where it sits, which
   is the whole point: a button three blocks deep cannot otherwise tell whether
   it is standing on beige or on rust.

   --twg-ground     the colour the section is actually sitting on
   --twg-ink        the only colour allowed to be drawn on that ground
   --twg-ink-hover  what that ink becomes on hover

   Custom properties inherit, so this is set once on the section and reaches
   every descendant. The default pair is the body's own: Abyss ground, rust ink.

   WHY THERE IS A HOVER INK AT ALL, added 4 August. Gord's button specification
   of 30 July says the outline variant hovers by turning its border and its
   lettering COPPER, and the theme never did it: hover only deepened the ground
   and said so in a comment. That is half a hover, and the outline button is the
   one every jump pill row now ends on, so it is on 140 pages.

   It is a separate property rather than a hardcoded copper because the pairing
   rule outranks it. Rust ink goes copper on hover, which is Gord's spec and the
   direction of travel they asked for. ABYSS ink stays abyss, because abyss ink
   only ever appears on a rust or copper ground, and copper lettering on a rust
   ground is the sort of thing the pairing rule exists to stop. Both instructions
   are Gord's, and this is the one place they meet.
--------------------------------------------------------------------------- */
body{
	--twg-ground: var(--wp--preset--color--abyss);
	--twg-ink: var(--wp--preset--color--rust);
	--twg-ink-hover: var(--wp--preset--color--copper);
}
.has-abyss-background-color{
	--twg-ground: var(--wp--preset--color--abyss);
	--twg-ink: var(--wp--preset--color--rust);
	--twg-ink-hover: var(--wp--preset--color--copper);
}
.has-beige-background-color{
	--twg-ground: var(--wp--preset--color--beige);
	--twg-ink: var(--wp--preset--color--rust);
	--twg-ink-hover: var(--wp--preset--color--copper);
}
/* Rust and copper are the two that had to be named. Rust lettering on a rust
   ground is invisible and beige lettering on either is the thing Gord ruled
   out, so both grounds take Abyss. And abyss ink does not go copper on hover,
   for the reason in the block comment above. */
.has-rust-background-color{
	--twg-ground: var(--wp--preset--color--rust);
	--twg-ink: var(--wp--preset--color--abyss);
	--twg-ink-hover: var(--wp--preset--color--abyss);
}
.has-copper-background-color{
	--twg-ground: var(--wp--preset--color--copper);
	--twg-ink: var(--wp--preset--color--abyss);
	--twg-ink-hover: var(--wp--preset--color--abyss);
}

/* ---------------------------------------------------------------------------
   THE OUTLINE BUTTON STANDS ON ITS OWN GROUND

   It used to be forced transparent, which is why picking a background colour
   for it in the editor did nothing at all. Over a flat section that was fine.
   Over a photograph it was not: the lettering fought whatever happened to be
   behind it.

   So it now carries the section's own ground colour, knocked back a quarter so
   the picture still shows through and the button reads as a panel rather than a
   solid block. Border and lettering take the ink for that ground, so the rule
   above is enforced here rather than remembered.

   color-mix keeps it to one declaration per state and means a new palette
   colour never needs a matching rgba() written by hand.
--------------------------------------------------------------------------- */
/* A FAINT TINT, NOT A PANEL. Gord, 3 August: 25% means 25% of the colour is
   there and the rest is the picture. It is enough to stop the lettering fighting
   whatever is behind it and little enough that it does not read as a filled
   button when there is no picture behind it at all.

   The strength is a slider in the editor (see "Background opacity" in the
   Tarot with Gord panel). 25% is only the starting point.

   Core writes preset background classes with !important, so matching it is the
   only way to knock one back; without it the button stays flat. */
/* ⚠️ THIS RULE WAS DEAD AND NOBODY HAD NOTICED. The selector list ended with a
   COMMA instead of an opening brace, so the browser threw the whole block away
   and skipped to the next `}`. Every outline button on the site has therefore
   been rendering with none of the three declarations below: no 25% ground, no
   3px border, no ink colour. Found on 5 August by counting the braces in this
   file, which came out at 164 open against 166 closed.

   FIXING THE TYPO MAKES THE OUTLINE BUTTONS CHANGE VISIBLY, because they are
   about to start doing what this rule always said they should. That is the
   intended behaviour and not a new design decision: `ui-components.md` section 3
   specifies it and the comment above has described it all along. It is flagged
   to Gord rather than slipped in, because it is the kind of change that looks
   like somebody restyled the buttons when in fact somebody unbroke them. */
.wp-block-button.is-style-outline > .wp-block-button__link,
.wp-block-button.is-style-twg-outline > .wp-block-button__link{
	/* GORD, 5 August 2026, seeing it on the card tiles for the first time:
	   "why is there a fucking light backgound it needs to be transparent",
	   then: "It should only do that if it's a button that's on top of an image."

	   So the resting outline button is TRANSPARENT everywhere, and the knock-back
	   comes back only where it earns its keep: over a picture, where a bare
	   outline can land on any colour and stop being readable. The rule for that
	   is below. The 25% everywhere was the theme's own idea, never Gord's, and it
	   only became visible on 5 August when the dead rule was unbroken. */
	background-color: transparent !important;
	border: 3px solid var(--twg-ink);
	color: var(--twg-ink);
}

/* THE ONE PLACE AN OUTLINE BUTTON KEEPS A GROUND: on top of a picture.
   Gord, 5 August: "It should only do that if it's a button that's on top of an
   image." A cover block always has a picture or a colour behind it, and
   `twg-on-image` is the hook for anywhere else a button sits over artwork.
   Nothing else on the site gets a ground on a resting outline button. */
.wp-block-cover .wp-block-button.is-style-outline > .wp-block-button__link,
.wp-block-cover .wp-block-button.is-style-twg-outline > .wp-block-button__link,
.twg-on-image .wp-block-button.is-style-outline > .wp-block-button__link,
.twg-on-image .wp-block-button.is-style-twg-outline > .wp-block-button__link{
	background-color: color-mix(in srgb,
		var(--twg-ground) calc(var(--twg-bg-opacity, 0.25) * 100%),
		transparent) !important;
}

/* THE HOVER, PUT BACK TO GORD'S SPECIFICATION, 4 August.
   Gord, 30 July, on the outline variant: "border and text both go copper". The
   theme only ever deepened the ground and carried a comment explaining that it
   deliberately did not change the lettering, which was the wrong half of the
   rule to keep. Both now happen: the ground still deepens, AND the border and
   the lettering take the hover ink.

   On an Abyss or beige ground that hover ink is copper, which is the spec. On a
   rust or copper ground it stays abyss, because the pairing rule outranks it.
   See the block comment where the properties are defined.

   The duplicated selector pair that used to sit above this rule, with its own
   contradictory comment, is deleted: it was the same two selectors listed twice
   and only the second list did anything. */
/* ⚠️ AND THIS ONE WAS DEAD TOO, THE SAME WAY: a comma where the opening brace
   should be. So the hover that was "put back to Gord's specification" on
   4 August has never once fired. The comment above describes behaviour the
   browser was throwing away, which is exactly why nobody caught it by reading
   the file. Both of these were found together on 5 August by counting braces. */
.wp-block-button.is-style-outline > .wp-block-button__link:hover,
.wp-block-button.is-style-outline > .wp-block-button__link:focus,
.wp-block-button.is-style-twg-outline > .wp-block-button__link:hover,
.wp-block-button.is-style-twg-outline > .wp-block-button__link:focus{
	background-color: color-mix(in srgb,
		var(--twg-ground) calc(var(--twg-bg-opacity, 0.08) * 190%),
		transparent) !important;
	border-color: var(--twg-ink-hover, var(--twg-ink));
	color: var(--twg-ink-hover, var(--twg-ink));
}

/* Picking a background colour on the button itself still works: the palette
   classes below set --twg-ground, so the colour chosen in the editor is the one
   that gets knocked back. */
.wp-block-button__link.has-abyss-background-color{ --twg-ground: var(--wp--preset--color--abyss); --twg-ink: var(--wp--preset--color--rust); }
.wp-block-button__link.has-beige-background-color{ --twg-ground: var(--wp--preset--color--beige); --twg-ink: var(--wp--preset--color--rust); }
.wp-block-button__link.has-rust-background-color{ --twg-ground: var(--wp--preset--color--rust); --twg-ink: var(--wp--preset--color--abyss); }
.wp-block-button__link.has-copper-background-color{ --twg-ground: var(--wp--preset--color--copper); --twg-ink: var(--wp--preset--color--abyss); }

/* ---------------------------------------------------------------------------
   BACKGROUND OPACITY ON ANYTHING, NOT JUST BUTTONS

   Gord, 3 August: "on any fucking thing where I'm setting a colour, just let me
   change the transparency." The slider sets --twg-bg-opacity and adds this
   class; the rest is arithmetic.

   The colour is read back off the block's own background rather than guessed,
   so this works with the palette AND with a one-off custom colour. !important
   matches core, which writes preset background classes that way.
--------------------------------------------------------------------------- */
.twg-bg-opacity{
	background-color: color-mix(in srgb,
		var(--twg-bg-colour, var(--twg-ground))
		calc(var(--twg-bg-opacity, 1) * 100%),
		transparent) !important;
}
.twg-bg-opacity.has-abyss-background-color{ --twg-bg-colour: var(--wp--preset--color--abyss); }
.twg-bg-opacity.has-beige-background-color{ --twg-bg-colour: var(--wp--preset--color--beige); }
.twg-bg-opacity.has-rust-background-color{ --twg-bg-colour: var(--wp--preset--color--rust); }
.twg-bg-opacity.has-copper-background-color{ --twg-bg-colour: var(--wp--preset--color--copper); }

/* A button carries the class on its wrapper, because that is the element the
   editor writes attributes to, but the colour lives on the link inside it.
   The custom property inherits down, so only the target needs naming. */
.twg-bg-opacity.wp-block-button{
	background-color: transparent !important;
}

/* ---------------------------------------------------------------------------
   THE ENTRANCE: PICTURE FIRST, THEN THE VEIL AND THE WORDS

   Gord, 3 August: the image should load on its own with no veil over it, and
   the veil and the text should arrive a little afterwards.

   PLAIN UTILITY CLASS, NOT A BLOCK STYLE, for the same reason twg-veil-fade is
   one: the section already spends its single block style on the veil strength.
   Add it under Advanced > Additional CSS classes:  twg-reveal

   Nothing here hides anything from a search engine or a screen reader. It is
   opacity and nothing else, the text is in the markup from the first byte, and
   the animation runs forwards only, so a browser that ignores it shows the
   finished section rather than an empty one.
   FOUR BEATS, NOT TWO. Gord, 3 August: the first version put the picture up and
   then everything else half a second later, and it read as text loading slowly
   rather than as a deliberate entrance. Their sequence, in their words: "Just
   the picture. The heading. The rest", with "the line can kind of come with the
   heading" and the buttons folding out from one another.

   So:
     beat 1   the photograph, alone, on its own for a proper moment
     beat 2   the veil, the heading and the rule under it, together
     beat 3   the body copy
     beat 4   the buttons, each one folding out after the one before

   Every delay is derived from one number, --twg-beat, so the whole thing can be
   sped up or slowed down in one place rather than by editing eight values that
   then disagree with each other.
--------------------------------------------------------------------------- */
.twg-reveal{
	--twg-beat: 0.42s;
}

/* ---------------------------------------------------------------------------
   BEAT 1: THERE IS NO LONGER A BEAT 1. THE PICTURE DOES NOT MOVE.

   Gord, 4 August, on the new hero photograph: "we don't need the zoom animation
   now". So the whole `twg-hero-approach` keyframe and the rule that ran it are
   gone rather than switched off, because a keyframe nothing uses is a thing the
   next person has to work out.

   REMOVING IT ALSO FIXED THE TILING, AND THAT IS WORTH UNDERSTANDING BEFORE
   ANYBODY PUTS IT BACK. The animation ran with `animation-fill-mode: both`,
   which meant its end state OUTRANKED the inline background the editor writes.
   The section is set to `cover` at `81% 28%` on the page; the animation forced
   `auto 100%` at `100% 100%` over the top of it. `auto 100%` sizes the picture
   to the height of the band, which on a wide screen is narrower than the band,
   and the rest of the band was filled by a second cut-off copy of the same
   photograph down the left edge. Measured on staging on 4 August, and visible in
   a screenshot as a second Gord in a second chair.

   So the hero's size and position now come from the block's own background
   controls in the editor, like every other section on the site. That is the rule
   in `decisions.md`: page layout is editor content, not theme CSS. Nothing here
   overrides it any more, and a hero that looks wrong is now fixed on the page
   rather than in this file.

   The staged arrival of the WORDS below is untouched. Gord asked for the zoom to
   go, not the entrance.
--------------------------------------------------------------------------- */

@keyframes twg-veil-in{
	from{ opacity: 0; }
	to{ opacity: var(--twg-veil-strength, 0); }
}
@keyframes twg-copy-in{
	from{ opacity: 0; transform: translateY(0.75rem); }
	to{ opacity: 1; transform: none; }
}
/* The buttons hinge down from their top edge rather than sliding, which is what
   makes three of them in a row read as folding out of one another. */
@keyframes twg-fold-in{
	from{ opacity: 0; transform: perspective(800px) rotateX(-72deg); }
	to{ opacity: 1; transform: perspective(800px) rotateX(0); }
}

/* Beat 2: the veil. */
/* THE VEIL ARRIVES AFTER THE WORDS, NOT WITH THEM.
   14 August. Gord: "the hero image needs to display without any mask on it,
   without any overlay on it, so that all of the overlays are completely
   transparent until the text appears and then it should go a bit darker."
   It was on beat 2, the same beat as the H1, so the picture was already being
   dimmed at the moment it was supposed to be clean. The heading lands around
   beat 3.4, so the veil now starts at 3 and takes longer to arrive, which puts
   the darkening under the copy rather than ahead of it. */
.twg-reveal::before{
	animation: twg-veil-in 1.1s ease-out calc(var(--twg-beat) * 3) backwards;
}

/* On a phone the veil animates to the MOBILE strength, or to the desktop one if
   no mobile value has been set. A SEPARATE keyframe name rather than redefining
   `twg-veil-in` inside the media query: redefining a name does work, because the
   last matching definition wins, but a keyframe that quietly means two different
   things depending on viewport is the kind of thing nobody finds at 2am.

   Without this the veil would animate to the DESKTOP value and then snap to the
   mobile one the instant the animation finished, because the animation fills
   backwards only and the static rule takes over at the end. */
@media (max-width: 781px){
	@keyframes twg-veil-in-mobile{
		from{ opacity: 0; }
		to{ opacity: var(--twg-veil-strength-mobile, var(--twg-veil-strength, 0)); }
	}
	.twg-reveal::before{
		animation-name: twg-veil-in-mobile;
	}
}
/* The bottom-third ramp on a phone travels with the veil, otherwise the section
   arrives half veiled. Its strength is fixed at 0.5, so it gets its own pair. */
@media (max-width: 781px){
	@keyframes twg-veil-ramp-in{
		from{ opacity: 0; }
		to{ opacity: 0.5; }
	}
	.twg-reveal::after{
		animation: twg-veil-ramp-in 1.1s ease-out calc(var(--twg-beat) * 3) backwards;
	}
}

/* Beat 2, with the veil: the heading and its rule.
   Targeted at the elements themselves rather than at the section's direct
   children, because the heading sits two levels down inside a Columns block and
   animating the wrapper would bring the whole lot in at once, which is exactly
   the fault being fixed. */
.twg-reveal :is(h1, h2, .wp-block-separator){
	animation: twg-copy-in 0.6s ease-out calc(var(--twg-beat) * 2) backwards;
}

/* Beat 3: the rest of the words. */
.twg-reveal :is(p, ul, ol){
	animation: twg-copy-in 0.6s ease-out calc(var(--twg-beat) * 3.2) backwards;
}

/* Beat 4: the buttons, one after another. */
.twg-reveal .wp-block-button{
	transform-origin: 50% 0;
	animation: twg-fold-in 0.55s cubic-bezier(0.2, 0.8, 0.3, 1)
	           calc(var(--twg-beat) * 4.4) backwards;
}
.twg-reveal .wp-block-button:nth-child(2){ animation-delay: calc(var(--twg-beat) * 4.8); }
.twg-reveal .wp-block-button:nth-child(3){ animation-delay: calc(var(--twg-beat) * 5.2); }
.twg-reveal .wp-block-button:nth-child(4){ animation-delay: calc(var(--twg-beat) * 5.6); }
.twg-reveal .wp-block-button:nth-child(n+5){ animation-delay: calc(var(--twg-beat) * 6); }

/* A button already inside a paragraph-level beat must not inherit that too. */
.twg-reveal .wp-block-button p{
	animation: none;
}

/* Anyone who has asked for less movement gets the finished section immediately.
   Not a shorter animation, none. */
@media (prefers-reduced-motion: reduce){
	.twg-reveal::before,
	.twg-reveal::after,
	.twg-reveal :is(h1, h2, .wp-block-separator, p, ul, ol),
	.twg-reveal .wp-block-button{
		animation: none;
	}
}

/* ---------------------------------------------------------------------------
   COPY THAT READS WITHOUT A VEIL AT ALL

   The other half of the same problem. The poster heading already carries an
   outline, which is why it reads over anything. Body copy cannot use the same
   trick: a stroke that thick closes up small letterforms and makes them harder
   to read, not easier.

   A soft halo in the background colour does the same job at paragraph size. It
   sits tight to the letters, so from any distance it is invisible, and it lifts
   the text off whatever is behind it.

   A named block style, so it is a choice on any paragraph in the editor rather
   than something welded to the hero. Styles > Legible over a photo.
--------------------------------------------------------------------------- */
.is-style-twg-legible{
	text-shadow:
		0 0 4px var(--wp--preset--color--abyss),
		0 0 8px var(--wp--preset--color--abyss),
		0 1px 2px var(--wp--preset--color--abyss);
}

/* ---------------------------------------------------------------------------
   BANDED SECTIONS BUTT TOGETHER

   The page is built as full-width colour bands. WordPress puts its block gap
   between top level blocks, which leaves a stripe of the body's Abyss showing
   between one band and the next, and any background image in a band then
   stops short of the band below it. Bands own their own padding, so the gap
   between them is always wrong.
--------------------------------------------------------------------------- */
.wp-block-post-content > .alignfull,
.entry-content > .alignfull{
	margin-block-start: 0;
	margin-block-end: 0;
}

/* AND THE SAME GAP EXISTS ONE LEVEL UP, BETWEEN THE HEADER AND THE PAGE.
   Measured on staging, 4 August, after Gord pointed at a strip of bare page
   colour under the header rule: the header's own box ends at 158 and `main`
   starts at 178. `main` is a top level child of `.wp-site-blocks`, so WordPress
   gives it the 20px block gap, and because the header is sticky and dark and
   the hero underneath it is a photograph, that 20px reads as a seam across the
   top of the site rather than as spacing.
   The rule above only covers blocks INSIDE the content, which is why this was
   never caught by it. Bands own their own padding, so nothing here should ever
   be separated by a gap. */
.wp-site-blocks > main{
	margin-block-start: 0;
}

/* ---------------------------------------------------------------------------
   HERO BACKGROUND ON A PHONE

   THE FORCED SIZE AND POSITION ARE GONE, 4 August, and it is worth knowing why
   because they were right when they were written.

   They were `background-size: auto 100%` and `background-position: center
   bottom`, and they existed because the old hero photograph was a CENTRED
   2000x2000 square: sizing it to the width made it a strip along the bottom of
   the band, and centring it put Gord in the middle of the frame, which is where
   he was in that picture.

   Neither is true of the photograph Gord took on 4 August. He is well right of
   centre in it, so `center` showed a tall slice of empty wall with an elbow and
   a boot entering from the right edge, and nothing else. Gord sent a screenshot
   of exactly that. On a band this tall `auto 100%` and `cover` resolve to the
   same scale anyway, so the size half of the rule was doing nothing and only the
   centring was doing harm.

   So the phone now uses the block's own background position from the editor,
   the same as every other width. One place to change it, with a drag handle,
   and Gord does not need anybody to edit a stylesheet to move his own face.

   The padding below stays: it is a different thing that Gord asked for
   separately, and it is about the copy, not the picture.

   The class is still a plain utility class rather than a block style, because
   block styles are pick-one-only in the editor. Advanced > Additional CSS
   classes: twg-fill-mobile
--------------------------------------------------------------------------- */
@media (max-width: 781px){
	/* Room to breathe. Gord, 3 August: "maybe give me a bit more space on the
	   mobile view." The section was running the copy hard up against the top of
	   the band and hard down onto the buttons, so the words had nowhere to sit
	   that was not directly on Gord's face. This does not move anything, it just
	   stops the block being wedged in. */
	.wp-block-group.twg-fill-mobile{
		padding-top: var(--wp--preset--spacing--60);
		padding-bottom: var(--wp--preset--spacing--60);
	}
	.wp-block-group.twg-fill-mobile .wp-block-columns{
		margin-bottom: var(--wp--preset--spacing--50);
	}
	.wp-block-group.twg-fill-mobile .wp-block-buttons{
		gap: var(--wp--preset--spacing--20);
	}
}

/* ---------------------------------------------------------------------------
   IMAGES IN A QUERY LOOP TILE ARE RESPONSIVE

   An image inside a tile shrinks with its tile, and a grid is one column on a
   phone. The tile's own artwork carries an inline height, and an inline style
   beats a stylesheet, so it keeps its intended size.

   `minmax(0, 1fr)`, never a bare `1fr`: an `auto` minimum lets one unshrinkable
   child set the floor for the whole row, which is what hung the card meanings
   hub 130px off the side of a phone.
--------------------------------------------------------------------------- */
.wp-block-post-template > li img{
	max-width: 100%;
	height: auto;
}

@media (max-width: 781px){
	.wp-block-post-template.is-layout-grid{
		grid-template-columns: minmax(0, 1fr);
	}
}


/* Cards inside a Query Loop share a height, so a row reads as a row. */
.wp-block-post-template.is-layout-grid > li{ display: flex; }
.wp-block-post-template > li > .wp-block-group.is-style-twg-card{
	height: 100%;
	width: 100%;
	display: flex;
	flex-direction: column;
}

/* ---------------------------------------------------------------------------
   THE TILE. THERE ARE TWO OF THEM AND THIS IS WHAT MAKES BOTH BEHAVE.

   The audit found twelve versions of one component, because every page carried
   its own copy of the tile inside its own Query Loop. `tile-full` and
   `tile-compact` are the two that replace them, and everything about how they
   SIT is here rather than in either pattern, so the two cannot drift apart the
   way the twelve did.

   THE BUTTON IS WHAT GETS PUSHED DOWN, NOT THE TITLE. The rule that used to live
   here put `margin-top: auto` on the post title, which drops the name of the
   thing to the foot of the tile and leaves the picture floating above a gap. It
   is the buttons that have to sit on a common baseline, because they are what
   the eye tracks across a row. Finding 2 of the report: "Rows do not line up. A
   shorter tile pulls its button up above its neighbours."
--------------------------------------------------------------------------- */
.twg-tiles > li{ display: flex; }
.twg-tiles > li > .wp-block-group.is-style-twg-card{
	height: 100%;
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--20);
}
/* The one that matters: every tile's button lands on the same line. */
.twg-tiles > li > .wp-block-group.is-style-twg-card > .wp-block-buttons{
	margin-top: auto;
	margin-bottom: 0;
}
/* The title is the title. It stays where it is put. */
.twg-tiles > li > .wp-block-group.is-style-twg-card > .wp-block-post-title{
	margin-top: 0;
	margin-bottom: 0;
}
.twg-tiles > li > .wp-block-group.is-style-twg-card > .wp-block-post-title a{ text-decoration: none; }
.twg-tiles > li > .wp-block-group.is-style-twg-card > .wp-block-post-title a:hover{ text-decoration: underline; }

/* Artwork is contained, never cropped: several graphics have words baked in and
   `cover` chops them off (ui-components.md section 6). The cap stops one tall
   picture setting the height of the whole row. */
.twg-tiles--full > li > .wp-block-group.is-style-twg-card > .wp-block-post-featured-image img{
	max-height: 190px;
	width: auto;
	object-fit: contain;
	margin-inline: auto;
}
.twg-tiles--full > li > .wp-block-group.is-style-twg-card > .wp-block-post-excerpt{ margin: 0; }

/* AND THE FIGURE AROUND IT GETS A CEILING, WHICH THE PICTURE ALONE DOES NOT.
   The rule above caps the IMAGE. The figure holding it was still free to be
   wider than the card, and on 7 August the post-booking page proved it: two
   landscape thumbnails sat at 252px inside a 254px card and the one PORTRAIT
   thumbnail rendered its figure at 338px, pushing the page to 407px wide in a
   390px window. `object-fit: contain` letterboxes the picture inside that box
   rather than shrinking the box, so nothing looked broken, the page just
   scrolled sideways.
   Measured by injecting this one declaration into the real page before it was
   written here: at 390 the page goes 407 to 390 with nothing past the edge and
   the odd tile loses the 48px it had been stretched by. At 1440 NOTHING moves,
   on that page or on /blog/, which is the other place these tiles are used. */
.twg-tiles--full > li > .wp-block-group.is-style-twg-card > .wp-block-post-featured-image{ max-width: 100%; }

/* A compact tile is short by design, so it needs a floor or a row of one-word
   names collapses to a strip of buttons. */
.twg-tiles--compact > li > .wp-block-group.is-style-twg-card{ min-height: 9rem; }

/* One column on a phone, for both. `minmax(0, 1fr)` never a bare `1fr`: see the
   note above about the card meanings hub hanging off the side of a phone. */
@media (max-width: 781px){
	.twg-tiles.is-layout-grid{ grid-template-columns: minmax(0, 1fr); }
}


/* ---------------------------------------------------------------------------
   ONE FIELD DESIGN, AND THE SCREENS THAT TAKE THE MONEY GET IT TOO

   THE FINDING THIS FIXES, from the audit: "There are two form designs, and the
   plainer one is on the sign-in and checkout screens - 1px grey borders and 8px
   corners, where the site's own fields are 3px rust and 15px." Put plainly: the
   screen every member uses looked the least like the site, and there were no
   form rules in this stylesheet at all, so the sign-in and the checkout were
   rendering with the browser's defaults and PMPro's.

   THE NUMBERS ARE MEASURED OFF THE SITE, NOT CHOSEN HERE. 3px rust border and a
   15px radius is what the sign-up pop-up's own fields already do, and the report
   names those as the ones to keep: "One field design everywhere: dark fill,
   thick rust border, round corners."

   TWO THINGS ARE DELIBERATELY NOT 15px.

   A CHECKBOX at a 15px radius is a circle, and a circle means "pick one of
   these" to everybody who has ever used a form. So the tick box takes a small
   radius and the radio stays round, because the SHAPE is what tells the two
   apart and losing that would be a usability fault dressed up as consistency.

   SCOPE. This covers PMPro's screens and plain page forms. It deliberately does
   NOT reach into the member area, the journal, the recorder or the account hub:
   those print their own scoped CSS against the `--nv-*` tokens and have already
   been signed off, and `ui-components.md` is explicit that a section never
   repaints the components inside it.
--------------------------------------------------------------------------- */
.pmpro_form input[type="text"],
.pmpro_form input[type="email"],
.pmpro_form input[type="password"],
.pmpro_form input[type="tel"],
.pmpro_form input[type="number"],
.pmpro_form select,
.pmpro_form textarea,
.wp-block-post-content form:not(.twg-form-scope) input[type="text"],
.wp-block-post-content form:not(.twg-form-scope) input[type="email"],
.wp-block-post-content form:not(.twg-form-scope) input[type="password"],
/* tel, number and date were missing, so the moment the site's own form asked for
   a phone number, an event date and a guest count, three of its six fields
   rendered as raw white browser boxes next to three styled ones. Found by
   looking at the page, not by any count. */
.wp-block-post-content form:not(.twg-form-scope) input[type="tel"],
.wp-block-post-content form:not(.twg-form-scope) input[type="number"],
.wp-block-post-content form:not(.twg-form-scope) input[type="date"],
.wp-block-post-content form:not(.twg-form-scope) select,
/* THE SITE HAS ONE FIELD STYLE AND THIS IS IT. Gord, 16 August: I want one thing
   that styles all the forms, not a hundred. The rule used to reach only inside a
   page's own content, so anything the plugins drew themselves showed raw browser
   boxes, and the fix that got tried first was a second field style in the plugin.
   That was the disease, not the cure. Our own components are named here instead. */
.wp-block-post-content form:not(.twg-form-scope) textarea,
.twg-form__field input[type="text"],
.twg-form__field input[type="email"],
.twg-form__field textarea,
.twg-rdt__select,
.twg-rdt__text,
/* ⛔ EVERY FIELD ON THE SITE IS NAMED HERE AND NOWHERE ELSE. Gord, 28 August:
   "I want every fucking field and every fucking button to follow the same
   pattern." Six competing field designs had grown up in the plugins, each one
   added because this rule did not reach that far, which is the exact mistake
   the note above already warned about. Adding a class to this list is the only
   correct way to style a new field. Never restate the look in a plugin. */
.twg-rd-form input[type="text"],
.twg-rd-form input[type="email"],
.twg-rd-form input[type="password"],
.twg-rd-form input[type="number"],
.twg-rd-form input[type="datetime-local"],
.twg-rd-form input[type="date"],
.twg-rd-form input:not([type]),
.twg-rd-form select,
.twg-rd-form textarea,
.twg-rd-filters input,
.twg-rd-filters select,
.twg-st-noteline,
.twg-st-input,
.twg-st-reflect,
.twg-card-filter__input,
.twg-topics__select,
.twg-pop .sib_signup_form input[type="text"],
.twg-pop .sib_signup_form input[type="email"],
.twg-pitch__acct input[type="password"],
.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea,
.twg-header-search .wp-block-search__input,
.wp-block-search:not(.twg-header-search) .wp-block-search__input,
.twg-spread-people select,
#twg-spread-builder-box .twg-sb-bar select,
#twg-spread-builder-box .twg-sb-bar input[type="number"],
#twg-spread-builder-box .twg-sb-cardctl select,
#twg-spread-builder-box .twg-sb-cardctl input[type="number"]{
	/* ⛔ 3px. GORD SAID SO, TWICE. I read 1px off the account area's own rule and
	   changed it on that basis, which was second-guessing a stated instruction
	   with a measurement. Gord, 28 August: "WHY 1px?!? IT SHOULD BE 3px."

	   ⛔ WHAT SOMEBODY TYPES IS RUST. THE PLACEHOLDER IS BEIGE. Gord, same day:
	   "Placeholder should be beige, inputted text should be rust." Two jobs, two
	   colours, and the placeholder sets its own on the rule below. */
	background-color: var(--wp--preset--color--abyss);
	color: var(--wp--preset--color--rust);
	border: 3px solid var(--wp--preset--color--rust);
	border-radius: var(--wp--custom--radius--box, 15px);
	padding: 0.7rem 0.9rem;
	/* ⛔ FIELDS ARE RALEWAY, NOT BITTER. Gord, 28 August: "all things relating to
	   fields should be in Raleway rather than Bitter. Every field that you type
	   in, or the explainer text or whatever." */
	font-family: var(--wp--preset--font-family--raleway);
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.5;
	width: 100%;
	max-width: 100%;
	/* Without this, `width: 100%` means 100% of the container PLUS the padding
	   and the 3px border on each side, so every field on the site rendered
	   about 35px wider than the box holding it. On the workshops page that was
	   425px of field in a 390px phone window and the whole page scrolled
	   sideways, on a page Gord sells from. `max-width: 100%` does not save it,
	   because 100% is still measured before the padding is added. */
	box-sizing: border-box;
	box-shadow: none;
	/* The native date and time pickers paint light-on-light on a dark field and
	   the icon disappears. Same fix as the member canvas already uses. */
	color-scheme: dark;
}

.pmpro_form textarea,
.wp-block-post-content form:not(.twg-form-scope) textarea{ min-height: 8rem; }

.pmpro_form input::placeholder,
.wp-block-post-content form:not(.twg-form-scope) input::placeholder,
.wp-block-post-content form:not(.twg-form-scope) textarea::placeholder,
.twg-form__field input::placeholder,
.twg-rdt__text::placeholder,
.twg-rd-form input::placeholder,
.twg-rd-form textarea::placeholder,
.twg-st-noteline::placeholder,
.twg-st-input::placeholder,
.twg-st-reflect::placeholder,
.twg-card-filter__input::placeholder,
.twg-pop .sib_signup_form input::placeholder,
.twg-pitch__acct input::placeholder,
.comment-form input::placeholder,
.comment-form textarea::placeholder,
.wp-block-search__input::placeholder{
	color: var(--wp--preset--color--beige);
	opacity: 0.55;
	font-family: var(--wp--preset--font-family--raleway);
}

/* Focus goes copper, which is what copper is for everywhere else on the site. */
.pmpro_form input:focus,
.pmpro_form select:focus,
.pmpro_form textarea:focus,
.wp-block-post-content form:not(.twg-form-scope) input:focus,
.wp-block-post-content form:not(.twg-form-scope) select:focus,
.wp-block-post-content form:not(.twg-form-scope) textarea:focus,
.twg-form__field input:focus,
.twg-form__field textarea:focus,
.twg-rdt__select:focus,
.twg-rdt__text:focus,
.twg-rd-form input:focus,
.twg-rd-form select:focus,
.twg-rd-form textarea:focus,
.twg-rd-filters input:focus,
.twg-rd-filters select:focus,
.twg-st-noteline:focus,
.twg-st-input:focus,
.twg-st-reflect:focus,
.twg-card-filter__input:focus,
.twg-pop .sib_signup_form input:focus,
.twg-pitch__acct input:focus,
.comment-form input:focus,
.comment-form textarea:focus,
.wp-block-search__input:focus{
	border-color: var(--wp--preset--color--copper);
	outline: none;
}

.pmpro_form label,
.pmpro_form legend{
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 700;
	color: var(--wp--preset--color--rust);
}

/* REAL TICK BOXES. The browser's own are the grey-on-grey squares the audit
   found on the checkout, and they are the one thing on that page that cannot be
   mistaken for anything but a default. */
.pmpro_form input[type="checkbox"],
.pmpro_form input[type="radio"],
.wp-block-post-content form:not(.twg-form-scope) input[type="checkbox"],
.wp-block-post-content form:not(.twg-form-scope) input[type="radio"],
.comment-form input[type="checkbox"],
.twg-form__consent input[type="checkbox"],
.twg-rd-form input[type="checkbox"],
.twg-pop .sib_signup_form input[type="checkbox"],
#cmplz-manage-consent-container input[type="checkbox"].cmplz-consent-checkbox{
	appearance: none;
	-webkit-appearance: none;
	width: 1.35rem;
	height: 1.35rem;
	min-width: 1.35rem;
	margin: 0 0.6rem 0 0;
	vertical-align: middle;
	background-color: var(--wp--preset--color--abyss);
	border: 3px solid var(--wp--preset--color--rust);
	display: inline-grid;
	place-content: center;
	cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease;
}
/* Square-ish for a tick box, round for a radio. The shape is the meaning. */
.pmpro_form input[type="checkbox"],
.wp-block-post-content form:not(.twg-form-scope) input[type="checkbox"],
.comment-form input[type="checkbox"],
.twg-form__consent input[type="checkbox"],
.twg-rd-form input[type="checkbox"],
.twg-pop .sib_signup_form input[type="checkbox"],
#cmplz-manage-consent-container input[type="checkbox"].cmplz-consent-checkbox{ border-radius: 5px; }
.pmpro_form input[type="radio"],
.wp-block-post-content form:not(.twg-form-scope) input[type="radio"]{ border-radius: 50%; }

.pmpro_form input[type="checkbox"]::before,
.wp-block-post-content form:not(.twg-form-scope) input[type="checkbox"]::before,
#cmplz-manage-consent-container input[type="checkbox"].cmplz-consent-checkbox::before{
	content: "";
	width: 0.7rem;
	height: 0.38rem;
	border-left: 3px solid var(--wp--preset--color--abyss);
	border-bottom: 3px solid var(--wp--preset--color--abyss);
	transform: rotate(-45deg) translate(1px, -1px) scale(0);
	transition: transform .15s ease;
}
.pmpro_form input[type="checkbox"]:checked,
.pmpro_form input[type="radio"]:checked,
.wp-block-post-content form:not(.twg-form-scope) input[type="checkbox"]:checked,
.wp-block-post-content form:not(.twg-form-scope) input[type="radio"]:checked,
#cmplz-manage-consent-container input[type="checkbox"].cmplz-consent-checkbox:checked{
	background-color: var(--wp--preset--color--rust);
}
.pmpro_form input[type="checkbox"]:checked::before,
.wp-block-post-content form:not(.twg-form-scope) input[type="checkbox"]:checked::before,
#cmplz-manage-consent-container input[type="checkbox"].cmplz-consent-checkbox:checked::before{
	transform: rotate(-45deg) translate(1px, -1px) scale(1);
}
.pmpro_form input[type="radio"]::before,
.wp-block-post-content form:not(.twg-form-scope) input[type="radio"]::before{
	content: "";
	width: 0.6rem;
	height: 0.6rem;
	border-radius: 50%;
	background-color: var(--wp--preset--color--abyss);
	transform: scale(0);
	transition: transform .15s ease;
}
.pmpro_form input[type="radio"]:checked::before,
.wp-block-post-content form:not(.twg-form-scope) input[type="radio"]:checked::before{
	transform: scale(1);
}
.pmpro_form input[type="checkbox"]:focus-visible,
.pmpro_form input[type="radio"]:focus-visible,
.wp-block-post-content form:not(.twg-form-scope) input[type="checkbox"]:focus-visible,
.wp-block-post-content form:not(.twg-form-scope) input[type="radio"]:focus-visible,
#cmplz-manage-consent-container input[type="checkbox"].cmplz-consent-checkbox:focus-visible{
	border-color: var(--wp--preset--color--copper);
	outline: 2px solid var(--wp--preset--color--copper);
	outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   ⚠️ HERE IS THE SECOND RUST. THE AUDIT SAID THERE WERE TWO AND THIS IS THE
   OTHER ONE.

   The report's third sitewide setting is "One rust, not two". The theme has only
   ever had one, `#b87c00`, and every page checked came back clean, so it looked
   like the finding was already closed. It was not. It was hiding in PMPro's own
   custom properties, on the screens the audit said looked least like the site:

     --pmpro--color--accent: #bc8700    <- NOT the palette rust
     --pmpro--color--border: #777777    <- a grey, and a fifth colour
     --pmpro--base--border-radius: 8px  <- the 6/8px mix section 4 abolished

   `#bc8700` against `#b87c00` is four points of hue apart, which is exactly why
   nobody spotted it by eye on a page nobody looks at twice. It paints every
   PMPro link, button and highlight on the sign-in, the checkout, the levels page
   and the member account screens.

   FIXED AT THE VARIABLES RATHER THAN RULE BY RULE, because PMPro 3 styles its
   whole front end from these, so one correction reaches every component it owns
   instead of the handful somebody happens to write selectors for. That is the
   same reasoning as the shared disclosure in `ui-components.php`.

   `--pmpro--color--base` and `--contrast` are LEFT ALONE deliberately: they are
   already the site's beige and abyss, so somebody set them on purpose, and the
   beige checkout panel is a legitimate light band rather than a stray.
--------------------------------------------------------------------------- */
/* ON `body`, NOT ON `:root`, AND THAT IS THE WHOLE TRICK. The wrong rust is set
   by an inline `<style>` block on `:root`, and an inline block is written into
   the document AFTER this stylesheet is linked, so at equal specificity it wins
   and a `:root` rule here loses. Custom properties inherit, so setting them one
   step closer to the content, on `body`, beats the `:root` value for everything
   inside it without an `!important` anywhere. */
body,
.pmpro,
.pmpro_form,
.pmpro_card{
	--pmpro--color--accent: var(--wp--preset--color--rust);
	--pmpro--color--accent--variation: var(--wp--preset--color--copper);
	--pmpro--color--border: var(--wp--preset--color--rust);
	--pmpro--color--border--variation: var(--wp--preset--color--rust);
	--pmpro--base--border-radius: var(--wp--custom--radius--box, 15px);
}

/* THE TWO PANEL HEADINGS WERE TWO DIFFERENT COLOURS. "About You" rendered abyss
   while "Choose Your Payment Method" rendered rust, on the same beige panel, two
   inches apart. Section 1's pairing rule is that lettering on beige is rust, and
   theme.json's heading colour is written with `:where()`, which has no
   specificity at all, so PMPro's own heading colour was quietly beating it. */
.pmpro_form .pmpro_card_title,
.pmpro_card .pmpro_card_title,
.pmpro_form .pmpro_form_heading,
.pmpro_card h2,
.pmpro_card h3{ color: var(--wp--preset--color--rust); }

/* Every commerce button is the site's button. Gord, 4 August: "the purchase
   button is completely unbranded." */
.pmpro_form input[type="submit"],
.pmpro_btn,
.pmpro_form .pmpro_btn-submit-checkout{
	background-color: var(--wp--preset--color--rust);
	color: var(--wp--preset--color--abyss);
	border: 3px solid var(--wp--preset--color--abyss);
	border-radius: var(--wp--custom--radius--pill, 30px);
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	padding: 12px 22px;
	cursor: pointer;
	width: auto;
}
.pmpro_form input[type="submit"]:hover,
.pmpro_btn:hover{ background-color: var(--wp--preset--color--copper); }

@media (prefers-reduced-motion: reduce){
	.pmpro_form input[type="checkbox"],
	.pmpro_form input[type="radio"],
	.pmpro_form input[type="checkbox"]::before,
	.pmpro_form input[type="radio"]::before{ transition: none; }
}

/* ---------------------------------------------------------------------------
   THE CLOSE CONTROL GETS ITS OWN SPACE. ONE RULE, EVERY OVERLAY.

   Finding 1 of the four the audit found repeating across the site: "The close
   button is never given its own space." Three separate things did it, and the
   menu on a phone is one of them, with the close cross landing on top of the
   hamburger underneath it.

   `ui-components.md` 7b, added 5 August after Gord asked for exactly this: "We
   need to make sure that all of the modals and pop-ups have a consistent rule
   with the close button, because at the moment they all do different things."
   The spec is: top right, INSIDE the panel, it reserves a real row so content
   never runs underneath it, 44x44 minimum tap target with a smaller glyph, rust
   going copper, and Esc and backdrop both close it.

   THE FAULT IS THAT THE BUTTON IS POSITIONED ABSOLUTELY, so whether it lands on
   the heading depends on how long that heading happens to be. That is luck, not
   design. Core positions it absolutely and there is no setting for it, so the
   space is reserved by padding the overlay instead: the button keeps its
   position and the content is pushed clear of it, which gets the same result
   without fighting core's own layout.

   44px is not a preference. It is the floor for something a thumb has to hit,
   and the audit measured between 4 and 14 targets per page under 40px tall.
--------------------------------------------------------------------------- */
.wp-block-navigation__responsive-container-close{
	color: var(--wp--preset--color--rust) !important;
	fill: var(--wp--preset--color--rust);
	min-width: 44px;
	min-height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border-radius: var(--wp--custom--radius--box, 15px);
}
.wp-block-navigation__responsive-container-close:hover,
.wp-block-navigation__responsive-container-close:focus-visible{
	color: var(--wp--preset--color--copper) !important;
	fill: var(--wp--preset--color--copper);
}
/* The glyph itself stays the size it was. Only the thing you press grew. */
.wp-block-navigation__responsive-container-close svg{ width: 22px; height: 22px; }

/* The reserved row. The close sits in the overlay's top right, so the menu's
   own content starts below it rather than under it. */
.wp-block-navigation__responsive-container.is-menu-open{
	padding-top: calc(44px + var(--wp--preset--spacing--30, 1.5rem));
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-close{
	padding-top: 0;
}

/* ⛔ THIS BLOCK IS 1150px, NOT 781px, AND THAT IS THE WHOLE POINT.
   27 August 2026. The overlay menu appears from 1150px DOWN, because the theme
   collapses the nav there rather than at WordPress's own breakpoint (see the long
   note further up this file about the eight top-level items needing about 914px).
   Every rule for the OPEN menu was written at 781px, so between 782px and 1150px
   the overlay opened with none of them applied: full block gaps, 20px of submenu
   padding, and links about 120px apart. Gord was looking at exactly that window
   and it took three goes to spot, because I kept checking the rules and not the
   width they were written for.

   ⛔ ANY RULE FOR THE OPEN OVERLAY BELONGS AT 1150px. Anything about the phone
   layout itself still belongs at 781px. They are different questions. */
@media (max-width: 1150px){
	/* ⛔ MEASURED BEFORE AND AFTER, 27 August 2026. Gord: "it needs to be about a
	   quarter of what it is right now."

	   Before: a top level link was 44px tall around 26px of text, so 18px of space.
	   A submenu link was 59px, because it carried 15px of its own padding on top of
	   the same 44px minimum, so 33px of space. Every submenu then added another
	   20px of padding above itself.

	   After: 4px of space around a top level link, 6px around a submenu one, and no
	   padding above a submenu at all. The 44px minimum has gone, because it was the
	   thing making the list a scroll and Gord has asked for tight. */
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content{
		display: block;
		padding-block: 4px !important;
		min-height: 0 !important;
	}
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content{
		padding-block: 6px !important;
		padding-inline: 0 !important;
		min-height: 0 !important;
	}

	/* ⛔ THE OPEN MENU WAS A SCROLL, NOT A MENU. Gord, 27 August: "why are these
	   still so far apart?"

	   MEASURED, NOT GUESSED, by forcing the overlay open and reading the computed
	   values. Two things were doing it, and the first attempt only fixed one:
	     1. the list itself has a 20px flex gap
	     2. every submenu has 20px of its own padding on top, plus a 32px indent
	   Fifteen links then came out about 100px apart and more than half the menu was
	   below the fold.

	   ⛔ EVERY ONE OF THESE NEEDS !important. Core sets them from the block's own
	   layout styles, which are printed after the theme, so a plain rule loses. The
	   first go left the submenu padding without it and nothing changed.

	   The 44px tap target on each link STAYS. It is the dead space between links
	   that goes, never the size of the thing you are aiming at. */
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container{
		gap: 0 !important;
		row-gap: 0 !important;
	}
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container{
		padding-top: 0 !important;
		padding-bottom: 0 !important;
		padding-left: 1.25rem !important;
	}
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item{
		margin-block: 0 !important;
	}
	/* A hairline under each top level item, so the list reads as a list once the
	   space between them has gone. */
	.wp-block-navigation__responsive-container.is-menu-open > .wp-block-navigation__responsive-dialog .wp-block-navigation__container > .wp-block-navigation-item + .wp-block-navigation-item{
		border-top: 1px solid rgba(184,124,0,.18);
	}
}

/* ---------------------------------------------------------------------------
   THE FOUR SIMPLY TAROT PAGES: THE HEADING EXISTS AGAIN, AND NOTHING MOVES.

   Gord, 5 August, and this settles it: the script logo IS the title, it reads
   perfectly well, and printing the words a second time next to a 500px picture
   of the same words would be worse. So the LOOK does not change. At all.

   The only real problem was invisible. `.ticss-90770a8c { display: none }` is
   Gord's own rule, written years ago through Otter's custom CSS panel to stop
   the page saying its name twice, and it does that job. But `display: none`
   removes the element from the accessibility tree and from what Google reads,
   so all four money pages have been serving NO heading at all in their outline.
   The logo carries the words as pixels, and a picture is not a heading.

   `clip-path: inset(50%)` is the standard way to keep an element in the
   accessibility tree while taking it off the screen. A screen reader announces
   "Simply Tarot Membership, heading level 1" and Google reads it. Nobody sees
   anything different. It is scoped to `h1` so the rest of Gord's rule is
   untouched: everything else that class hides stays hidden.

   THE CLASS IS NAMED HERE ON PURPOSE. It is one generated class shared by all
   four pages, so one rule covers the lot. If a fifth page ever hides its H1
   under a DIFFERENT ticss class this will not catch it, and the check is to
   look for an H1 computing to `display: none`.
--------------------------------------------------------------------------- */
/* FOLDED INTO `.twg-sr-only` at the foot of this file, 7 August, theme 0.9.6.
   The selector is kept because it is what the four service pages actually carry;
   the declarations now live once, with the class, instead of twice. */

/* ---------------------------------------------------------------------------
   A LINK ON A COLOURED PANEL WAS THE SAME COLOUR AS THE PANEL

   On `/tarot/how-i-read-tarot/` the link "How to Prepare for a Tarot Reading"
   was rust lettering on a rust panel. Measured contrast: 1.00. Not hard to
   read, INVISIBLE. The one next to it was rust on copper at 1.08.

   The panels already set their own text to Abyss, which is why every ordinary
   word in them reads perfectly. Links were the one thing still taking the
   global rust link colour, so the fault only ever showed up on the sentences
   that happened to contain a link.

   Keyed off the ground the panel actually declares, not off `.twg-panel`, so
   it holds for any element painted rust or copper. Buttons are excluded
   because they set their own pair and are already correct.
--------------------------------------------------------------------------- */
.has-rust-background-color a:not(.wp-block-button__link):not(.wp-element-button),
.has-copper-background-color a:not(.wp-block-button__link):not(.wp-element-button){
	color: var(--wp--preset--color--abyss);
}


/* ---------------------------------------------------------------------------
   A LINK TAKES ITS COLOUR FROM THE GROUND IT IS STANDING ON

   0.7.9 fixed links on rust and copper panels. It missed the commonest case on
   the whole site: a rust link on a BEIGE section measures 2.17:1. Counted at
   1440, before this rule: 84 of 88 body links on /digital-downloads/, 9 of 14
   on /learn-tarot/, 2 of 2 on /ethical-tarot-readings/.

   Done with an inherited custom property rather than a pile of descendant
   selectors, and that is the whole point. Ground selectors of equal weight do
   NOT resolve to the nearest ancestor, they resolve to whichever was written
   last, so a card sitting inside a beige section takes the beige answer and
   its links go abyss on abyss. A custom property inherits, so the nearest
   ancestor that declares one always wins.

   PROVED BY INJECTION BEFORE IT WAS WRITTEN HERE. The first attempt keyed off
   the has-*-background-color classes alone and turned all ten card titles on
   /blog/ INVISIBLE, contrast 1.00, because .is-style-twg-card paints its own
   abyss ground through the style and carries no such class. Anything that
   paints its own ground has to re-declare the ink. Across nine pages the
   finished rule fixes 111 links and breaks none.

   Buttons are excluded: they set their own pair and are already right.
--------------------------------------------------------------------------- */
.has-abyss-background-color,
.is-style-twg-card,
.wp-block-navigation-item,
.wp-block-navigation__submenu-container{ --twg-link-ink: var(--wp--preset--color--rust); }

/* ⛔ SUBMENU ITEMS ONLY, AND ON THEIR OWN LINE. Gord, 27 August: "I just said the
   sub-menu items." Changing the value on the list above turned EVERY menu item
   copper, plus the cards and every link on an abyss ground, because that selector
   list is shared by four different things. A change meant for one of them gets its
   own rule underneath, never an edit to the shared value. */
.wp-block-navigation__submenu-container .wp-block-navigation-item{
	--twg-link-ink: var(--wp--preset--color--copper);
}
.wp-block-navigation__submenu-container .wp-block-navigation-item__content{
	color: var(--wp--preset--color--copper);
}

/* Body links on beige stay abyss. That is separate from headings and Gord has
   not asked for it to change. Headings are handled below. */
.has-beige-background-color{ --twg-link-ink: var(--wp--preset--color--abyss); }
.has-rust-background-color{ --twg-link-ink: var(--wp--preset--color--abyss); }
.has-copper-background-color{ --twg-link-ink: var(--wp--preset--color--abyss); }

:is(.has-abyss-background-color,.has-beige-background-color,.has-rust-background-color,.has-copper-background-color) a:not(.wp-block-button__link):not(.wp-element-button):not(.edd-submit){
	color: var(--twg-link-ink);
}

/* ---------------------------------------------------------------------------
   HEADING INK, BY THE GROUND IT STANDS ON

   14 August. The link fix above was made on 6 August and headings were left
   alone, so rust headings on beige sections were still sitting at 2.17:1. Found
   by sweeping the home page rather than by being told: "Try Something Free
   First" measured 2.17. It is on every light band on the site.

   Gord's correction stands and is not being undone: HEADINGS ARE RUST. That is
   right on the dark ground the site mostly uses. It is only wrong on the light
   bands, where rust and beige are two mid tones a shade apart.

   ➡️ SO: rust on dark grounds, abyss on light ones. This is a look-and-feel
   call, made rather than asked, per the standing instruction. Gord has been
   told it is coming and can throw it out on sight.

   Same mechanism as the link ink above and for the same reason: ground
   selectors of equal weight resolve to whichever was written last, not to the
   nearest ancestor, so a card inside a beige section would take beige's answer
   and lose its rust. A custom property inherits, so the nearest ancestor that
   declares one always wins, and a card declares its own.
--------------------------------------------------------------------------- */
/* ANYTHING THAT PAINTS ITS OWN ABYSS GROUND DECLARES ITS OWN INK, AND A
   DISCLOSURE IS ONE OF THEM. Added 14 August after the heading-ink rule below
   reached inside the FAQ cards on the spread pages: the band behind them is
   beige, so the questions took beige's answer and went abyss on the card's own
   abyss, contrast 1.00. Ten of them on one page. Same trap as the tiles, same
   fix, and the property inherits so the nearest declaration always wins. */
.has-abyss-background-color,
.is-style-twg-card,
.edd-blocks__download{ --twg-heading-ink: var(--wp--preset--color--rust); }

/* ⛔ BEIGE TAKES RUST, LIKE EVERY OTHER GROUND. PUT BACK 15 AUGUST 2026.
   It said abyss here, which is the second time that override has been written
   against Gord's stated rule. Gord, 30 July: beige heading text "is wrong" and
   the colour that should do the job is "the one currently used for the menu and
   for links, i.e. rust." Rust on beige measures about 2.2 to 1 and Gord has
   settled that twice. A contrast sweep will flag it every single time. It is
   still not a fault.

   Rust and copper keep abyss, because rust lettering on a rust ground cannot be
   read. That pairing is Gord's too and is not the thing that was wrong. */
.has-beige-background-color{ --twg-heading-ink: var(--wp--preset--color--rust); }
.has-rust-background-color{ --twg-heading-ink: var(--wp--preset--color--abyss); }
.has-copper-background-color{ --twg-heading-ink: var(--wp--preset--color--abyss); }

:is(.has-abyss-background-color,.has-beige-background-color,.has-rust-background-color,.has-copper-background-color,.is-style-twg-card,.edd-blocks__download) :is(h1,h2,h3,h4,h5,h6):not([class*="has-"][class*="-color"]){
	color: var(--twg-heading-ink);
}

/* THE REVIEW STARS ARE NOT FIXED HERE, ON PURPOSE. They were the last thing
   failing on the home page, rust on the beige review card at 2.17:1, and the
   first attempt was a rule in this file. It lost, because the review card's
   colours are printed by TWG Core as an inline style block that loads after
   this stylesheet, so at equal weight the plugin wins.

   Beating it from here would have meant this theme patching around a component
   it does not own, which is the hodgepodge Gord objected to on 13 August. The
   review card already decides its own ground in the plugin, so it decides its
   own star ink there too. See `twg-core/includes/ui-components.php`. */

/* Easy Digital Downloads paints its own buttons and it paints its own text
   colour onto them: #333 on the site's rust ground, which measures 3.56:1 at
   18px weight 900. Bold 18px is 13.5pt, just under the large-text threshold,
   so 3.56 fails. Measured on /digital-downloads/ on 6 August: 132 elements,
   88 add-to-cart buttons and 44 Checkout links.
   The Checkout links are hidden until something is in the cart, which is why
   a sweep of visible links finds none of them and an earlier note recorded
   four at 1.00. There are 44 and they are 3.56, the same as the buy buttons.
   Abyss on the same rust is 4.77 and is what every other button here uses, so
   the buttons look the same and the ratio clears. EDD's own selector is
   .edd-submit.button, so the class pair is needed to beat it. */
.edd-submit,
.edd-submit.button,
.edd-submit.button:visited,
.edd_purchase_submit_wrapper a.edd_go_to_checkout{
	color: var(--wp--preset--color--abyss);
}
/* Brevo's own sign-up form prints its submit as a bare input.sib-default-btn,
   so on the mailing-list page the button under two properly styled fields was
   a small grey browser default. The fields themselves already pick up the form
   rule above. This gives the button the same treatment every other button on
   the site gets, without touching Brevo. */
.wp-block-post-content .sib_signup_form input[type="submit"],
.wp-block-post-content input.sib-default-btn{
	background-color: var(--wp--preset--color--rust);
	color: var(--wp--preset--color--abyss);
	border: 3px solid var(--wp--preset--color--abyss);
	border-radius: 30px;
	padding: 0.7rem 1.6rem;
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	cursor: pointer;
	width: auto;
}

.wp-block-post-content .sib_signup_form input[type="submit"]:hover,
.wp-block-post-content input.sib-default-btn:hover{
	background-color: var(--wp--preset--color--copper);
}

/* ---------------------------------------------------------------------------
   PRODUCT TILES  (Easy Digital Downloads)

   /digital-downloads/ lists 44 products in three columns. Left alone, EDD
   gives each one a bare picture, an underlined link and a button sitting
   straight on the section's ground: no panel, no edge, nothing holding the
   three parts together, so the page reads as a list of loose parts rather
   than a shop.

   Measured on 6 August: every picture renders 300 tall but their widths run
   214, 231, 232, 233 and 300, so the tops of the tiles are ragged and the
   titles below them start at different heights.

   This gives every tile the same card the rest of the site already uses,
   .is-style-twg-card: abyss ground, rust edge, 15px corner, the same padding.
   The artwork goes in a fixed box so every tile lines up whatever shape the
   cover is, and the buy button is pinned to the bottom so tiles with a
   two-line title still finish level with their neighbours.

   The tile paints its own ground, so it re-declares --twg-link-ink. Without
   that line every title inside the beige sections would take beige's answer
   and go abyss on abyss, which is exactly how the blog card titles were
   turned invisible on 6 August.
--------------------------------------------------------------------------- */
.edd-blocks__download{
	display: flex;
	flex-direction: column;
	height: 100%;
	/* EDD ships these as content-box. Without this line height:100% measures
	   the row track and then the 24px padding and 1px edge are ADDED on top, so
	   every tile stands ~50px taller than its own row, swallows the 32px gap
	   and overlaps the row beneath it by 18px. */
	box-sizing: border-box;
	background-color: var(--wp--preset--color--abyss);
	color: var(--wp--preset--color--beige);
	border: 1px solid var(--wp--preset--color--rust);
	border-radius: 15px;
	padding: var(--wp--preset--spacing--30);
	--twg-link-ink: var(--wp--preset--color--rust);
}

.edd-blocks__download .edd-blocks__download-header{
	display: flex;
	flex-direction: column;
}

.edd-blocks__download a.edd-blocks__download-image-link{
	display: block;
	text-decoration: none;
	margin-bottom: var(--wp--preset--spacing--30);
}

.edd-blocks__download img.edd-blocks__download-image{
	display: block;
	width: 100%;
	height: 260px;
	object-fit: contain;
	object-position: center;
	margin-inline: auto;
}

.edd-blocks__download .edd-blocks__download-header :where(h1,h2,h3,h4,h5,h6){
	color: var(--wp--preset--color--rust);
	margin: 0 0 var(--wp--preset--spacing--30) 0;
}

.edd-blocks__download .edd-blocks__download-header a{ text-decoration: none; }
.edd-blocks__download .edd-blocks__download-header a:hover,
.edd-blocks__download .edd-blocks__download-header a:focus{ text-decoration: underline; }

/* Pins the price and the buy button to the foot of the card. */
.edd-blocks__download .edd-blocks__download-footer{ margin-top: auto; }

/* EDD's own .edd-blocks__columns .edd-blocks__download sets padding:1rem, which
   outranks the single-class card rule above, so the tile was sitting at 16px
   while every other card on the site uses the 24px step. One more step of
   specificity puts it back on the site's spacing scale. */
.entry-content .edd-blocks__columns .edd-blocks__download{
	padding: var(--wp--preset--spacing--30);
}

/* ---------------------------------------------------------------------------
   THE EDD BUY BUTTON

   These were rust pills until 6 August and it turned out nothing on this site
   was making them so: the styling came from a leftover Otter custom-CSS blob
   stored on the four product blocks on /digital-downloads/, full of
   !important, still being printed after Otter itself had gone. Clearing that
   dead attribute off the blocks stripped the buttons back to the browser's own
   grey Arial box, on the site's only shop page. It only showed up because the
   page was loaded and looked at.

   So the button now gets the site's real button treatment from the theme,
   copied from the .wp-block-button__link rule above so the two match exactly.
   EDD's own selector is .edd-submit.button, hence the class pair.

   NO display PROPERTY IN HERE, EVER. The first version set
   display:inline-block and that un-hid two things EDD deliberately keeps
   hidden: the no-JS fallback input and the Checkout link. Every card showed
   two identical buy buttons side by side.
--------------------------------------------------------------------------- */
.entry-content button.edd-submit,
.entry-content .edd-submit.button,
.entry-content a.edd-submit.button,
.entry-content .edd_purchase_submit_wrapper a.edd_go_to_checkout{
	background-color: var(--wp--preset--color--rust);
	border: 3px solid var(--wp--preset--color--abyss);
	border-radius: 30px;
	color: var(--wp--preset--color--abyss);
	padding: 12px 22px;
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 900;
	font-size: 0.95rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	line-height: 1.15;
	text-decoration: none;
	cursor: pointer;
	width: auto;
}

.entry-content button.edd-submit:hover,
.entry-content .edd-submit.button:hover,
.entry-content a.edd-submit.button:hover,
.entry-content .edd_purchase_submit_wrapper a.edd_go_to_checkout:hover{
	background-color: var(--wp--preset--color--copper);
	border-color: var(--wp--preset--color--abyss);
	color: var(--wp--preset--color--abyss);
}

/* ---------------------------------------------------------------------------
   THE PANEL IS A CARD, SO IT HAS TO LOOK LIKE ONE

   On /tarot/ the four price panels were turned Abyss on 6 August so the reading
   name artwork sits on the ground it was drawn for. That was right, and it left
   four Abyss panels on an Abyss band with no edge at all, so they read as four
   columns of text rather than four cards. A border was set in the block itself
   and did not render, measured 0px afterwards, which is why it is here.

   THE NUMBERS ARE LIVE'S, NOT CHOSEN HERE. The same four panels on the live
   site are Abyss with a 2px rust border and a 15px corner. Staging now matches
   that exactly, so this is bringing the rebuild into line rather than inventing
   a look.

   KEYED OFF THE GROUND THE PANEL DECLARES, not off `.twg-panel`, the same way
   the link rule further up this file is. The panels on /simply-spreads/ carry
   the same class on a RUST ground, and rust on rust measures 1.00 contrast,
   which is the invisible-border fault this project has already had once. Only
   an Abyss panel gets the edge, because only an Abyss panel needs one.

   `height: 100%` is the "rows are rows" rule in `ui-components.md`. The columns
   were already stretching to 750px and the panels inside them were not, so the
   card bottoms were ragged at 656, 719, 750 and 750. Ragged card bottoms were
   called the single most obvious fault on this very page.
--------------------------------------------------------------------------- */
.twg-panel{
	height: 100%;
	box-sizing: border-box;
	border-radius: var(--wp--custom--radius--box, 15px);
}

.twg-panel.has-abyss-background-color{
	border: 2px solid var(--wp--preset--color--rust);
}

/* ---------------------------------------------------------------------------
   THE PASSKEY BUTTON ON ORDINARY PAGES WAS A GREY BROWSER DEFAULT, ON 25 OF THEM

   Found by looking at `/checkout/order-history/` after finishing something else
   on it. Every gated page prints the Secure Passkeys sign-in button under the
   log-in form, and it rendered as `rgb(239,239,239)`, black Arial 13px, square
   corners, an outset border: the browser's own button, sitting next to the
   site's gold LOG IN pill. **Twenty-five published pages carry it.**

   The login SCREEN's copy of this button was styled on 6 August, inside
   TWG Account, scoped to `body.login`. That scope is why it never reached these
   pages. The numbers here are that rule's, so the two match.

   🚨 IT MUST BE KEYED OFF THE ID, AND THAT IS NOT A PREFERENCE.

   The served HTML says `class="button button-large login-via-passkey"`, so a
   class selector looks obviously right. **It does not work.** The plugin's own
   script rewrites the element after the page loads and the class is gone by the
   time anybody sees it; the id survives. A rule on `.login-via-passkey` alone
   changed nothing at all, twice, including with `!important` on every line, and
   the only thing that proved it was injecting `#login-via-passkey{background:red}`
   into the real page and watching it turn red. **The class is kept in the
   selector in case the plugin ever stops rewriting it.**

   And the reason the first two attempts looked like a specificity fight and were
   not: a style injected into a page BEFORE that script has run gets measured
   against the element it has already replaced. **Wait for the page to settle,
   then inject, then measure.**
--------------------------------------------------------------------------- */
#login-via-passkey,
.login-via-passkey{
	background: transparent;
	border: 2px solid var(--wp--preset--color--rust);
	color: var(--wp--preset--color--rust);
	border-radius: 30px;
	padding: 12px 22px;
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 900;
	font-size: 0.95rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	line-height: 1.15;
	cursor: pointer;
	box-shadow: none;
	width: auto;
}

#login-via-passkey:hover,
#login-via-passkey:focus,
.login-via-passkey:hover,
.login-via-passkey:focus{
	border-color: var(--wp--preset--color--copper);
	color: var(--wp--preset--color--copper);
}

/* ---------------------------------------------------------------------------
   ONE NAMED WAY TO TAKE A HEADING OFF THE SCREEN WITHOUT TAKING IT OFF THE PAGE

   The site keeps doing the same thing: the words that name a page are a
   picture, and the real heading is either missing or set to `display: none`.
   That was the fault on the four money pages, fixed in 0.7.7, and it was the
   fault on the member journal, fixed in the membership plugin at 1.25.0.

   `display: none` is never the answer, because it takes the element out of the
   accessibility tree AND out of what Google reads, which is the whole problem
   it was supposed to solve. Clipping keeps the element on the page and takes it
   off the screen. Nobody sees anything different.

   Use this class rather than writing the trick out again. The 0.7.7 rule above
   is scoped to one generated class on four particular pages and should be
   folded into this one next time it is opened.
--------------------------------------------------------------------------- */
.twg-sr-only,
main h1.ticss-90770a8c {
	display: block !important;
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ---------------------------------------------------------------------------
   THE COOKIE POLICY TABLES, ON A PHONE

   The consent plugin draws its cookie tables as a grid, 100px for the label and
   whatever is left for the value. Three things fought the screen at 390:

   1. Every cell carries 15px of padding on a content-box, so each one rendered
      30px wider than the space it was given.
   2. The wide track is a `1fr`, whose automatic minimum is the widest thing
      inside it. Cookie names like `__ppcp-block-editor-checkout-paylater-
      message_storage__` are one unbreakable word, so the track grew to fit the
      longest name and pushed the whole page sideways. `min-width: 0` lets the
      track shrink and `overflow-wrap` lets the name break instead.
   3. The description and sharing blocks are set to `width: 100%` on a
      content-box, so they too came out 30px over.

   Measured on both cookie pages with the accordions open, which is the state a
   reader is actually in: 192 elements past the right edge and the page scrolling
   495 in a 390 window, before. Nothing past the edge and 390, after. Desktop is
   unchanged apart from the two description columns losing the 30px that was
   always overhanging.

   The selectors copy the plugin's own, including the ID, because anything
   written with classes loses to it. This stylesheet loads after the plugin's,
   so an equal-specificity copy wins.
--------------------------------------------------------------------------- */
#cmplz-cookies-overview .cmplz-dropdown .cmplz-service-description,
#cmplz-cookies-overview .cmplz-dropdown .cmplz-sharing-data,
#cmplz-cookies-overview .cmplz-dropdown p,
#cmplz-cookies-overview .cmplz-dropdown h4,
#cmplz-cookies-overview .cmplz-dropdown ul,
#cmplz-document .cmplz-dropdown .cmplz-service-description,
#cmplz-document .cmplz-dropdown .cmplz-sharing-data,
#cmplz-document .cmplz-dropdown p,
#cmplz-document .cmplz-dropdown h4,
#cmplz-document .cmplz-dropdown ul {
	box-sizing: border-box;
}

#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div,
#cmplz-document .cmplz-dropdown .cookies-per-purpose div {
	box-sizing: border-box;
	min-width: 0;
	overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------------------
   THE COOKIE POLICY PANELS TAKE THE SITE'S COLOURS

   The consent plugin draws its own panels in white, #f7f7f7 and #dadada. On a
   page whose ground is Abyss and whose body text is Beige, that put beige
   lettering on white: measured at 1.5 to 1 against a 4.5 minimum, which is a
   legal disclosure nobody can read. It was also four colours from outside the
   four, on a page that is otherwise brand.

   So the panels take the site's colours instead of being repainted around the
   plugin's. Panel and cells go to Abyss, lifted with Beige at low opacity so an
   Abyss panel is not sitting on an Abyss page behind nothing but a rust
   hairline, which is a closed fault. Section 4 radius, section 1 pairing.

   Measured after, on both cookie pages at 390 and at 1440: every value 9 to 1
   or better, both headings clear of the large-text threshold, was 1.4 to 1.6.

   Two traps that both bit while writing this. The plugin's alternating-row and
   header-cell rules carry a heavier selector than its own cell rule, so setting
   only a tint here leaves the plugin's white underneath: the colour has to be
   set again on each. And a tint given as a translucent background COLOUR lets
   the grid's own ground through, so the tints are background IMAGES sitting on
   an opaque Abyss.
--------------------------------------------------------------------------- */
#cmplz-cookies-overview .cmplz-dropdown,
#cmplz-document .cmplz-dropdown {
	background-color: rgba(214, 201, 174, 0.06);
	border: 1px solid var(--wp--preset--color--rust);
	border-radius: 15px;
	overflow: hidden;
}
#cmplz-cookies-overview .cmplz-dropdown summary,
#cmplz-document .cmplz-dropdown summary {
	background-color: rgba(214, 201, 174, 0.12);
}
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose,
#cmplz-document .cmplz-dropdown .cookies-per-purpose {
	background-color: rgba(214, 201, 174, 0.22);
	border: 1px solid rgba(214, 201, 174, 0.22);
	border-radius: 15px;
	overflow: hidden;
}
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div,
#cmplz-document .cmplz-dropdown .cookies-per-purpose div {
	background-color: var(--wp--preset--color--abyss);
}
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose .name-header,
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose .retention-header,
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose .function-header,
#cmplz-document .cmplz-dropdown .cookies-per-purpose .name-header,
#cmplz-document .cmplz-dropdown .cookies-per-purpose .retention-header,
#cmplz-document .cmplz-dropdown .cookies-per-purpose .function-header {
	background-color: var(--wp--preset--color--abyss);
	background-image: linear-gradient(rgba(214, 201, 174, 0.12), rgba(214, 201, 174, 0.12));
}
@media only screen and (max-width: 600px) {
	#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+2),
	#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+3),
	#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+4),
	#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+5),
	#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+6),
	#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+7),
	#cmplz-document .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+2),
	#cmplz-document .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+3),
	#cmplz-document .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+4),
	#cmplz-document .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+5),
	#cmplz-document .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+6),
	#cmplz-document .cmplz-dropdown .cookies-per-purpose div:nth-child(12n+7) {
		background-color: var(--wp--preset--color--abyss);
		background-image: linear-gradient(rgba(214, 201, 174, 0.07), rgba(214, 201, 174, 0.07));
	}
}

/* ---------------------------------------------------------------------------
   SECTION 7.1 OF THE COOKIE POLICY, "MANAGE YOUR CONSENT SETTINGS"

   Four solid grey bars with the browser's own tick boxes in them, on a page
   that is otherwise the site. Every count on that page was green and only
   looking at it found this.

   Two separate things, and somebody had already fixed a third. The consent
   banner's own stylesheet carries hand-written overrides putting the category
   body on Abyss and its text on Beige, and those work. What they never covered
   is the header bar, which the document stylesheet paints with a half-white
   veil OVER that Abyss, so the bar came out grey and its label sat on it at
   1.4 to 1. That is one declaration.

   The tick boxes are the site's own, and NOT a second copy of them: the theme
   already draws real tick boxes and its selectors simply never reached here,
   because these controls are not inside a form. The consent checkbox has been
   added to those six existing rules instead. Change the tick box once and it
   changes here too, which is the whole point.

   Measured after, at 390 and at 1440: label 10.3 to 1 where it was 1.4, tick
   box 22px with the 3px rust edge and the 5px corner like every other one on
   the site, four categories, row height unchanged, nothing past the edge.
   The banner itself is untouched, because none of this is scoped to it.
--------------------------------------------------------------------------- */
#cmplz-manage-consent-container.cmplz-manage-consent-container .cmplz-categories .cmplz-category .cmplz-category-header {
	background-color: transparent;
}

/* ---------------------------------------------------------------------------
   MOBILE HERO VEIL. 12 August 2026, theme 0.9.16.
   At 390 the hero picture sits behind the copy, and the words and the outline
   button were landing on the brightest part of it, straight over the white
   cards. The flat veil was ruled out long ago: Gord, 3 August, with it on
   "the image just looks dull", with it off "the picture pops" but the copy
   cannot be read. twg-veil-fade solved that on desktop by fading sideways and
   left mobile alone, on the note that there was nowhere to fade to. There is,
   vertically: Gord's face is at the top, the words and the buttons are at the
   bottom. So the veil fades DOWN the section on mobile. Desktop untouched.
   Utility class twg-fill-mobile, home hero only.
--------------------------------------------------------------------------- */
@media (max-width: 781px){
  /* ⛔ THE HOME HERO ON A PHONE. COPIED FROM THE LIVE SITE, 27 August 2026.
     Gord: "look at what's on my live site and just do something similar to that
     and stop overcomplicating it."

     The live site does the obvious thing and it works:
       heading on plain dark  →  the photograph in a band of its own  →  the words

     The photograph is never behind any text. That is the entire trick, and six
     attempts at shading, reordering and full-height heroes all missed it.

     ⛔ ON STAGING THE PHOTOGRAPH IS THE SECTION'S BACKGROUND, not a picture block,
     which is why it kept ending up behind the copy. So on a phone the section's
     background is switched OFF and the same picture is put on the separator that
     already sits between the heading and the copy, which turns that separator into
     the photograph's own band. Nothing is added to the page and desktop is
     untouched.

     ⛔ IF THE HERO PICTURE IS EVER CHANGED, the URL below has to change with it.
     That is the one thing here that is written down twice. */

  /* The section stops carrying the picture. Plain abyss behind the words. */
  .wp-block-group.twg-fill-mobile{
    background-image: none !important;
  }
  .wp-block-group.twg-fill-mobile.twg-veil.has-background::before{
    background-image: none !important;
    background-color: transparent !important;
  }

  /* The separator becomes the picture's band: full width, its own space, nothing
     written on it. */
  .wp-block-group.twg-fill-mobile .wp-block-separator{
    border: 0 !important;
    /* ⛔ THE PHOTOGRAPH IS NOT CROPPED. Hero-Gord.png is a square cut-out of Gord,
       2000 x 2000. The first go set it to FILL a wide band, copying the shape of
       the live site's hero picture, which is a landscape strip. That chopped Gord's
       head and feet off. Gord: "why have you cropped the image?"
       So the band is square, matching the picture, and the picture is CONTAINed
       inside it. The whole of it shows, at any screen width. */
    aspect-ratio: 1 / 1;
    margin: var(--wp--preset--spacing--40) calc(var(--wp--style--root--padding-right, 1.25rem) * -1);
    background-image: url('/wp-content/uploads/2026/08/Hero-Gord.png');
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    opacity: 1;
  }

  /* ⛔ THE BUTTONS KEEP THEIR OWN COLOURS. An earlier go forced both of them to
     solid rust, because at that point the photograph was still behind them and the
     outlined one vanished into it. The photograph has its own band now and the
     buttons sit on plain abyss, so the theme's normal styles read perfectly well
     and the override was changing the look for no reason. Gord: "why have the
     button colours changed on mobile?" Only the SHAPE is set here: stacked and
     full width, so they are thumb sized. */
  .wp-block-group.twg-fill-mobile .wp-block-buttons{
    flex-direction: column;
    width: 100%;
  }
  .wp-block-group.twg-fill-mobile .wp-block-button{ width: 100%; }
  .wp-block-group.twg-fill-mobile .wp-block-button__link{
    width: 100%;
    text-align: center;
    padding-top: .9rem;
    padding-bottom: .9rem;
  }
}


@media (max-width: 781px) {
	.wp-block-social-links.twg-header-social {
		gap: 12px;
	}
	.twg-header-social .wp-block-social-links {
		gap: 12px;
	}
}

/* HEADER RIGHT SIDE. Menu and search on one line, a small social row tucked
   under it on the right, the way live does it. The socials are 16px on purpose:
   at 24 they compete with the menu and the whole bar grows a band. */
.twg-header-right {
	gap: 6px;
	align-items: flex-end;
}
.twg-header-navrow {
	gap: 18px;
	align-items: center;
}
.wp-block-social-links.twg-header-social {
	gap: 14px;
}
.twg-header-search .wp-block-search__button {
	background-color: transparent;
	border: 0;
	color: var(--wp--preset--color--rust);
	fill: var(--wp--preset--color--rust);
	padding: 0;
	min-width: 0;
	width: 20px;
	height: 20px;
}
.twg-header-search .wp-block-search__button svg {
	width: 20px;
	height: 20px;
	min-width: 20px;
}
.twg-header-search .wp-block-search__inside-wrapper {
	align-items: center;
}
.twg-header-search .wp-block-search__input {
	background-color: var(--wp--preset--color--abyss);
	border: 1px solid var(--wp--preset--color--rust);
	color: var(--wp--preset--color--beige);
}

/* On a phone the header is the logo, the menu and the search, nothing else.
   Eight icons wrap onto two rows there and grow the bar into a band, which is
   the exact thing that was thrown out. They are still in the footer. */
@media (max-width: 781px) {
	.wp-block-social-links.twg-header-social {
		display: none;
	}
}

/* MOBILE HEADER. Logo centred, menu and search on the right. The logo is taken
   out of the flow and centred on the bar rather than the row being stacked[CM] so
   the header stays one line high. */
@media (max-width: 781px) {
	.twg-header-inner {
		position: relative;
		justify-content: flex-end;
		min-height: 56px;
		align-items: center;
	}
	.twg-header-inner {
		justify-content: center;
	}
	.twg-header-inner > figure.twg-logo {
		margin: 0;
		width: auto !important;
	}
	.twg-header-inner > figure.twg-logo img {
		display: block;
	}
	/* No transform here. A transformed ancestor becomes the containing block for
	   anything fixed inside it[CM] which pinned the menu social row to this corner
	   instead of the bottom of the screen. */
	.twg-header-right {
		position: absolute;
		right: 0;
		top: 0;
		bottom: 0;
		justify-content: center;
	}
	/* The social row belongs in the menu on a phone[CM] at the bottom of it. */
	.twg-header-right:has(.is-menu-open) .wp-block-social-links.twg-header-social {
		display: flex;
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 100000;
		justify-content: center;
		gap: 20px;
		padding: 1.25rem 1rem;
		background-color: var(--wp--preset--color--abyss);
		border-top: 1px solid var(--wp--preset--color--rust);
	}
	/* Room at the end of the menu so the icon bar never sits over a link. */
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
		padding-bottom: 6rem;
	}
	.twg-header-right:has(.is-menu-open) .wp-block-social-links.twg-header-social .wp-block-social-link svg {
		width: 26px;
		height: 26px;
	}

	/* SEARCH TO THE LEFT CORNER. Gord, 13 August: next to the menu it crowded one
	   end of the bar[CM] on the left it frames the logo. Search, logo, menu.

	   The search sits inside the right-hand group in the markup, so that group and
	   the nav row are made static here and the two controls are pinned to their own
	   corners instead. Anchoring is on the header row, which is already relative.

	   NO TRANSFORMS on either. The menu overlay is fixed, and a transformed
	   ancestor would become its containing block and pin it to the header, which is
	   the fault the note further up this block already warns about. Centring is
	   done with top/bottom and flex. */
	.twg-header-right { position: static; }
	.twg-header-navrow { position: static; }

	.twg-header-search {
		position: absolute;
		left: 0;
		top: 0;
		bottom: 0;
		display: flex;
		align-items: center;
		margin: 0;
	}
	.twg-header-navrow > .wp-block-navigation {
		position: absolute;
		right: 0;
		top: 0;
		bottom: 0;
		display: flex;
		align-items: center;
	}
}

/* ---------------------------------------------------------------------------
   JUMP LINKS ON CARD AND SPREAD PAGES

   A card page carries eight filled gold pills directly under the card, before
   the reader has read a single word, and a spread page does the same. Gord,
   13 August: "all of these buttons that show up in the hero section, it's very
   overwhelming, why do we have so many buttons".

   They are useful, so they stay. What changes is their weight. They stop being
   eight of the loudest control on the site and become a quiet row of outlined
   links, so the real calls to action further down the page are the ones that
   read as buttons. The last one, View All Cards, is already an outline and now
   simply matches the rest.
--------------------------------------------------------------------------- */
.twg-card-jump .wp-block-button__link,
.twg-spread-jump .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--rust);
	border: 1px solid var(--wp--preset--color--rust);
	font-size: 0.78rem;
	font-weight: 700;
	padding: 7px 15px;
	letter-spacing: 0.02em;
}
/* SECONDARY HOVER, GORD'S SPEC: the rust goes copper, border and lettering
   both, and the ground stays out of it. This used to fill with rust and put
   abyss lettering on top, which is the PRIMARY pattern wearing a secondary
   button's clothes. There are two patterns and this is the second one. */
.twg-card-jump .wp-block-button__link:hover,
.twg-card-jump .wp-block-button__link:focus,
.twg-spread-jump .wp-block-button__link:hover,
.twg-spread-jump .wp-block-button__link:focus {
	background-color: transparent;
	color: var(--wp--preset--color--copper);
	border-color: var(--wp--preset--color--copper);
}
/* ⛔ THE BEIGE EXCEPTION IS GONE, 15 August 2026. It said the rust outline was
   "too pale to find" on beige and swapped it to abyss, then filled it abyss on
   hover with beige lettering. That is the same override that was wrong on the
   outline button, written twice in two places, and it is not Gord's spec. The
   jump pills are secondary buttons: rust line, rust lettering, copper on hover,
   on every ground. See the block by the outline button rules. */
.twg-card-jump .wp-block-buttons,
.twg-spread-jump .wp-block-buttons {
	gap: 0.5rem;
	justify-content: center;
}

/* ---------------------------------------------------------------------------
   THE FIRST BAND ON A PAGE

   A band in the middle of a page needs a full section's air above it to read as
   a new section. The first band does not: it already has the header above it,
   so the same measurement just prints a gap between the menu and the heading.
   Learn Tarot was opening with a full 128px, against the home page hero's 42px,
   which is the "strange gap at the top" Gord reported.
--------------------------------------------------------------------------- */
.entry-content > .wp-block-group.alignfull:first-child {
	padding-top: var(--wp--preset--spacing--40);
}

/* ---------------------------------------------------------------------------
   READABILITY ON A LIGHT GROUND

   Sections that were built to sit on Abyss carry light text. If one of them is
   later given the beige ground, that text would be light on light. This is the
   backstop: on beige, body copy is Abyss unless it has deliberately been given
   its own colour. Rust headings and rust links are untouched.
--------------------------------------------------------------------------- */
.has-beige-background-color {
	color: var(--wp--preset--color--abyss);
}
.has-beige-background-color :where(p, li, blockquote, dd, dt, figcaption):not([class*="has-"][class*="-color"]) {
	color: var(--wp--preset--color--abyss);
}

/* ---------------------------------------------------------------------------
   REVIEWS

   The stars and the reviewer's name were both left-aligned, so a review read as
   one ragged left column and the name looked like the start of another line of
   the quote rather than the person who said it. Name to the right, stars centred
   and larger, which is the shape people expect a review to be.
--------------------------------------------------------------------------- */
.twg-reviews .twg-review__name{
	text-align: right;
	display: block;
	width: 100%;
}
.twg-reviews .twg-review__stars{
	text-align: center;
	display: block;
	width: 100%;
	font-size: 1.6rem;
	line-height: 1.2;
	letter-spacing: 0.08em;
}

/* ---------------------------------------------------------------------------
   CUT-OUT PHOTOGRAPHS SIT FLUSH ON THE BAND EDGE

   The photographs of Gord are cut out with a straight bottom, so they are drawn
   to stand ON a surface. On a phone the columns stack, the picture ends up last
   in its band, and the band's own bottom padding then printed a strip of beige
   underneath it. Gord, 13 August: it should be flush "like is in the hero".

   Two things caused the strip. The band's bottom padding, and the image being
   an inline element, which leaves a few pixels of text baseline under it.
--------------------------------------------------------------------------- */
@media (max-width: 781px) {
	.wp-block-group.has-background:has(> .wp-block-columns:last-child > .wp-block-column:last-child > .wp-block-image:last-child) {
		padding-bottom: 0;
	}
	.wp-block-group.has-background > .wp-block-columns:last-child > .wp-block-column:last-child > .wp-block-image:last-child {
		margin-bottom: 0;
	}
	.wp-block-group.has-background > .wp-block-columns:last-child > .wp-block-column:last-child > .wp-block-image:last-child img {
		display: block;
	}
}

/* The footer menus are centred under the centred brand block. Left-aligned
   lists under a centred logo is what made it look lopsided. */
footer .wp-block-columns .wp-block-list {
	list-style: none;
	margin: 0;
	padding: 0;
	text-align: center;
}

/* ---------------------------------------------------------------------------
   SINGLE PAGE FURNITURE, added 14 August with single.html and
   single-testimonial.html.

   Gord found both faults on a phone and described them the same way: the title
   "flush with the divider between the menu and the title". Neither template had
   a band under its heading, so the H1 started on the header hairline. The bands
   are in the templates; these are the two small pieces of type that go with them.
--------------------------------------------------------------------------- */
.twg-eyebrow{
	margin: 0 0 0.4rem;
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	font-size: 0.85rem;
	color: var(--wp--preset--color--rust);
}

.twg-post-meta{
	margin-top: 0.9rem;
	gap: 0.4rem 1.1rem;
	font-size: 0.9rem;
	opacity: 0.85;
}
.twg-post-meta .wp-block-post-date,
.twg-post-meta .wp-block-post-terms{ margin: 0; }

/* A featured image is a photograph, not a tile, so it is not cropped and it does
   not carry the card corner. The radius came off every image in theme.json on
   14 August because Gord found it on the blog: "all of the images seem to have
   this border radius around them that should not be there". */
.wp-block-post-featured-image.is-style-twg-contain img{
	width: 100%;
	height: auto;
	max-height: 480px;
	object-fit: contain;
	border-radius: 0;
}

/* ---------------------------------------------------------------------------
   SEARCH BOXES OUTSIDE THE HEADER

   Only `.twg-header-search` was ever styled, so every other search box on the
   site rendered as a raw browser input: white ground, grey hairline, square
   corners, nothing to do with this site.

   Gord, 14 August, on the card meanings page on a phone: "the search bar is
   completely unbranded, it's white around, there's no styling on it whatsoever."
   Same box on the search results page and in the Help Centre.

   This is deliberately NOT scoped to one page. Any core search block anywhere
   that is not the header one now looks like it belongs here.
--------------------------------------------------------------------------- */
.wp-block-search:not(.twg-header-search) .wp-block-search__inside-wrapper{
	border: 3px solid var(--wp--preset--color--abyss);
	border-radius: 30px;
	background-color: var(--wp--preset--color--beige);
	padding: 3px;
	max-width: 34rem;
}
.has-abyss-background-color .wp-block-search:not(.twg-header-search) .wp-block-search__inside-wrapper{
	border-color: var(--wp--preset--color--rust);
}
.wp-block-search:not(.twg-header-search) .wp-block-search__input{
	border: 0;
	background: transparent;
	color: var(--wp--preset--color--abyss);
	font-family: var(--wp--preset--font-family--raleway);
	font-size: 1rem;
	padding: 0.65rem 1rem;
	min-width: 0;
}
.wp-block-search:not(.twg-header-search) .wp-block-search__input::placeholder{
	color: var(--wp--preset--color--abyss);
	opacity: 0.6;
}
.wp-block-search:not(.twg-header-search) .wp-block-search__input:focus{
	outline: 2px solid var(--wp--preset--color--copper);
	outline-offset: 2px;
	border-radius: 26px;
}
.wp-block-search:not(.twg-header-search) .wp-block-search__button{
	margin: 0;
	background-color: var(--wp--preset--color--rust);
	color: var(--wp--preset--color--abyss);
	border: 3px solid var(--wp--preset--color--abyss);
	border-radius: 30px;
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	padding: 12px 22px;
	cursor: pointer;
}
.wp-block-search:not(.twg-header-search) .wp-block-search__button:hover,
.wp-block-search:not(.twg-header-search) .wp-block-search__button:focus{
	background-color: var(--wp--preset--color--copper);
}

/* On a phone the box and the button stack rather than squeezing the field down
   to nothing. The whole review was done on a phone. */
@media (max-width: 600px){
	.wp-block-search:not(.twg-header-search) .wp-block-search__inside-wrapper{
		flex-direction: column;
		align-items: stretch;
		border-radius: 22px;
		gap: 3px;
	}
	.wp-block-search:not(.twg-header-search) .wp-block-search__button{ width: 100%; }
}

/* ---------------------------------------------------------------------------
   THE BOOKING DIALOG SCROLLS. THE PAGE BEHIND IT DOES NOT.

   14 August. Gord, on a phone: "the booking widget scrolls and the page scrolls
   so it's confusing."

   Amelia already locks this, and it is not enough. It sets `overflow:hidden` on
   BODY, and on this site the element that actually scrolls is HTML, which stays
   `visible`. Measured with the dialog open: body hidden, html visible, page still
   scrollable. So the overlay scrolls, and the whole page slides about underneath
   it at the same time.

   `:has()` rather than a class on the body, because the class would have to be
   added and removed by script that watches a third party dialog, and Amelia
   already tells us it is open by putting its overlay in the document.

   Both of Amelia's dialog overlays are named, rather than any `.el-overlay`,
   because Element Plus overlays are used by other things and a blanket rule
   would lock the page for a toast notification.
--------------------------------------------------------------------------- */
/* ⚠️ `overflow:hidden` ON HTML DOES NOTHING HERE AND I TRIED IT FIRST.
   Measured with the dialog open: html and body were BOTH already hidden, and the
   page still scrolled, because the html box is as tall as the whole document
   (9595px) rather than the viewport. There is nothing for hidden to clip.
   Forcing a viewport height would work and would throw the page back to the top
   the moment the dialog opened, which is worse than the fault.

   What Gord actually described is scroll CHAINING: you scroll the booking, the
   booking reaches its end, and the page behind carries on moving. That is what
   `overscroll-behavior: contain` exists for, and it needs no script and no
   layout change. */
.el-overlay.am-dialog-popup,
.amelia-v2-booking.am-forms-dialog,
.el-overlay.am-dialog-popup .el-overlay-dialog,
.el-overlay.am-dialog-popup [class*="am-dialog"]{
	overscroll-behavior: contain;
}

/* ---------------------------------------------------------------------------
   HANDS OFF AMELIA'S OWN CONTROLS

   14 August. Gord, on a phone: "the tick boxes on the booking form don't seem to
   show. When I try and agree to the terms and conditions, it doesn't tell me
   whether I've clicked Agree or not."

   The cause is ours. The theme restyles checkboxes and radios inside
   `.wp-block-post-content form`, which is right for our own forms and for PMPro.
   Amelia's booking dialog is printed by a shortcode that lives in page content,
   so it sits inside that same wrapper and gets caught by it.

   Amelia does not use a bare checkbox. It draws its own control and keeps the
   real input for the state. Our rule sets `appearance: none` on that input and
   paints a box over it, so the tick Amelia relies on never appears and nothing
   changes when you agree to the terms.

   ⛔ THE RULE THIS SETS: our form styling stops at the edge of somebody else's
   application. Amelia gets its controls back exactly as it shipped them.
--------------------------------------------------------------------------- */
.amelia-v2-booking input[type="checkbox"],
.amelia-v2-booking input[type="radio"],
.el-overlay.am-dialog-popup input[type="checkbox"],
.el-overlay.am-dialog-popup input[type="radio"],
.amelia-app-booking input[type="checkbox"],
.amelia-app-booking input[type="radio"]{
	appearance: auto;
	-webkit-appearance: auto;
	width: auto;
	height: auto;
	min-width: 0;
	margin: initial;
	padding: initial;
	background-color: initial;
	background-image: none;
	border: initial;
	border-radius: initial;
	display: inline-block;
	place-content: initial;
	vertical-align: baseline;
}
.amelia-v2-booking input[type="checkbox"]::before,
.amelia-v2-booking input[type="radio"]::before,
.el-overlay.am-dialog-popup input[type="checkbox"]::before,
.el-overlay.am-dialog-popup input[type="radio"]::before{
	content: none;
}

/* ---------------------------------------------------------------------------
   ⛔ THE OUTLINE BUTTON IS RUST ON EVERY GROUND. DO NOT "FIX" IT AGAIN.

   Gord's button specification, restated 15 August 2026:

     PRIMARY    abyss border, abyss lettering, rust ground.
                Hover: the ground goes copper.
     SECONDARY  rust border, rust lettering, transparent ground, plus a faint
                knock-back only when it sits over a picture.
                Hover: the rust goes copper. Border and lettering both.

   That is it. There is no light-band exception and there never was.

   ⚠️ WHAT WAS HERE AND WHY IT IS GONE. On 14 August I measured rust lettering on
   a beige band at 2.17:1, decided that was a fault, and wrote an override making
   the outline button abyss on every light ground, filling it abyss on hover and
   turning the lettering beige. Beige lettering hovering on a beige band is
   invisible, which is what Gord photographed on 15 August. Gord: "half the
   outline buttons on the site seem to be wrong. this is not ok."

   Rust on beige is Gord's settled choice, already recorded for headings at the
   same ratio. **A contrast measurement is not permission to overrule a stated
   design decision.** If the contrast ever needs revisiting, that is a
   conversation with Gord, not a rule quietly added to this file.

   The base rules further up already do the right thing: --twg-ink is rust on
   abyss and on beige, abyss on rust and copper (because rust on rust cannot be
   read), and --twg-ink-hover carries it to copper. Nothing needs adding here.
--------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   CUT-OUT PICTURES SIT ON THE EDGE OF THEIR BAND. NO STRIP UNDERNEATH.

   Gord has now raised this three times, on the home page, on both reading pages
   and on the spread pages: "adding this sort of margin at the bottom of images,
   I bet it's the case on the home page as well, because I bet you still have not
   sorted it. You have not sorted it for EVERY image like this."

   Right, and the earlier fix was scoped to one component, which is why it kept
   coming back somewhere else. These are cut-outs of Gord with the background
   removed, and they are drawn to stand ON the join between two bands. Anything
   under them reads as a mistake.

   The strip comes from two places and both are handled here rather than per
   component: an inline image sits on the text baseline and leaves a few pixels
   of descender space under it, and a figure carries a bottom margin from the
   block editor. So every figure inside a split loses its margin and every image
   inside one becomes a block aligned to the bottom.

   ⚠️ SCOPED TO SPLITS AND BANDS ON PURPOSE. A picture in the middle of a blog
   post still wants its normal spacing.
--------------------------------------------------------------------------- */
.twg-card-split__figure,
.twg-card-split figure,
.twg-location-hero__figure{
	margin-block: 0;
}
.twg-card-split__figure img,
.twg-card-split figure img,
.twg-location-hero__figure img{
	display: block;
	margin-bottom: 0;
	vertical-align: bottom;
}
/* ⛔ ONLY A CUT-OUT STANDS ON THE JOIN. NOT EVERY PICTURE.
   Where a cut-out is the last thing in a band, the band gives up its bottom
   padding so the figure lands on the join rather than floating above it. This
   rule was written without exceptions and it caught the gift voucher, which is
   a finished graphic with its own ground and its own border and wants room
   underneath it like anything else. Gord, 14 August: "you're almost treating
   every image as if it's operating in the same way and they need to not be."
   Any band that is a framed graphic rather than a cut-out is excluded here. */
.twg-card-section--band:not(.twg-location-gift-band):not(.twg-location-members):has(> .twg-card-split:last-child > .twg-card-split__figure:last-child),
.twg-card-section--band:not(.twg-location-gift-band):not(.twg-location-members):has(> * > .twg-card-split:last-child > .twg-card-split__figure:last-child){
	padding-block-end: 0;
}


/* ═══════════════════════════════════════════════════════════════════════════
   19 AUGUST 2026. Moved here out of the Site Editor's Additional CSS.

   ⛔ NOTHING BELONGS IN ADDITIONAL CSS. It went in there on the morning of the
   19th only because the theme files were unreachable, and it stayed there out
   of habit for a few hours after they came back. Gord: "we shouldn't have
   anything in additional css." The box is empty again and it stays empty.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ---------------------------------------------------------------------------
   CARD BORDERS ARE 3px, THE SAME AS LIVE

   The rebuild drew them at 1px. ⛔ THE SELECTOR HAS TO WEIGH MORE THAN
   `.wp-block-group.is-style-twg-card`, which is 0-2-0, or it loses in silence
   and every card stays thin while looking plausibly thick in a screenshot.
   The card and spread tiles carry their own 1px rule printed inline by
   twg-core, so they need naming too.
--------------------------------------------------------------------------- */
body .wp-block-group.is-style-twg-card{ border-width: 3px; }

body .twg-card-tile.is-style-twg-card,
body .twg-spread-tile.is-style-twg-card,
body .twg-tiles .is-style-twg-card{ border-width: 3px; }

/* ---------------------------------------------------------------------------
   SOCIAL ICONS, A TOUCH BIGGER

   Core's "small" is 16px. Gord wanted them a teeny bit bigger, so 20px.
--------------------------------------------------------------------------- */
header .wp-block-social-links.has-small-icon-size{ font-size: 20px; }

/* ---------------------------------------------------------------------------
   THE CARD SEARCH BOX BELONGS ON THE FULL CARD MEANINGS PAGE AND NOWHERE ELSE

   Gord, 19 August: "There should only be one at the top of all of the tarot
   cards. Any other section that's showing just a few of the cards, there
   shouldn't be a search fucking thing."

   It was appearing above every short run of cards, on the court cards page and
   the rest, as an unstyled white browser box sitting in the first card's grid
   slot.

   ⚠️ 11735 IS THE CARD MEANINGS PAGE ON STAGING. Check that ID on live before
   this goes across, or the box shows everywhere again. The real fix is for
   twg-core to stop printing it on a partial query, and this is the stopgap.

   ⚠️ twg-core prints its own styles inline in the body, so these carry an extra
   selector to win. Anything else overriding twg-card-filter needs the same.
--------------------------------------------------------------------------- */
body:not(.page-id-11735) .twg-card-filter{ display: none; }

body .twg-tiles > .twg-card-filter{ grid-column: 1 / -1; }

/* The card filter had a THIRD copy of the field design here, with a `body`
   prefix so it beat the one rule. Gone: it is named in the one rule now. */


/* ---------------------------------------------------------------------------
   A FREEBIE POP-UP BUTTON INSIDE A CARD SITS WITH THE REST OF THE CARD

   `[twg_freebie mode="popup"]` renders its button as its own full-width block,
   so it breaks out of the paragraph it was written into and ignores any
   centring on that paragraph. It landed hard against the left edge of a card
   whose heading and copy were centred. Centre the button's own wrapper instead.
--------------------------------------------------------------------------- */
body .is-style-twg-card > .wp-block-button,
body .is-style-twg-card .has-text-align-center + .wp-block-button{ text-align: center; }


/* ---------------------------------------------------------------------------
   21 AUGUST 2026. CUT-OUTS AND THE JOIN. ONE CONTROL, WORKS AT EVERY WIDTH.

   A cut-out of Gord is drawn to stand on the join between two bands. Where the
   subject is visibly chopped, the chop has to land on that join. Where Gord is
   resting on something, the picture carries on past the join so the join reads
   as the table.

   ⛔ THIS IS THE FOURTH REWRITE AND THE FIRST THREE ALL FAILED THE SAME WAY:
   they used a fixed number of pixels. The picture scales with the window and a
   fixed number does not, so every one of them was right at one width and wrong
   at every other. Gord, 21 August: "they work on some fucking widths. They
   don't work on other fucking widths... there needs to be a way to set the
   bottom of the image so that we can ensure that the overhang is consistent,
   regardless of how wide the screen is."

   So the overhang is a PERCENTAGE OF THE PICTURE'S OWN HEIGHT, applied as a
   transform. The picture and its overhang scale together, at every width, for
   ever, and no other measurement on the page changes.

   HOW TO USE IT ON A NEW PICTURE. Put twg-cutout on the SECTION, then set two
   things in that section's own style:

     --twg-cutout-pad    the band's bottom padding, written the same way the
                         band writes it, so it cancels exactly. Almost always
                         var(--wp--preset--spacing--60).
     --twg-cutout-drop   how far past the join the picture goes, as a
                         percentage of the picture's own height.
                           0%    chopped subject, stands on the join
                           15%   resting on something, join reads as the table

   It is a percentage of the picture's height whatever shape the picture is, so
   there is nothing to work out and nothing to convert.

   ⛔ THE BAND'S OWN PADDING IS NEVER TOUCHED. Gord, 21 August: "You're not meant
   to fucking fuck with the rest of the content. The margins for the rest of the
   content need to be fucking respected." Only the picture moves. The heading,
   the copy and the button stay exactly where they were.

   ⛔ OPT IN. A finished graphic with its own ground, the gift voucher above all,
   wants room underneath it like any other picture and never gets this class.

   ⛔ IT IS FOR THE TWO-COLUMN BANDS ONLY, where one column is copy and the other
   is nothing but the picture. The Learn Tarot hero puts its picture in amongst
   the heading and the copy rather than in a column of its own, so this does not
   apply to it and it was taken back off.
--------------------------------------------------------------------------- */
/* The picture's column fills the row and puts the picture at the very bottom of
   it, so the starting point is the same whichever column happens to be taller.
   Scoped to a column that holds nothing but the picture, so a column with copy
   in it as well is never rearranged. */
body .wp-block-group.twg-cutout .wp-block-columns > .wp-block-column:has(> figure.wp-block-image:only-child){
	align-self: stretch;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
}

/* ⛔ THE MOVE IS A TRANSFORM, NEVER A MARGIN, AND THIS IS THE WHOLE TRICK.
   A negative bottom margin on the picture shortens the column it lives in. The
   column is then re-anchored to the bottom of the row, which puts the picture
   straight back where it started. That is why the margin version looked correct
   on the reading page, where the picture is the taller column, and did nothing
   at all on Meet Gord, where the text is taller. A transform moves what you see
   and changes no measurement, so it works whichever column happens to be taller
   and nothing else on the page shifts by a pixel.

   translateY resolves a percentage against the element's OWN height, so
   --twg-cutout-drop is a straight percentage of the picture's height and holds
   at every window width without anyone touching it again. */
body .wp-block-group.twg-cutout figure.wp-block-image{
	transform: translateY(calc(var(--twg-cutout-pad, 0px) + var(--twg-cutout-drop, 0%)));
	line-height: 0;
	position: relative;
	z-index: 1;
}

body .wp-block-group.twg-cutout figure.wp-block-image img{
	display: block;
	margin-block-end: 0;
	vertical-align: bottom;
}

/* ⛔ ON A PHONE THE PICTURE STANDS ON THE JOIN AND NEVER HANGS OVER IT, AND THIS
   IS NOT THE SAME MISTAKE AS THE HALVING.

   On a laptop the picture is in a column of its own beside the copy, so what
   hangs below the join hangs over empty space next to the following heading.
   On a phone the columns stack, the picture goes full width and centred, and
   anything hanging below lands directly on top of the next heading. Gord sent a
   phone screenshot of exactly that, with a hand across "In-Person Tarot".

   0.9.74 tried halving it, which was arbitrary and still collided. 0.9.75 took
   the phone rule out altogether, which collided harder. The honest answer is
   that the overhang is a side-column flourish and there is no side column on a
   phone, so it goes to nothing and the picture stands cleanly on the join.
   That is a deliberate difference with a reason, not a fudged number. */
@media (max-width: 781px){
	body .wp-block-group.twg-cutout figure.wp-block-image{
		transform: translateY(var(--twg-cutout-pad, 0px));
	}
}


/* ---------------------------------------------------------------------------
   21 AUGUST 2026. BUTTONS IN A ROW OF COLUMNS LINE UP WITH EACH OTHER.

   Gord, 21 August, on Learn Tarot: "Those buttons look fucking lopsided."
   They were. Three columns, three different lengths of copy, so each button sat
   wherever its own paragraph happened to finish and the third one floated 31
   pixels above the other two.

   The column becomes a column-direction flex box and the last row of buttons
   takes the leftover space above it, so every button in the row lands on the
   same line no matter how much copy is above it.

   ⛔ OPT IN. A column whose button is meant to follow straight on from its text
   should not be dragged to the floor.
--------------------------------------------------------------------------- */
body .twg-buttons-baseline > .wp-block-column{
	display: flex;
	flex-direction: column;
}

body .twg-buttons-baseline > .wp-block-column > .wp-block-buttons:last-child{
	margin-block-start: auto;
}

/* Stacked there is only one column on screen at a time, so there is nothing to
   line up with and the gap would just be dead space. */
@media (max-width: 781px){
	body .twg-buttons-baseline > .wp-block-column > .wp-block-buttons:last-child{
		margin-block-start: var(--wp--preset--spacing--40);
	}
}


/* ---------------------------------------------------------------------------
   22 AUGUST 2026. BUTTONS FOLLOW THE HEADING THEY SIT UNDER.

   Every band on the site centres its heading and then left-aligns the button
   underneath it, which reads as unfinished. Gord, 22 August, on Learn Tarot:
   "this weird fucking justification of all the buttons to the left. It looks
   fucking gross."

   The rule is deliberately narrow: a row of buttons that FOLLOWS a centred
   heading inside the same container gets centred with it. Buttons in a column
   next to a picture, or under left-aligned copy, are untouched, because the
   selector needs the centred heading as a sibling before it does anything.
--------------------------------------------------------------------------- */
body .wp-block-heading.has-text-align-center ~ .wp-block-buttons{
	justify-content: center;
}


/* ---------------------------------------------------------------------------
   23 AUGUST 2026. HERO PHOTOGRAPHS CARRY THE BRAND'S COLOURS, NOT THEIR OWN.

   Gord, on the Membership hero: "There's a fucking unlicensed colour on the
   background of the hero section. It looks awful."

   They were right, and it was never going to be fixed by darkening it. The
   photograph has a bright purple top in it and a pair of blue jeans, and no
   amount of dimming turns purple into abyss, it only turns it into dark purple.
   Circle and Workshops looked fine by luck, because the pictures picked for them
   happen to be warm and brown already. Luck is not a rule.

   So every hero photograph is stripped of its own colour and put back in the
   brand's: greyscale first, which kills the purple outright, then a warm brown
   over the top. Any picture dropped into any hero now comes out on-brand, and
   nobody has to look at a photograph and judge it.

   ⛔ THE FILTER IS ON THE PICTURE, NEVER ON THE SECTION. A filter on an ancestor
   makes that ancestor the containing block for anything fixed inside it. The
   sign-up overlay is fixed and lives inside sections like these, and that is
   exactly the fault fixed on the same day: the dark overlay stopped 215px in
   from each edge because a layout rule had caught it. Filtering the section
   would reintroduce it. The picture has no children, so it is safe.

   ⛔ THIS NEEDS THE COVER'S PARALLAX SWITCHED OFF. With parallax on, WordPress
   paints the photograph as a background on the section itself and there is no
   picture to filter, only the section. That is why the four service heroes had
   parallax removed on the same day. A hero with parallax still on gets no
   treatment and will look wrong next to the others.
--------------------------------------------------------------------------- */
.wp-block-cover img.wp-block-cover__image-background,
.wp-block-cover video.wp-block-cover__video-background{
	filter: grayscale(1) sepia(0.42) saturate(1.35) brightness(0.92);
}


/* ---------------------------------------------------------------------------
   23 AUGUST 2026. A BAND'S WORDS TAKE THEIR COLOUR FROM THE BAND.

   Gord: "everything needs to be in the theme not in the fucking blocks, this is
   exactly the fucking piecemeal shit I've complained about before."

   Right, and it was worse than untidy. Earlier the same day a band was flipped
   from beige to abyss and its words stayed abyss, so a whole section of the
   Course page was dark text on a dark ground and could not be read at all. The
   fix at the time was to write a text colour onto every band by hand. That put
   styling in the content, and it broke the blocks: WordPress compares the saved
   class list against what it would generate itself, the hand-written classes did
   not match, and three groups on Free Tarot Shit came up as needing recovery.
   A block that will not parse is a block Gord cannot edit.

   So the rule lives here, once. Set a band's background and its words follow.
   Nothing needs a text colour in the editor, and flipping a band can no longer
   hide its own copy.
--------------------------------------------------------------------------- */
body .wp-block-group.has-abyss-background-color,
body .wp-block-cover.has-abyss-background-color{
	color: var(--wp--preset--color--beige, #d6c9ae);
}

body .wp-block-group.has-beige-background-color{
	color: var(--wp--preset--color--abyss, #1f1c1d);
}

/* Anything that sets its own ground keeps its own words. The reviews strip is
   the one that caught this out: it sits inside a band and paints its own
   background, so it must not inherit the band's text colour. */
body .wp-block-group .twg-reviews--abyss{ color: var(--wp--preset--color--beige, #d6c9ae); }
body .wp-block-group .twg-reviews--beige{ color: var(--wp--preset--color--abyss, #1f1c1d); }

/* ---------------------------------------------------------------------------
   AN EMPTY BAND TAKES NO SPACE AT ALL.

   `single-service.html` carries a fallback band for the questions, and it draws
   nothing when the questions have already been swapped into the page content,
   which is what happens on three of the four service pages. The band still had
   its padding and its margin, so it left about sixty-five pixels of dead ground
   above the footer. Gord, 24 August, looking at the Circle page on a phone:
   *"the spacing on the circle page is just wrong, and it's gross."*

   The template's own comment said a rule like this existed. It did not.

   `:empty` matches an element with no children and no text, so a band with
   anything in it, even a single space, is untouched.
--------------------------------------------------------------------------- */
body .wp-block-group.alignfull.has-background:empty{
	display: none !important;
}

/* ---------------------------------------------------------------------------
   ⛔ ON A PHONE THE PICTURE ALWAYS GOES ON TOP.

   Every one of these pages alternates: words on the left with a picture on the
   right, then a picture on the left with words on the right, all the way down.
   That is what makes it feel like a page rather than a list, and on a wide
   screen it works.

   Stacked on a phone it fell apart, because the rows just stack in the order
   they were written. So half the sections showed the picture first and half
   showed it after the words, at random, and the alternation that was the whole
   point of the layout turned into a mess. Gord, 25 August: *"On mobile, it
   looks disgraceful. We need to make sure that if a heading image or something
   is to the right on desktop, it's showing above on mobile."*

   ⛔ ONLY WHERE THE PICTURE IS THE SECOND OF TWO. `:nth-child(2):last-child`
   means exactly two columns, so a three-across row of text is never touched,
   and the `:not(:has(...))` means a row that already leads with its picture is
   left exactly as it is. Nothing here reorders words.

   ⛔ AND IT IS wrap-reverse, NOT column-reverse. Below 782px core stacks these
   by letting each column take a full-width flex line, so reversing the LINE
   order is what moves the picture up. `flex-direction: column-reverse` turns
   the 100% basis into a height and collapses the row.

   The `!important` is only there to beat core's own `flex-wrap: wrap !important`.
--------------------------------------------------------------------------- */
@media (max-width: 781px) {

	.wp-block-columns:not(.is-not-stacked-on-mobile):has(
			> .wp-block-column:nth-child(2):last-child :is(img, figure, .wp-block-image, .wp-block-video)
		):not(:has(
			> .wp-block-column:first-child :is(img, figure, .wp-block-image, .wp-block-video)
		)) {
		flex-wrap: wrap-reverse !important;
	}
}


/* ===========================================================================
   AMELIA, BROUGHT ONTO THE SAME FIELD AND BUTTON DESIGN

   Gord, 28 August: "I just want you to make sure that that's consistent across
   all Amelia booking forms as well, if we can. Consistency is key. I want this
   to feel like one website."

   AMELIA IS ENTIRELY DRIVEN BY ITS OWN DESIGN TOKENS, which is the whole reason
   this is a short block and not fifty overrides. Read off the rendered booking
   dialog on 28 August: the button is `--am-rad-btn`, `--am-padd-btn`,
   `--am-fw-btn`, `--am-c-btn-*`, and the fields are Element Plus underneath,
   on `--el-border-radius-base`. Set the tokens to the site's own numbers and the
   widget follows on its own.

   ⛔ SO DO NOT ADD PER-ELEMENT OVERRIDES HERE. If something in Amelia looks
   wrong, find the token it reads and set that. The only rules below the tokens
   are the three things Amelia has no token for: the border WIDTH, the uppercase
   lettering, and Element Plus drawing its field border as a box-shadow rather
   than a border.

   ⛔ AND ITS LABELS ARE LEFT ALONE ON PURPOSE. Gord wants the visible label gone
   where a placeholder can say it instead, but Amelia's fields are configured in
   its own admin and not every one has placeholder text. Hiding the label site
   wide would leave some fields with nothing to say what they are.
   =========================================================================== */

.amelia-v2-booking,
.amelia-v2-booking #amelia-container,
#amelia-container {
	--am-rad-input: var(--wp--custom--radius--box, 15px);
	--am-rad-btn: var(--wp--custom--radius--pill, 30px);
	--am-padd-btn: 12px 22px;
	--am-fw-btn: 900;
	--am-fs-btn: 1rem;
	--am-h-btn: auto;
	--am-lh-btn: 1.15;
	--am-c-btn-bgr: var(--wp--preset--color--rust);
	--am-c-btn-border: var(--wp--preset--color--abyss);
	--am-c-btn-text: var(--wp--preset--color--abyss);
	--el-border-radius-base: var(--wp--custom--radius--box, 15px);
	--el-input-border-radius: var(--wp--custom--radius--box, 15px);
	--el-component-size: auto;
}

/* The border WIDTH and the lettering have no token. */
.amelia-v2-booking .am-button {
	border-width: 3px !important;
	text-transform: uppercase;
	letter-spacing: 0.12em;
}

.amelia-v2-booking .am-button__inner {
	text-transform: uppercase;
	letter-spacing: inherit;
	font-weight: inherit;
}

.amelia-v2-booking .am-button--filled:hover,
.amelia-v2-booking .am-button--primary:hover {
	background-color: var(--wp--preset--color--copper) !important;
}

/* Element Plus paints a field's border as a box-shadow, so a border here would
   sit outside the one it already draws and the field would gain 6px. An inset
   shadow keeps the geometry identical and reads as the site's 3px rust edge. */
.amelia-v2-booking .el-select__wrapper,
.amelia-v2-booking .el-input__wrapper,
.amelia-v2-booking .el-input__inner,
.amelia-v2-booking .el-textarea__inner,
.amelia-v2-booking .el-select__selected-item:not(.el-select__placeholder) {
	color: var(--wp--preset--color--rust) !important;
}

.amelia-v2-booking .el-select__wrapper,
.amelia-v2-booking .el-input__wrapper,
.amelia-v2-booking .el-textarea__inner {
	box-shadow: inset 0 0 0 3px var(--wp--preset--color--rust) !important;
	padding: 0.7rem 0.9rem !important;
	min-height: 0 !important;
}

.amelia-v2-booking .el-select__wrapper.is-focused,
.amelia-v2-booking .el-input__wrapper.is-focus,
.amelia-v2-booking .el-textarea__inner:focus {
	box-shadow: inset 0 0 0 3px var(--wp--preset--color--copper) !important;
}

.amelia-v2-booking .el-select__placeholder,
.amelia-v2-booking .el-input__inner::placeholder,
.amelia-v2-booking .el-textarea__inner::placeholder {
	color: var(--wp--preset--color--beige) !important;
	opacity: 0.55 !important;
}


/* ===========================================================================
   ONE HIDDEN LABEL CLASS

   Gord, 28 August: "where possible, we don't have a description above it.
   Obviously, we have that for screen readers, but that's hidden, and the
   preview text is what tells them what it is, like first name, last name."

   So every field's label stays in the markup, tied to its field, and is drawn
   off screen instead of above the box. This is the standard recipe. It was NOT
   defined anywhere in this theme, so anything already using the class was
   relying on WordPress's own stylesheet being present.
   =========================================================================== */

.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

.screen-reader-text:focus {
	clip-path: none;
	height: auto;
	left: 5px;
	top: 5px;
	width: auto;
	z-index: 100000;
}


/* ===========================================================================
   ONE COMPONENT HEADING

   The same audit that found six field designs found headings written eleven
   different ways across the plugins: Raleway spelled five ways, weights of 600,
   700 and 900, and colours as raw hex rather than the site's own.

   ⛔ SO THE FAMILY, THE WEIGHT AND THE INK ARE SET ONCE, HERE, and every
   component heading class is named below. The plugin stylesheets keep only the
   SIZE, because that is a per-component scale decision and genuinely differs
   between a card panel title and a pop-up heading. Everything else does not.

   The ink is `--twg-heading-ink`, not a fixed rust, so a heading on a beige
   panel goes abyss on its own without a second rule. That variable is already
   how the band colours work.

   ⛔ SIZES WERE DELIBERATELY LEFT ALONE. Changing a heading's size moves the
   layout around it, and doing that blind across eleven components is how you
   break five pages to tidy one stylesheet. Bring them onto the preset scale
   deliberately, one component at a time, looking at each.
   =========================================================================== */

.twg-card-panel__title,
.twg-card-reading__title,
.twg-card-section__title,
.twg-plain-section__h,
.twg-draw__one h3,
.twg-fbl__title,
.twg-fbl__h,
.twg-pop__h,
.twg-readings__title,
.twg-reviews__title,
.twg-pitch__h,
.twg-pitch__screenh,
.twg-rd-action-h,
.twg-rd-obstacle h4,
.twg-rd-people h4,
.twg-st-heading,
.twg-totw-vgate__heading,
.twg-totw-vgate__subheading,
.twg-totw-preview__title,
.twg-totw-upcoming-title,
.twg-pop__headline {
	font-family: var(--wp--preset--font-family--raleway);
	font-weight: 900;
	color: var(--twg-heading-ink, var(--wp--preset--color--rust));
}

/* A link inside one of those headings is the heading, not a link. */
.twg-totw-preview__title a,
.twg-totw-upcoming-title a {
	color: inherit;
	text-decoration: none;
}

.twg-totw-preview__title a:hover,
.twg-totw-upcoming-title a:hover {
	color: var(--wp--preset--color--copper);
}
