/* ==================================================================
 * iTech Valet — main stylesheet
 *
 * Hand-written. No framework, no build step, no preprocessor.
 *
 * EVERY colour and size lives in section 01 as a token. Nothing below
 * section 01 may contain a raw hex value or a raw font size. If you find
 * yourself typing "#063a6c" further down, add a token instead.
 *
 * The token values were extracted from the LIVE stylesheets of the old
 * Beaver Builder site on 2026-08-21 (migration/capture_design.py), not
 * eyeballed from screenshots.
 *
 * 01 TOKENS
 * 02 RESET AND BASE
 * 03 TYPOGRAPHY
 * 04 LAYOUT
 * 05 BUTTONS
 * 06 HEADER AND NAV
 * 07 FOOTER
 * 08 PROSE
 * 09 ARTICLE LISTINGS
 * 10 WORDPRESS BLOCK CORRECTIONS
 * 11 ACCESSIBILITY UTILITIES
 * 12 BACK TO TOP
 * ================================================================== */


/* ==================================================================
 * 01 TOKENS
 * ================================================================== */

:root {
	/* Brand */
	--c-navy:       #063a6c;
	--c-blue:       #2494e0;
	--c-blue-mid:   #2b7bb9;
	--c-blue-pale:  #cfe8fc;
	--c-orange:     #dd6b00;
	--c-amber:      #fba702;

	/* Neutrals */
	/* PURE BLACK, measured off the live DOM - every body paragraph on the live
	   homepage computes rgb(0,0,0). A softened ink is the usual house style and
	   it is wrong here: at Lexend 300 the #3d3d3d read visibly lighter than the
	   original, which is the single biggest reason the rebuild looked "off"
	   next to a screenshot of the real thing. */
	--c-ink:        #000000;
	--c-white:      #ffffff;
	--c-grey-line:  #e6e6e6;
	--c-grey-mid:   #a3a3a3;
	--c-grey-soft:  #f6f8fb;
	/* THE ARTICLE CARD'S OWN FILL, and it is #f2f2f2 on purpose: it is the
	   grey the LIVE BODY is, which means on the live site a card is exactly
	   the same colour as the page behind it and exists only by its border
	   and its shadow. This site's ground is white (see --c-page), so the
	   same value now reads as a tint - a card that looks like a card. The
	   number is transcribed; the effect is better than the original's by
	   accident of Gerek's background call. */
	--c-card-fill:  #f2f2f2;
	--c-page-chip:  #f5f5f5;   /* the current page number's chip, measured */

	/* TWO DARKENED BRAND STEPS, and they exist for one reason: 14px text on
	   --c-card-fill. --c-blue measures 2.94:1 there and --c-orange 3.04:1,
	   against the 4.5:1 floor for text under 18.66px. These are the same
	   hues far enough down to clear it - 4.81:1 and 4.93:1 on the card,
	   5.38:1 and 5.52:1 on white. They are NOT general-purpose colours: use
	   --c-blue and --c-orange everywhere the type is large enough. */
	--c-blue-deep:   #26709f;
	--c-orange-deep: #a94f00;
	/* GEREK'S CALL, and it overrides the measurement. The original body is
	   #f2f2f2; this site's page background is pure white. Do not "restore" the
	   grey because the migration export measures it - the export is the source
	   of truth for geometry and type, not for this. */
	--c-page:       #ffffff;

	/* Roles — always reference these, not the raw brand names above */
	--c-text:       var(--c-ink);
	--c-heading:    var(--c-navy);
	--c-link:       var(--c-blue-mid);
	--c-link-hover: var(--c-navy);
	--c-bg:         var(--c-white);
	--c-rule:       var(--c-grey-line);

	/* INLINE LINKS IN BODY COPY - the five knobs section 02b reads.
	   These are the DEFAULT, which is the articles' treatment: blue, no
	   underline, orange on hover. A block that cannot carry it overrides
	   the five on itself rather than writing a link rule of its own, so
	   the rule exists in exactly one place. See 02b for the measurement
	   that decides which blocks those are. */
	--link-ink:                  var(--c-link);
	--link-rule:                 none;
	--link-rule-thickness:       1px;
	--link-ink-hover:            var(--c-orange);
	--link-rule-hover:           var(--link-rule);
	--link-rule-hover-thickness: 1px;

	/* Type families */
	--f-display: "Bebas Neue", "Haettenschweiler", Impact, sans-serif;
	--f-body:    "Lexend", system-ui, -apple-system, "Segoe UI", sans-serif;
	--f-accent:  "Chewy", "Comic Sans MS", cursive;

	/* Type scale */
	/* Measured on the live homepage at 375, 768, 820, 900, 1100 and 1280.
	   The coefficients are chosen so each reaches its upper value BY 768 -
	   8vw and 12vw got there at 875 and 917, which left the hero 4-9px small
	   across the whole tablet range. The accent has a genuine third step: it
	   is 100px from 768 all the way to 1100 and only 110 at desktop. */
	--t-hero:    clamp(2.9375rem, 9.1vw, 70px);    /* 47 at 375, 70 from 768 */
	--t-accent:  clamp(3.75rem, 13.02vw, 100px);   /* 60 at 375, 100 from 768 */
	--t-h1:      clamp(2.25rem, 4.5vw, 3.5rem);
	--t-h2:      clamp(2.5rem, 4.7vw, 60px);    /* the MOBILE value; stepped below */
	--t-h3:      clamp(1.25rem, 2vw, 1.625rem);
	--t-body:    1.0625rem;
	/* Measured: 22px in section bodies. The coefficient is 1.72vw, not 1.7 -
	   at the 1280 measuring viewport 1.7vw resolves to 21.76px and the clamp
	   never actually reaches the value it was measured at. 1.72vw hits 22px
	   at exactly 1280. */
	--t-lead:    clamp(1.25rem, 1.72vw, 22px);   /* the MOBILE value; stepped below */
	--t-small:   0.9375rem;
	--t-nav:     1.0625rem;    /* 17px - measured 20px read too heavy at this scale */

	--lh-tight:  1.05;
	--lh-head:   1.15;
	--lh-body:   1.7;
	--lh-lead:   1.45;         /* measured: 31.9px on 22px */

	/* Spacing — the small end is fixed, the large end is fluid. */
	--s-1:  0.25rem;
	--s-2:  0.5rem;
	--s-3:  0.75rem;
	--s-4:  1rem;
	--s-5:  1.5rem;
	--s-6:  2rem;
	--s-7:  3rem;
	--s-8:  clamp(2.5rem, 6vw, 4rem);
	--s-9:  clamp(3rem, 8vw, 6rem);
	--s-band: clamp(3rem, 7.8vw, 100px);   /* full section band, measured 100px */

	/* Structure */
	/* TWO widths, measured. The header, hero and footer run to 1400; every
	   content band is 1200. Using 1400 throughout is what made the page read
	   as too wide and off-balance - the bands were never meant to reach as
	   far as the hero does. */
	--container:      1400px;   /* header, hero, footer */
	--container-band: 1200px;   /* every content section */
	--gutter:         20px;     /* measured: row padding is 100px 20px */
	--measure:        68ch;
	--radius-pill:    999px;
	--radius:         10px;
	--header-h:       92px;

	--shadow-cta:  0 2px 10px rgba(6, 58, 108, 0.25);
	--shadow-card: 0 1px 3px rgba(6, 58, 108, 0.08), 0 8px 24px rgba(6, 58, 108, 0.06);

	/* THE LIFTED STATE OF --shadow-card, for a card under a pointer. Same
	   two-layer navy tint, roughly doubled, so the tile reads as having
	   come up off the page rather than as having grown a darker edge. */
	--shadow-card-lifted: 0 2px 6px rgba(6, 58, 108, 0.12), 0 14px 34px rgba(6, 58, 108, 0.12);

	/* LIVE'S CARD SHADOW, and it is OPAQUE - `3px 2px 15px rgb(61,61,61)`,
	   no alpha at all, which is a dark grey halo rather than a shadow. It
	   is the only thing separating a card from the page on the original,
	   because that card is the same colour as that page. This theme's card
	   is white on white with --shadow-card instead; see section 09.

	   STILL IN USE: the five Start Here photographs on /learn/ carry it,
	   where it is the original's and looks right on pale artwork. */
	--shadow-card-hard: 3px 2px 15px rgb(61, 61, 61);

	--ease: 160ms ease;
}


/* THE TYPE STEPS WHERE THE ORIGINAL STEPS - 768 and 992, not a ramp.
 *
 * The clamps above are the MOBILE scale. They were written to be exact at
 * 1280 and 375, and they are; between those they decay smoothly while the
 * original holds its desktop values all the way down to 993 and then takes
 * one step. On an iPad at 820 that put the body copy at 20px against the
 * original's 22 and every section heading at 40px against 50 - Gerek:
 * "everything is just too small on tablet."
 *
 * Both floors are already reached by 768 (4.7vw is 36px there, 1.72vw is
 * 13px), so these two queries change NOTHING at or below 768 and nothing at
 * or above 1280. They fill in the middle, which is the part that was wrong.
 *
 * --t-h2 also feeds `.prose h2`, so this moves article headings in the same
 * range. That is the same correction, not a side effect: the articles were
 * decaying for the same reason.
 */
/* 600, NOT 769. The step was written to the original's own breakpoint, and
   that turned out to leave the most common tablet on the phone scale: an
   iPad mini is 744pt in portrait, and every small tablet sits between 600
   and 834. Gerek, on a mini: "I do not see the font size increased. Feels
   like it's 18."

   600 is the line between a phone and a tablet, not between two of Beaver
   Builder's breakpoints - the widest phone in portrait is about 430, so
   nothing hand-held is caught by it, and a phone turned landscape reading at
   tablet sizes is correct anyway. The LAYOUT breakpoints are untouched:
   only the type moves here. */
@media (min-width: 600px) {
	:root {
		--t-h2:   50px;
		--t-lead: 22px;
	}
}

@media (min-width: 993px) {
	:root { --t-h2: 60px; }
}

/* The legal pages set their own heading size and so are not carried by
   --t-h2 - but their clamp decays exactly the same way. Same correction,
   applied by the same principle rather than from its own measurement: the
   value is the desktop size this page already ships. */
@media (min-width: 600px) {
	.page--legal .prose h2 { font-size: 40px; }
}


/* The accent's own upper step. Measured 100px at 1100 and 110px at 1280, so
   the change is above 1100 - 1201 is BB's large breakpoint and lands both
   measurements correctly. */
@media (min-width: 1201px) {
	:root { --t-accent: 110px; }
}


/* ==================================================================
 * 02 RESET AND BASE
 * ================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/* WHITE, everywhere. Any band without its own artwork or fill sits on pure
   white - the hopium row, the phones row, the engine row. The original's
   #f2f2f2 body is deliberately not carried over; see --c-page above. */
body {
	margin: 0;
	background: var(--c-page);
	color: var(--c-text);
	font-family: var(--f-body);
	font-size: var(--t-body);
	font-weight: 300;
	line-height: var(--lh-body);
	/* NO -webkit-font-smoothing. It was set to `antialiased`, which thins every
	   glyph on macOS; the live site leaves it at `auto` and its text is
	   noticeably heavier as a result. Lexend 300 has little weight to spare,
	   so this was compounding the light ink above. Do not re-add it. */
}

img, svg, video { max-width: 100%; height: auto; display: block; }

strong, b { font-weight: 700; }

a { color: var(--c-link); text-decoration-thickness: 1px; text-underline-offset: 2px; }

/* The :not() is load-bearing. On previous iTV themes a bare a:hover rule
   outranked .cta-button and repainted button labels invisible three separate
   times. Any global link rule must exempt buttons. */
a:not(.cta-button):not(.to-top):hover { color: var(--c-link-hover); }

:focus-visible { outline: 3px solid var(--c-amber); outline-offset: 2px; }


/* ==================================================================
 * 02b INLINE LINKS IN BODY COPY - ONE RULE FOR THE WHOLE SITE
 *
 * Gerek, 2026-08-25: "Make inline link styling consistent across the
 * whole site, matching the articles."
 *
 * THE RULE, and it is the articles' own: --c-link, no underline,
 * --c-orange on hover. It lives here now rather than in article.css,
 * so /learn/, the six page templates and all 156 articles read the
 * same declaration. 78 prose links across the site match it.
 *
 * WHY THE SELECTOR NAMES ITS CONTAINERS. A bare `.site-main a` would
 * repaint three COMPONENTS that are links but are not prose: the
 * article cards (`.article-card__link`), the /learn/ topic tiles
 * (`.lrn-start__media`) and the pagination (`.page-numbers`). Every
 * one of those was censused in the rendered HTML of nine pages plus an
 * article, and every one sits OUTSIDE a p/li/dd/blockquote/figcaption
 * /td/th, while all 78 prose links sit inside one. Naming the
 * containers is what separates them; excluding the components by class
 * would need this list to be kept in step with every new component.
 *
 * SPECIFICITY, and it is load-bearing for the fourth time on this
 * build. This is (0,3,2) at rest and (0,4,2) on hover, so it clears
 * main.css's own `a:not(.cta-button):not(.to-top):hover` at (0,3,1) -
 * the rule that has silently repainted four separate pages' links navy
 * during this rebuild. Nothing below needs to restate the :not()s.
 *
 * ---- THE ONE EXCEPTION ------------------------------------------
 *
 * A link in body copy has to clear TWO bars, not one:
 *
 *   1. 4.5:1 against the ground actually behind it, and
 *   2. 3:1 against the copy AROUND it - because dropping the underline
 *      makes colour the only thing marking it as a link (WCAG 1.4.1,
 *      technique G183).
 *
 * Every inline link on the site was measured against the real artwork
 * pixels at 375 and 1280 - the artwork composited into a canvas at the
 * band's own background-size/position and read back, cross-checked
 * against an independent PIL decode of the same file, agreeing to
 * 0.06. The numbers are in BUILD-PLAN.md.
 *
 * TWO WHOLE CATEGORIES CANNOT SATISFY BOTH, AND NOT FOR WANT OF A
 * BETTER BLUE - it is arithmetic, and no colour exists that does it:
 *
 *   Copy that is --c-navy on white. Bar 1 needs relative luminance
 *   <= 0.1833; bar 2 needs >= 0.2244. Empty range. --c-link measures
 *   4.53:1 on the ground and 2.53:1 against the navy.
 *
 *   White copy on dark artwork. --c-blue-pale reads 5.02-12.85 on the
 *   artwork and 1.26:1 against the white copy beside it; --c-link is
 *   1.00-3.59 on the artwork. One bar or the other, never both.
 *
 * Where both bars cannot be met the link takes the copy's own colour
 * and KEEPS AN UNDERLINE, thickening to 2px on hover. The underline is
 * then the affordance, and it is the only one that works on any ground.
 * That is what the six page stylesheets were each doing separately,
 * with three different hover gestures between them and two of them
 * broken; it is now one declaration.
 * ================================================================== */

.site-main :is(p, li, dd, dt, blockquote, figcaption, td, th) a:not(.cta-button):not(.to-top) {
	color: var(--link-ink);
	text-decoration: var(--link-rule);
	text-decoration-thickness: var(--link-rule-thickness);
}

.site-main :is(p, li, dd, dt, blockquote, figcaption, td, th) a:not(.cta-button):not(.to-top):hover,
.site-main :is(p, li, dd, dt, blockquote, figcaption, td, th) a:not(.cta-button):not(.to-top):focus-visible {
	color: var(--link-ink-hover);
	text-decoration: var(--link-rule-hover);
	text-decoration-thickness: var(--link-rule-hover-thickness);
}

/* THE OFFSET IS DELIBERATELY NOT IN THE RULE ABOVE. It stays on the base
   `a` in section 02 at (0,0,1), so the two components below and the
   article CTA can each set their own 3px without a specificity fight. */

/* THE EXCEPTION, as a utility. A block carrying this keeps the copy's
   colour and an underline. It is applied by the page stylesheets, each
   of which records the ratio that put its own bands here. */
.links-inherit {
	--link-ink:                  currentColor;
	--link-ink-hover:            currentColor;
	--link-rule:                 underline;
	--link-rule-hover:           underline;
	--link-rule-hover-thickness: 2px;
}


/* ==================================================================
 * 03 TYPOGRAPHY
 * ================================================================== */

h1, h2, h3, h4 {
	margin: 0 0 var(--s-4);
	color: var(--c-heading);
	font-weight: 700;
	line-height: var(--lh-head);
}

/* Bebas Neue is a condensed all-caps display face. It is drawn uppercase, so
   the transform makes mixed-case source copy render as designed. */
.hero__headline,
.section-title,
h1.page-title,
h2.section-title {
	font-family: var(--f-display);
	font-weight: 400;
	letter-spacing: normal;
	text-transform: uppercase;
	line-height: 1;
}

h1.page-title    { font-size: var(--t-h1); }

/* Measured: 60px above, 20px below - the heading is not tight to its band. */
h2.section-title {
	margin: clamp(2rem, 4.7vw, 60px) 0 20px;
	font-size: var(--t-h2);
	line-height: 1.1;
}
h3               { font-size: var(--t-h3); }

.lead { font-size: var(--t-lead); line-height: var(--lh-lead); }

/* Measured on the live DOM: paragraphs in every band sit 10px apart, never the
   browser's 1em. With the UA default the copy columns ran ~100px taller than
   the original and the page read airy where it should read compact.

   Bottom margin only, so it collapses against .prose's own `> * + *` rhythm
   and leaves article spacing alone. */
p { margin: 0 0 10px; }


/* ==================================================================
 * 04 LAYOUT
 * ================================================================== */

.container {
	width: 100%;
	max-width: var(--container);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

/* Measured per row - band padding is NOT one value:
     phones · blue · closing          20 / 20
     disqualifiers · method · engine  20 / 60
     hopium                           20 / 100
     credentials                      100 / 0
   Applying 20/60 everywhere left the even bands visibly lopsided. */
.section { padding-block: 20px; }
.section--pad60 { padding-bottom: clamp(2.5rem, 4.7vw, 60px); }

/* Content bands are narrower than the hero.

   The gutter sits on the SECTION, not inside the container, so the container's
   1200px is 1200px of usable width - as it is in the original. Putting the
   gutter inside made the real width 1160 and shifted every element 20px
   right, which read as the whole page being off-centre. */
.section { padding-inline: var(--gutter); }
.section > .container { max-width: var(--container-band); padding-inline: 0; }
.section--hero > .container { max-width: var(--container); padding-inline: 0; }

/* Stacked columns need less air between them than side-by-side ones do. */
@media (max-width: 860px) {
	.split { gap: var(--s-5); }
}

.section--tight { padding-block: 20px; }
/* 100px of tail. Used by Hopium and by the phones band, whose closing line
   sat tight against the blue row underneath it. */
.section--deep  { padding-bottom: clamp(3rem, 7.82vw, 100px); }

.section--navy {
	background: linear-gradient(135deg, var(--c-navy) 0%, var(--c-blue) 100%);
	color: var(--c-white);
}
.section--navy h1,
.section--navy h2,
.section--navy h3 { color: var(--c-white); }

.section--pale { background: var(--c-grey-soft); }
.section--white { background: var(--c-white); }

.page-header { margin-bottom: var(--s-7); }


/* ==================================================================
 * 05 BUTTONS
 * ================================================================== */

/* Measured off the live hero button: a 3px white ring and a real drop
   shadow, not a flat pill. The gradient runs left-to-right (90deg), not
   top-to-bottom. */
.cta-button {
	display: inline-block;
	padding: var(--s-3) var(--s-6);
	border: 3px solid var(--c-white);
	border-radius: 100px;
	background: linear-gradient(90deg, var(--c-amber) 0%, var(--c-orange) 100%);
	box-shadow: 3px 2px 10px rgba(61, 61, 61, 0.55);
	color: var(--c-white);
	font-family: var(--f-body);
	font-size: var(--t-body);
	font-weight: 700;
	line-height: 1.3;
	text-align: center;
	text-decoration: none;
	transition: background var(--ease), box-shadow var(--ease),
	            transform var(--ease), filter var(--ease);
}

/* Hover: the gradient REVERSES. That colour change is what does the work -
   it says "clickable" on its own. The lift is deliberately small (1px);
   at 2px the movement started competing with the colour instead of
   supporting it. */
.cta-button:hover,
.cta-button:focus-visible {
	background: linear-gradient(90deg, var(--c-orange) 0%, var(--c-amber) 100%);
	box-shadow: 4px 3px 12px rgba(61, 61, 61, 0.55);
	transform: translateY(-1px);
	color: var(--c-white);
}

/* Pressed. Without this a button feels inert at the moment of the click -
   the one moment the feedback actually matters. */
.cta-button:active {
	transform: translateY(0);
	box-shadow: 1px 1px 5px rgba(61, 61, 61, 0.5);
	filter: brightness(0.95);
}

/* Measured: 26px Lexend, padding 20px 40px. */
.site-header__cta {
	white-space: nowrap;
	flex: 0 0 auto;
	padding: 10px 26px;
	border-width: 2px;
	font-size: 0.9375rem;
	box-shadow: 2px 1px 6px rgba(61, 61, 61, 0.35);
}

.cta-button--lg {
	padding: 20px 40px;
	font-size: clamp(1.125rem, 2vw, 26px);
	font-weight: 400;
}


/* ==================================================================
 * 06 HEADER AND NAV
 * ================================================================== */

/* NOT STICKY. It scrolls away with the page, as the original does - nothing
   on the live site is sticky or fixed. Gerek's call, and it takes the scroll
   shadow with it: that shadow existed only to separate a floating bar from
   content sliding underneath, and nothing slides underneath a header that
   scrolls away. */
/* RELATIVE, AND THAT IS LOAD-BEARING - it is not a leftover of the sticky
   header. The mobile menu panel is `position: absolute; inset: 100% 0 auto 0`,
   which needs a positioned ancestor to mean "directly under the header".
   Without one it resolved against the initial containing block, so the panel
   opened 100% of a VIEWPORT down the page: the hamburger worked, the icon
   animated to an X, and the menu appeared one full screen below the fold
   where nobody would find it. The site had no working mobile navigation.

   It broke in 4e7456c, which removed `position: sticky` and `z-index` when
   Gerek asked for the header to scroll away. That commit verified the header
   computed `static` - the thing it changed - and not the panel that depended
   on it. Same lesson as the CSS move that silently killed six backgrounds:
   after a refactor, re-check the things the refactor was NOT about.

   The z-index comes back too, on its own merit: it makes the header a
   stacking context so the open panel paints over the page instead of
   interleaving with whatever the first band happens to contain. */
.site-header {
	position: relative;
	z-index: 50;
	background: var(--c-blue-pale);
	border-bottom: 1px solid rgba(6, 58, 108, 0.08);
}

.site-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--s-5);
	min-height: var(--header-h);
}

.site-header__logo { flex: 0 0 auto; display: block; }
.site-header__logo img { width: auto; max-height: 64px; }

.site-header__wordmark {
	font-family: var(--f-display);
	font-size: 1.75rem;
	color: var(--c-navy);
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

/* Desktop: dissolve the wrapper so logo / menu / CTA space out across the
   header. Measured on the original: the menu sits near the centre, not
   pushed against the CTA. */
.site-header__collapse { display: contents; }

/* Menu sits hard right, against the CTA, rather than centred in the bar. */
.site-nav {
	display: flex;
	align-items: center;
	margin-left: auto;
}

.site-nav__list {
	display: flex;
	align-items: center;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Measured: Lexend 20px, weight 300, 14px padding each side - so the
   visual gap between labels is 28px, not the 32px a gap property gave.

   The vertical padding is what gives the hover pill its height. It is padding
   rather than a fixed height so the pill always wraps the label. */
.site-nav__list a:not(.cta-button) {
	display: inline-block;
	padding: 8px 20px;        /* more air between labels than the measured 14px */
	border-radius: 12px;
	color: var(--c-navy);
	font-size: var(--t-nav);
	font-weight: 300;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color var(--ease), color var(--ease);
}

/* HOVER ONLY. A translucent pill - the CTA's shape, softened, and light
   enough that the pale blue bar reads through it. There is deliberately no
   underline: it was doing this job before and Gerek does not want it. */
.site-nav__list a:not(.cta-button):hover {
	background-color: rgba(255, 255, 255, 0.6);
	color: var(--c-orange);
}

/* THE CURRENT PAGE IS ORANGE TEXT AND NOTHING ELSE. No pill, not even on
   hover - the pill is a pointer affordance, and painting one behind the page
   you are already on makes "here" and "about to go here" look the same. */
.site-nav__list .current-menu-item > a,
.site-nav__list .current_page_item > a { color: var(--c-orange); }

.site-nav__list .current-menu-item > a:hover,
.site-nav__list .current_page_item > a:hover { background-color: transparent; }

.nav-toggle { display: none; }


/* --- mobile ------------------------------------------------------ */

/* 1080, not 900. Logo + five items + the CTA needs ~1070px; below that the
   CTA ran past the right edge of the viewport and the whole document scrolled
   sideways. iPad landscape is 1024, which sat squarely inside the broken
   range. */
@media (max-width: 1080px) {

	.nav-toggle {
		display: block;
		/* Do not let flex shrink the target: it was being squeezed to 36px
		   between the logo and the CTA, under the 44px minimum. */
		flex: 0 0 auto;
		width: 44px;
		height: 44px;
		padding: 0;
		border: none;
		background: none;
		cursor: pointer;
	}

	.nav-toggle__bar,
	.nav-toggle__bar::before,
	.nav-toggle__bar::after {
		display: block;
		width: 26px;
		height: 2px;
		margin-inline: auto;
		background: var(--c-navy);
		transition: transform var(--ease), opacity var(--ease);
	}
	.nav-toggle__bar::before,
	.nav-toggle__bar::after { content: ""; position: relative; }
	.nav-toggle__bar::before { top: -8px; }
	.nav-toggle__bar::after  { top: 6px; }

	.nav-toggle[aria-expanded="true"] .nav-toggle__bar { background: transparent; }
	.nav-toggle[aria-expanded="true"] .nav-toggle__bar::before { transform: translateY(8px) rotate(45deg); }
	.nav-toggle[aria-expanded="true"] .nav-toggle__bar::after  { transform: translateY(-6px) rotate(-45deg); }

	/* The CTA stays in the bar; only the menu collapses. */
	.site-header__cta {
		margin-left: auto;
		padding: 9px 14px;
		font-size: 0.8125rem;
	}

	/* Let the logo give up width first, so the CTA keeps its single line. */
	.site-header__logo { flex: 0 1 auto; min-width: 0; }
	.site-header__logo img { max-height: 46px; }

	/* Mobile: the wrapper becomes a real element again and holds the panel. */
	.site-header__collapse {
		display: none;
		position: absolute;
		inset: 100% 0 auto 0;
		flex-direction: column;
		align-items: stretch;
		gap: var(--s-4);
		padding: var(--s-5) var(--gutter);
		/* WHITE, not the bar's pale blue. Gerek's call, and the reason is
		   that the panel was the same colour as the header it drops out of,
		   so opening the menu read as the bar getting taller rather than as
		   a panel over the page.

		   The shadow comes with the white: a white panel on a white page has
		   only a 1px rule holding it apart, which is not enough once it is
		   floating over content. Downward only - this is a dropdown, not a
		   card. */
		background: var(--c-white);
		border-bottom: 1px solid var(--c-rule);
		box-shadow: 0 10px 20px -10px rgba(6, 58, 108, 0.3);
	}

	.site-header__collapse.is-open { display: flex; }

	/* `margin-left: 0` UNDOES THE DESKTOP RULE. On desktop `.site-nav` carries
	   `margin-left: auto` to push the menu hard right against the CTA; inside
	   the mobile panel that auto margin survived and shoved the whole list
	   154px to the right of a 375px panel, which reads as badly centred rather
	   than as a menu. Gerek: "it looked weird." */
	.site-nav {
		flex-direction: column;
		align-items: stretch;
		margin-left: 0;
	}

	.site-nav__list {
		flex-direction: column;
		align-items: stretch;
		gap: var(--s-4);
	}

	/* Same specificity trap as section 02: a general rule for links inside the
	   mobile panel must not repaint the CTA label.
	   
	   No horizontal padding here, and the panel's own padding is the header
	   container's 20px, so the labels start exactly under the logo. Left with
	   the desktop pill's 20px the first character sat 44px in from the screen
	   edge, lining up with nothing. */
	.site-nav__list a:not(.cta-button) {
		display: block;
		padding-block: var(--s-2);
		padding-inline: 0;
	}

	/* Full-width rows, so the pill becomes a rounded bar. Same radius.
	
	   PALE BLUE, the inverse of the desktop pill. On desktop a translucent
	   WHITE pill sits on the pale blue bar; in a white panel that pill is
	   invisible, so the two colours swap. The hover now echoes the bar the
	   menu came out of, which is what ties the two together. */
	.site-nav__list a:not(.cta-button):hover { background-color: var(--c-blue-pale); }


}


/* ==================================================================
 * 07 FOOTER
 * ================================================================== */

.site-main { background: var(--c-bg); }

/* ONE PALE BLUE BAND, and it butts straight against the section above it.
   This had margin-top: var(--s-9), which opened ~96px of white between the
   closing band and the footer - invisible until the closing band grew, then
   very visible.

   It was also navy with the artwork sized `100% auto`, so the pale band only
   covered the top and everything below the logo sat on a navy strip the
   original does not have. The artwork covers now, and every glyph on it is
   navy. Measured: the whole band is 318px at 1280. */
.site-footer {
	padding-block: 40px;
	color: var(--c-navy);
	text-align: center;
}

/* MUST LIVE IN main.css. This sat in pages/home.css, which functions.php
   enqueues only when is_front_page() - so every other page rendered the footer
   logo uncapped at its intrinsic 600px and the footer looked like a different
   component. The footer is on every page; nothing that styles it belongs in a
   page stylesheet.

   Measured: 200px wide, and the blocks under it are each 20px apart - that
   margin belongs to them, not to the logo. */
.site-footer__logo {
	width: auto;
	max-width: 200px;
	margin: 0 auto;
}

/* EVERY footer link hovers to orange - the header nav's #dd6b00, so the two
   navigations answer the cursor the same way. Never an underline: it was the
   hover here and it read as a different component from the header.

   This covers the social discs too. Their mark is knocked out of a
   currentColor disc, so recolouring the link recolours the disc and leaves
   the glyph reading through it. */
.site-footer a {
	color: var(--c-navy);
	text-decoration: none;
	transition: color var(--ease);
}
.site-footer a:hover { color: var(--c-orange); }

/* Measured: five 35px discs on a 45px pitch, so 10px between them. */
.site-footer__social {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px;
	margin: 20px 0 0;
	padding: 0;
	list-style: none;
}

.site-footer__social a { display: block; line-height: 0; }

.social__icon { display: block; width: 35px; height: 35px; }

/* Measured: 16px, weight 300, no underline, and the gaps between labels are
   the links' own 20px padding - which also gives them a 44px tap target. */
.site-footer__list {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0;
	margin: 20px 0 0;
	padding: 0;
	list-style: none;
}

.site-footer__list a {
	display: block;
	padding: 14px 20px;
	/* The original runs 16px here. Gerek's call, in two passes: 16 -> 15 was
	   still heavy under the logo, so 13. Deliberately 3px off the original -
	   do not "restore" it to 16 on a fidelity pass. */
	font-size: 0.8125rem;
	font-weight: 300;
	line-height: 1;
}

.site-footer__legal {
	margin: 20px 0 0;
	color: var(--c-navy);
	font-size: 0.875rem;   /* measured: 14px, a step under --t-small's 15 */
	font-weight: 300;
	line-height: var(--lh-lead);   /* measured: 20.3px on 14 */
}


/* ==================================================================
 * 08 PROSE
 *
 * Editor-written copy only. AEO articles are EXCLUDED - they ship their
 * own scoped stylesheet and their own measure, and single.php does not
 * wrap them in this. See single.php.
 * ================================================================== */

.prose { max-width: var(--measure); }

/* Centre the reading column on articles and pages. The container stays 1200px
   because AEO articles bring their OWN wider container and must not be squeezed
   by a narrow parent - so the centring is applied to the reading column itself
   rather than to .container. The page title is centred with it so the two edges
   line up. */
.page-article .prose,
.page-article .page-title { margin-inline: auto; }
.page-article .page-title { max-width: var(--measure); }

.prose > * + * { margin-top: var(--s-5); }

.prose h2 { margin-top: var(--s-7); font-size: var(--t-h2); }
.prose h3 { margin-top: var(--s-6); }

.prose ul,
.prose ol { padding-left: var(--s-5); }
.prose li + li { margin-top: var(--s-2); }

.prose blockquote {
	margin-inline: 0;
	padding-left: var(--s-5);
	border-left: 3px solid var(--c-amber);
	color: var(--c-navy);
}

.prose img { border-radius: var(--radius); }

.prose table { width: 100%; border-collapse: collapse; }
.prose th,
.prose td { padding: var(--s-3); border-bottom: 1px solid var(--c-rule); text-align: left; }

/* Wide content must scroll inside itself rather than widening the page. */
.prose .table-wrap { overflow-x: auto; }


/* ==================================================================
 * 08b LEGAL PAGES
 *
 * Privacy Policy and Terms & Conditions only - the two pages that are
 * nothing but long-form text. Measured off the live pages at 1280 and 400.
 *
 * These deliberately do NOT use the .prose reading measure. The original
 * runs them at the full container width, and the brief was to match its
 * format. That is a long line for body copy; narrowing it is a one-line
 * change to the max-width below if it ever reads as too wide.
 * ================================================================== */

/* THE MEASURE, AND WHY IT IS NO LONGER `none`.
   Gerek, 2026-08-25: the body copy "feels a little too large... it needs
   to come down a little bit". It was 22px - measured, and the original's
   own value - on a 1200px column, which is 98 CHARACTERS PER LINE.

   Type size and line length are ONE decision here. Dropping the size on a
   1200px column pushes the line to about 120 characters and the page reads
   WORSE than the thing being complained about, because the eye loses its
   place on the return sweep rather than inside the word. So the column comes
   in as the type comes down.

   80ch is deliberately generous - still far wider than the 68ch .prose gives
   every other page - so these two keep reading as the full-width legal
   documents the original made them. Revert to `none` on this one line if the
   wide format is wanted back.

   The title stays full width and centred; only the reading column narrows.
   main.css's `.page-article .prose { margin-inline: auto }` centres it. */
.page--legal .page-article .prose { max-width: 80ch; }
.page--legal .page-article .page-title { max-width: none; }

/* Measured: 70px on 98px, weight 400, #333 - a lighter ink than the black
   body copy underneath it, and the only place on the site that uses it. */
.page--legal .page-title {
	margin: 20px 0;
	font-size: clamp(3.125rem, 5.47vw, 70px);   /* floor measured: 50px */
	line-height: 1.4;
	color: #333;
	text-align: center;
}

/* No .prose rhythm here: the original spaces this copy on its own margins -
   10px between paragraphs, 40px above each heading. */
.page--legal .prose > * + * { margin-top: 0; }

/* 18px AT EVERY WIDTH, down from the original's 22. The one size on the
   site that does not step, and the same 18 learn.css pins its intro to -
   see the note above on why the column narrowed with it. */
.page--legal .prose p,
.page--legal .prose ul,
.page--legal .prose ol {
	margin: 0 0 10px;
	font-size: 18px;
	line-height: var(--lh-lead);
	font-weight: 300;
	color: #000;
}

/* Measured: 40px on 56px Bebas, black, LEFT - not the uppercase navy of the
   section titles, and not centred like the page title. */
.page--legal .prose h2 {
	margin: 40px 0 20px;
	font-family: var(--f-display);
	font-size: clamp(1.875rem, 3.125vw, 40px);  /* floor measured: 30px */
	font-weight: 400;
	line-height: 1.4;
	color: #000;
	text-align: left;
	text-transform: none;
}

/* The standfirst and the effective date are centred; everything after them
   is left. Both pages open with exactly those two paragraphs, which is what
   makes first-child addressable rather than fragile. */
.page--legal .prose > p:first-child,
.page--legal .prose > p:first-child + p { text-align: center; }

/* Measured: 20px indent, discs, no gap between items. */
.page--legal .prose ul,
.page--legal .prose ol { padding-left: 20px; }
.page--legal .prose li + li { margin-top: 0; }

/* ONE HUNDRED PIXELS AT THE FOOT OF THE PAGE. Gerek's ask, and the same
   shape as the article template: the last child's margin is zeroed and the
   whole 100 is paid by the section, so the number in the file is the gap on
   screen rather than 90 + whatever the page happens to end on. It was 20. */
.page--legal .prose > :last-child { margin-bottom: 0; }
.page--legal .page-article { padding-bottom: 100px; }

/* THE PRIVACY POLICY SCROLLED SIDEWAYS ON A PHONE, and it was doing it
   before any of this session's changes. The page prints its third-party
   opt-out addresses as plain text, and the longest -
   `http://www.networkadvertising.org/understanding-online-advertising/how-does-it-work.`
   at 84 characters - cannot wrap, so it pushed the document 100px wider
   than a 375 viewport and took the header and footer with it.

   Found by asking for scrollWidth rather than by looking: nothing has a
   bounding box past the right edge, because the overflow is a text node
   inside a <li> that fits. `overflow-wrap: break-word` only acts on a word
   that would otherwise overflow, so ordinary copy is untouched.

   Verified: document.scrollWidth equals clientWidth at 375, 600, 993 and
   1280 on both pages after this. */
.page--legal .prose { overflow-wrap: break-word; }

@media (max-width: 860px) {
	.page--legal .prose h2 { line-height: 1.1; }
	.page--legal .page-title { line-height: 1.4; }
}


/* ==================================================================
 * 09 ARTICLE LISTINGS
 *
 * THE ARTICLES ARE THE ONE THING ON THIS SITE THAT IS NOT PER-PAGE.
 * Gerek, 2026-08-21: "this site is custom, so there's nothing that's
 * going to be consistent from page to page. It's the ARTICLES that are
 * set in stone." One card, one set of rules, adjusted once - and every
 * listing that shows one inherits it: /learn/, every topic page, and
 * search.
 *
 * THE MODEL IS THE PENINSULA CRE FEED, IN iTECH VALET'S COLOURS.
 * Gerek's call, 2026-08-25: "I like the Peninsula look and feel with the
 * way the cards are presented ... so use that model but for the iTV
 * branding." What came across is the BEHAVIOUR and the STRUCTURE - a
 * raised panel that is one link end to end, a lift and a slow image zoom
 * on hover, a clamped title and excerpt so a row stays level, and Read
 * More pinned to the foot of the tile. What did not come across is a
 * single colour or typeface: the face is Bebas, the ink is navy, the
 * date is this theme's blue and the link is its orange.
 *
 * FOUR THINGS CHANGED FROM THE LIVE CARD, AND ALL FOUR ARE THAT CALL:
 *
 * 1. WHITE, not live's #f2f2f2 fill. Live's card is the same colour as
 *    live's page, so it exists only by its border and its shadow. A
 *    white panel with a soft shadow is the Peninsula shape, and on the
 *    dark Browse All band a light card is the entire point.
 * 2. --shadow-card, not live's `3px 2px 15px rgb(61,61,61)`. That one is
 *    fully OPAQUE - no alpha at all - which is a dark grey halo rather
 *    than a shadow. --shadow-card was already in this file, already
 *    navy-tinted, and already this theme's answer.
 * 3. THE TITLE AND EXCERPT ARE CLAMPED to three lines each. Live lets
 *    both run and equalises the card heights with a matchHeight script
 *    after load - so a row is ragged until JavaScript runs, stays ragged
 *    if it does not, and the dates never line up with each other. Three
 *    lines and a flex column do it in CSS, with no layout shift.
 * 4. LEFT-ALIGNED. Live centres the title over a left-aligned date and
 *    excerpt. Two alignments inside one 275px tile is the thing that
 *    made the old row look unsettled.
 *
 * TWO COLOURS ARE NOT LIVE'S EITHER, and those are contrast rather than
 * taste - 14px text on the old #f2f2f2 fill measured 2.94:1 for the date
 * and 3.04:1 for Read More against a 4.5:1 floor. --c-blue-deep and
 * --c-orange-deep are the same hues two steps darker. They clear it on
 * white by a wider margin still.
 * ================================================================== */

.article-grid {
	display: grid;
	/* A neutral default for search. /learn/ and the topic pages set their
	   own column counts - three up inside a topic band, four up in Browse
	   All and on a topic page - because those are measured per band. */
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 20px;
}

/* The <article> is only the grid cell. Everything visible is the anchor
   inside it, so that the whole tile can be one link. */
.article-card { display: flex; }

.article-card__link {
	display: flex;
	flex: 1;
	flex-direction: column;
	overflow: hidden;               /* clips the image corners to the radius */
	border-radius: 15px;            /* live's own, kept */
	background: var(--c-white);
	box-shadow: var(--shadow-card);
	color: var(--c-navy);
	text-decoration: none;
	transition: transform var(--ease), box-shadow var(--ease);
}

/* THE LIFT IS 4px AND THE SHADOW DEEPENS WITH IT. Response-only, and it
   stops - see the motion policy in home.css. Nothing here loops. */
.article-card__link:hover,
.article-card__link:focus-visible {
	transform: translateY(-4px);
	box-shadow: var(--shadow-card-lifted);
}

/* 1408/768 IS THE ARTWORK'S OWN ASPECT, so nothing is cropped. Every
   featured image in the library is that shape. Peninsula uses 16/9 on the
   same files and loses about 3% off the sides; these are illustrations
   with type in them, so the source ratio is the safer of two answers that
   look identical.

   Held by aspect-ratio rather than a fixed height, so the picture scales
   with its column - and so one odd-shaped upload cannot make one tile
   taller than its row. */
.article-card__media {
	position: relative;
	display: block;
	overflow: hidden;
	aspect-ratio: 1408 / 768;
	/* A post with no featured image keeps the tile's shape instead of
	   collapsing to a white box. Pale blue, not grey - it reads as part of
	   the set rather than as a failure. */
	background: var(--c-blue-pale);
}

.article-card__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 400ms ease;
}

.article-card__link:hover .article-card__img,
.article-card__link:focus-visible .article-card__img { transform: scale(1.04); }

.article-card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 8px;
	padding: 20px;                  /* live's own, kept */
}

/* Bebas 24 on a 26px line - live's size, kept. Clamped to three lines so
   a long title cannot push its tile's date and excerpt out of line with
   the rest of the row; library titles run to eighteen words. */
.article-card__title {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	overflow: hidden;
	margin: 0;
	font-family: var(--f-display);
	font-size: 24px;
	font-weight: 400;
	line-height: 26px;
	letter-spacing: normal;
	text-transform: uppercase;
	color: var(--c-navy);
	transition: color var(--ease);
}

.article-card__link:hover .article-card__title,
.article-card__link:focus-visible .article-card__title { color: var(--c-blue-mid); }

/* The date, and nothing else - live's card meta prints no author and no
   category either. The tracking is what stops a small date reading as an
   afterthought under a 24px display face. */
.article-card__date {
	display: block;
	font-size: 14px;
	font-weight: 300;
	line-height: 22px;
	letter-spacing: 0.4px;
	color: var(--c-blue-deep);
}

/* 16px, against live's 14. A three-line clamp gives the excerpt a fixed
   share of the tile, so the extra two points cost nothing in height and
   buy a readable measure on a 275px card. */
.article-card__excerpt {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	overflow: hidden;
	font-size: 16px;
	font-weight: 300;
	line-height: 1.5;
	color: var(--c-navy);
}

/* PUSHED TO THE FOOT OF THE TILE, so every Read More in a row sits on one
   line however far the titles above them differ. It is a span, not a
   link - the anchor around it already is one. */
.article-card__more {
	display: block;
	margin-top: auto;
	padding-top: 8px;
	font-size: 16px;
	font-weight: 600;
	line-height: 22px;
	color: var(--c-orange-deep);
	text-decoration: underline;
	text-decoration-color: var(--c-orange);
	text-underline-offset: 3px;
}

.article-card__link:hover .article-card__more,
.article-card__link:focus-visible .article-card__more {
	text-decoration-color: currentColor;
}

/* THE WHOLE CARD STOPS MOVING, not just the lift. A zoom that keeps
   running when the lift is switched off is the half-fix. */
@media (prefers-reduced-motion: reduce) {
	.article-card__link,
	.article-card__img,
	.article-card__title { transition: none; }

	.article-card__link:hover,
	.article-card__link:focus-visible { transform: none; }

	.article-card__link:hover .article-card__img,
	.article-card__link:focus-visible .article-card__img { transform: none; }
}

/* A phone tile is the full column, so it can afford less inset. */
@media (max-width: 599px) {
	.article-card__body { padding: 16px; }
}


/* ------------------------------------------------------------------
 * Pagination
 *
 * WordPress's the_posts_pagination() markup, styled to live's numbers:
 * 5px/10px on each control, a 1px rule around it, and the current page
 * on a #f5f5f5 chip. The wrapper's 40px of air above and below is
 * measured too.
 *
 * THE 1px RULE STAYS AT --c-rule. It is 1.25:1 against white and that is
 * fine here - WCAG 1.4.11 asks for 3:1 on whatever IDENTIFIES a control,
 * and what identifies these is the number inside them. The link colour
 * is the part that had to move; see the header.
 * ------------------------------------------------------------------ */

.pagination {
	padding-block: 40px;
	text-align: center;
}

.pagination .screen-reader-text { position: absolute; }

.pagination .page-numbers {
	display: inline-block;
	padding: 5px 10px;
	margin: 0 0 5px;
	border: 1px solid var(--c-rule);
	font-size: 14px;
	font-weight: 300;
	line-height: 22px;
	color: var(--c-orange-deep);
	text-decoration: none;
}

.pagination a.page-numbers:hover { color: var(--c-navy); text-decoration: underline; }

.pagination .page-numbers.current {
	background: var(--c-page-chip);
	color: var(--c-navy);
}

.pagination .page-numbers.dots { border-color: transparent; color: var(--c-navy); }


/* ==================================================================
 * 10 WORDPRESS BLOCK CORRECTIONS
 * ================================================================== */

/* WordPress wraps the children of a group block in an EXTRA div. That div
   becomes the grid item, so every grid-template-columns silently collapses to
   a single column. Dissolving it lets the real children participate.
   This cost real debugging time on hbchiropractic; do not remove it. */
.wp-block-group__inner-container { display: contents; }

.alignwide, .alignfull { max-width: none; }
.aligncenter { margin-inline: auto; }


/* ==================================================================
 * 11 ACCESSIBILITY UTILITIES
 * 12 BACK TO TOP
 * ================================================================== */

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

.skip-link {
	position: absolute;
	left: -9999px;
	z-index: 100;
	padding: var(--s-3) var(--s-5);
	background: var(--c-navy);
	color: var(--c-white);
}
.skip-link:focus { left: var(--s-4); top: var(--s-4); }

/* ==================================================================
 * SCROLL REVEAL
 *
 * READ THIS BEFORE EDITING. Nothing here hides anything until JS adds
 * `js-reveal` to <html>. That is the whole design: a reveal that hides in
 * CSS and shows in JS turns any script error - or an ad blocker eating the
 * bundle - into a blank page. With no JS, an old browser, or a reduced-motion
 * preference, every one of these elements is simply visible, because the
 * hiding rule never matches.
 *
 * Do not "simplify" this by putting opacity: 0 on .reveal directly.
 * ================================================================== */

/* THE TRANSITION LIVES ON .is-in, NOT ON .reveal. If it sits on .reveal, then
   adding that class to an element that is currently visible animates it OUT -
   a 480ms fade to nothing on load, and a transition left running that holds
   the element at full opacity while it should already be hidden. Starting
   state must be instant; only the arrival is animated. */
.js-reveal .reveal {
	opacity: 0;
	transform: translateY(8px);
}

.js-reveal .reveal.is-in {
	opacity: 1;
	transform: none;
	transition: opacity 480ms ease, transform 480ms ease;
}


@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}
}

/* The footer's own artwork band. Shared - the footer is on every page.

   COVER, not `100% auto`. The artwork is 2560x454; at `100% auto` it scaled to
   the viewport width and left whatever the band's own height exceeded it
   showing the background colour underneath. The fallback colour is now the
   pale blue the artwork itself is, so a slow image never flashes navy. */
.site-footer {
	background-color: var(--c-blue-pale);
	background-image: url("../img/bg/footer-band.png");
	background-repeat: no-repeat;
	background-position: center;
	background-size: cover;
}


/* ==================================================================
 * 12 BACK TO TOP
 *
 * Site-wide, on every page. Gerek asked for it after the mobile menu
 * turned out to be broken and there was no way back up an 11,000px
 * article without a lot of thumb. Modelled on the one on
 * peninsulacregroup.com, in this site's own tokens rather than that
 * site's palette.
 *
 * IT IS AN <a href="#top">, NOT A BUTTON, AND THAT IS THE DESIGN.
 * "top" is a special fragment: with no element of that id the browser
 * scrolls to the top of the document by itself. So the control works
 * with no JavaScript at all, is focusable and keyboard-operable for
 * free, and honours `scroll-behavior` - which means it inherits the
 * reduced-motion switch in this file without knowing anything about it.
 * JavaScript only decides WHEN it is worth showing.
 *
 * VISIBLE BY DEFAULT, HIDDEN BY JS - the same rule the scroll reveal
 * follows. The hiding lives behind `.js-totop`, which a script adds. No
 * script, a throw, a blocked bundle: the link is simply always there and
 * still works.
 * ================================================================== */

.to-top {
	position: fixed;
	right: var(--s-5);
	bottom: var(--s-5);
	z-index: 25;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border: 1px solid rgba(6, 58, 108, 0.15);
	border-radius: var(--radius);
	background: rgba(255, 255, 255, 0.9);
	box-shadow: 0 2px 8px -2px rgba(6, 58, 108, 0.25);
	color: var(--c-navy);
	text-decoration: none;
}

/* A chevron drawn from two borders on a rotated box - no icon font, no SVG,
   and it inherits currentColor so the hover recolours it for free. The 3px
   nudge is optical: a rotated square centres low. */
.to-top__icon {
	width: 10px;
	height: 10px;
	margin-top: 3px;
	border-top: 2px solid currentColor;
	border-left: 2px solid currentColor;
	transform: rotate(45deg);
}

/* Response-only, like every other interaction on this site: the surface
   goes solid, the border takes the brand blue, and the same 1px lift the
   buttons use. Nothing runs on its own. */
.to-top:hover {
	background: var(--c-white);
	border-color: var(--c-blue);
	color: var(--c-navy);
	transform: translateY(-1px);
}

.to-top:active { transform: translateY(0); }

/* Only once JS has said so. The transition sits here rather than on the
   base rule so a page without JS has no animation to run at all. */
.js-totop .to-top {
	opacity: 0;
	visibility: hidden;
	transform: translateY(8px);
	transition: opacity 200ms ease, transform 200ms ease, visibility 200ms ease;
}

.js-totop .to-top.is-visible {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.js-totop .to-top.is-visible:hover { transform: translateY(-1px); }

/* Measured against Peninsula's: 44px and a 16px inset on a phone, so it
   clears the thumb without covering the copy. */
@media (max-width: 768px) {
	.to-top {
		right: var(--s-4);
		bottom: var(--s-4);
		width: 44px;
		height: 44px;
	}
}


/* The footer links stack two to a row on a phone, and at 14px of vertical
   padding each row was 41px tall - three rows of mostly air under the logo.
   Gerek: "a little too spread apart, top to bottom."

   10px rather than 14 takes 8px off each row, 24px off the block. The tap
   target goes from 41px to 33px, under the usual 44px guidance - acceptable
   here because the links are full-width rows with 20px of horizontal padding,
   so the hit area stays about 100x33 with nothing adjacent to mis-tap.
   Desktop keeps the 14px.

   AT THE END OF THE FILE ON PURPOSE. `.site-footer__list a` in section 07 is
   the same specificity (0,1,1), so this only wins by coming after it. Placed
   up in the token section it lost silently and the rows stayed 41px. */
@media (max-width: 768px) {
	.site-footer__list a { padding-block: 10px; }
}
