/*
Theme Name: Barbella
Theme URI: https://www.barbella.com/
Author: David Barbella
Description: Custom block theme for barbella.com. Core Gutenberg blocks only.
Version: 0.1.0
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: barbella
*/

/* Layout, color, and type live in theme.json.
   This file is only for what theme.json cannot express. */

/* ==========================================================================
   Global — the footer sits at the bottom of a short page

   Found on 2026-08-10, the first time the 404 and search templates were ever
   rendered. Both are short: at a 900px-tall window the footer ended at 591px
   and left 309px of white beneath it, with the grey band floating in the middle
   of the screen. A taller monitor makes it worse. Every page built so far is
   long enough to fill the window, which is why this never showed up.

   `min-height: 100vh` on the wrapper and `flex: 1` on `<main>` — the ordinary
   sticky-footer arrangement, on the wrapper WordPress already gives every block
   theme, so no markup changes and it covers templates not written yet.

   Measured on the homepage and Clients Served before writing it: every band's
   width, the list's 16px offset, document height and scroll width are identical
   with the rule and without it, and the sticky header still pins at the same
   offset. A flex container was the one thing here that could plausibly have
   disturbed either.
   ========================================================================== */

.wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

.wp-site-blocks > main {
	flex: 1;
}

/* ==========================================================================
   Global — hover transitions

   Site-wide standard, David 2026-08-07: every mouseover eases into its
   highlight rather than snapping to it.

   Declared once here rather than repeated on each component, so a new link or
   button inherits the behaviour without anyone remembering to add it. Only the
   four properties the theme's hovers actually change are listed — `transition:
   all` would also catch layout and paint properties and animate things nobody
   asked to animate.

   200ms: long enough to read as a fade, short enough that a button still feels
   like it responds the instant you touch it. Anything past ~250ms starts to
   feel like lag on a pointer.

   `ease-out` rather than `ease`: it moves most of the way immediately and
   settles, which reads as responsive. `ease` eases in as well, which on a
   change this short just looks slow to start.
   ========================================================================== */

a,
.wp-block-button__link,
.wp-block-search__button,
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
	transition:
		color 200ms ease-out,
		background-color 200ms ease-out,
		border-color 200ms ease-out,
		box-shadow 200ms ease-out;
}

/* Motion is a preference, not a given. Paired with the same guard on the
   mobile menu's height animation further down. */
@media (prefers-reduced-motion: reduce) {
	a,
	.wp-block-button__link,
	.wp-block-search__button,
	.wp-block-navigation__responsive-container-open,
	.wp-block-navigation__responsive-container-close {
		transition: none;
	}
}

/* ==========================================================================
   Components — Call-to-action button

   The orange button, shared by every CTA on the site. Add `barbella-cta` to a
   core Button block's Additional CSS Class field and it looks like this one; a
   second class alongside it carries anything unique to that instance (the
   resume button's fixed 300px width, an icon).

   Written as a component the second time it was needed rather than the fifth.
   theme.json's `elements.button` already supplies the orange, the white text
   and the square corners — only what it cannot express is here.
   ========================================================================== */

.barbella-cta .wp-block-button__link {
	/* Core does not set this on the link, and without it the 21px padding and
	   1px border push a width-constrained button past its stated width. */
	box-sizing: border-box;
	/* Type is the “Button Text - Large” style, defined in `styles/` and editable in
	   Appearance > Editor > Styles > Blocks. Deliberately not restated here:
	   the variation emits `:root :where(...)`, which a single class in this
	   file already ties with and beats on source order — so anything left
	   behind would quietly win and the CMS control would look broken. */
	/* The live site's `11px 21px 16px` is corrected here, David 2026-08-07 —
	   the deeper bottom padding pushes the label *up*, and on barbella.com it
	   sits visibly closer to the top of the button than the bottom.

	   The numbers, measured rather than eyeballed. A label with no descenders
	   ("View David's Resume") has ink running cap-top to baseline: 14.19px tall
	   at this size, 0.09px below the baseline. Inside the original's box that
	   left 16.66px of clear space above the ink and 22.76px below it — the label
	   sat 6.1px high.

	   Centring wants 19.71px on each side, which is the baseline 3.05px lower,
	   so 3px moves from the bottom padding to the top. The vertical total stays
	   27px, so the button keeps the original's measured 53.7px height, and the
	   remaining imbalance is 0.1px.

	   Not symmetrical padding: 13.5px each would centre the *line box*, which
	   reserves descender space at the bottom these labels never use, and would
	   leave them looking high again by half that reserve. */
	padding: 14px 21px 13px;
	/* Same colour as the fill, so the border is invisible — but it is 2px of the
	   button's measured width and 1px of its height. Dropping it would shrink
	   every button against the original. */
	border: 1px solid var(--wp--preset--color--button);
	/* 0.075em = the measured 1.425px at 19px. */
	text-shadow: 0 0.075em 0.075em rgba(0, 0, 0, 0.5);
}

/* Hover deliberately departs from the live site. The original goes *brighter*
   (#f56102) and swaps the label to dark grey (#3b3b3b), which reads as a
   rollover artefact and drops the text below WCAG contrast on the new fill.
   David's decision: darken instead and keep the label white. The fade itself
   comes from the global transition above. */
.barbella-cta .wp-block-button__link:hover,
.barbella-cta .wp-block-button__link:focus {
	background-color: #a84300;
	border-color: #a84300;
}

/* --- Button icons ---------------------------------------------------------
   The original appends FontAwesome glyphs inside the link (`<i class="x-icon
   x-icon-sign-out">`). This build has no icon font, so each is the same shape
   inlined as an SVG data URI on `::after`, matching the topbar icons in
   `assets/icons/`.

   On `::after` rather than inside the block: the button label has to stay
   editable in WordPress, and an icon written into the block content would be
   one stray keystroke away from deletion. */

.barbella-cta-icon .wp-block-button__link::after {
	content: "";
	display: inline-block;
	/* Measured ~17.5px wide at a 19px font-size, 9.5px clear of the text. */
	width: 0.93em;
	height: 0.93em;
	margin-left: 0.5em;
	vertical-align: -0.12em;
	background-repeat: no-repeat;
	background-position: center;
	background-size: contain;
}

/* Font Awesome Free 5.15.4 "sign-out-alt" (CC BY 4.0) — the external-link
   arrow the original used at `.x-icon-sign-out`. */
.barbella-cta-icon-external .wp-block-button__link::after {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23ffffff' d='M497 273L329 441c-15 15-41 4.5-41-17v-96H184c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h104V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z'/%3E%3C/svg%3E");
}

/* The same LinkedIn mark already drawn in `assets/icons/linkedin.svg` for the
   topbar, inlined here so the button costs no extra request. The original used
   FontAwesome's `linkedin-square`. Measured 16.29px wide against the arrow's
   17.65px — the shared 0.93em box holds both, since `contain` letterboxes the
   narrower mark rather than stretching it. */
.barbella-cta-icon-linkedin .wp-block-button__link::after {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cmask id='bb-li-btn'%3E%3Crect width='24' height='24' fill='%23ffffff'/%3E%3Cg fill='%23000000' transform='translate(3.21 3.48) scale(0.72)'%3E%3Cpath d='M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5zM3 9h4v12H3z'/%3E%3Cpath d='M9.5 9h3.83v1.64h.05c.53-1 1.84-2.06 3.79-2.06C21.2 8.58 22 10.9 22 14.4V21h-4v-5.86c0-1.4-.03-3.2-1.95-3.2-1.96 0-2.26 1.52-2.26 3.1V21h-4z'/%3E%3C/g%3E%3C/mask%3E%3Cpath d='M4 1.5h16a2.5 2.5 0 0 1 2.5 2.5v16a2.5 2.5 0 0 1-2.5 2.5H4A2.5 2.5 0 0 1 1.5 20V4A2.5 2.5 0 0 1 4 1.5z' fill='%23ffffff' mask='url(%23bb-li-btn)'/%3E%3C/svg%3E");
}

/* ==========================================================================
   Header — Document A §6
   Original heights: topbar min-height 46px, navbar min-height 80px.
   Global border-box means padding is included in both figures.
   ========================================================================== */

/* The topbar's height, named because the sticky header below has to subtract
   exactly this much and the two must never drift apart. */
:root {
	--barbella-topbar-height: 46px;
	/* The gap between page content and the edge of a phone screen, below 767px.
	   David 2026-08-07: it belongs to the containers, so content simply wraps
	   inside them and no individual heading or paragraph has to be targeted.

	   It exists because nothing on the live site sets one. Section by section the
	   original leaves 0px, 6px or 12px depending on which element you land on,
	   and the headings — the widest text on the page — are the ones at 0. This is
	   the first thing in the build that the original has no equivalent for.

	   20px: roughly double the widest gap the original manages, and the ordinary
	   iOS and Android content margin. */
	--barbella-gutter: 20px;
}

/* --- Sticky --------------------------------------------------------------
   The white navbar pins to the top of the viewport once the grey topbar has
   scrolled past; the topbar comes back when you return to the top.

   This is an addition, not a replication. barbella.com does not do it: its
   `<body>` carries `x-navbar-fixed-top-active`, so the theme option is on, but
   the class the CSS actually keys off (`.x-navbar-fixed-top`, which sets
   `position: fixed`) is never applied to the navbar element, and X-theme's
   `x-body.min.js` never adds it — it only reads that selector's height to
   offset anchor links. Measured on the live site at 1440x900: at scrollY 400
   the navbar's top edge is at -354, i.e. it scrolls away like any other
   element. David asked for it pinned anyway, 2026-08-07.

   `position: sticky` on the <header>, not on the navbar inside it. A sticky
   element can only travel within its containing block, so sticking the navbar
   itself would release it the moment the 126px header scrolled off — it would
   pin for 126px and then leave. Sticking the whole header instead gives it the
   page for a containing block.

   The negative offset is what hides the topbar: the header stays in flow until
   its top would pass -46px, at which point it pins with the topbar sitting
   just above the viewport edge and the navbar flush at the top. No JavaScript,
   no scroll listener, and no placeholder element — sticky keeps its space in
   the flow, so nothing below it shifts. */
header.wp-block-template-part {
	position: sticky;
	top: calc(var(--barbella-topbar-height) * -1);
	/* Above the hero's Cover, which paints a full-bleed image and would
	   otherwise cover the pinned bar. */
	z-index: 100;
}

/* `.x-container.width` is 88% wide, `.max` caps it at 1200px (Document A §1).
   theme.json's contentSize gives the cap but not the 88%. */
.barbella-container {
	width: 88%;
	max-width: 1200px;
	margin: 0 auto;
}

/* --- Topbar --------------------------------------------------------------
   renew.css:1091 `.x-topbar { min-height:46px; padding:6px 0 }`
   x-child style.css `.x-topbar { background:#444 }` — overrides the theme
   option's #d35400. `.x-social-global` is display:none there; not built.

   Each link is a Group of Image + Paragraph rather than a Social Icons link.
   Social Icons ships its own icon set and cannot take an arbitrary one, which
   fails links like Resume that have no matching service. The Group gives the
   three editable fields: Text and Destination on the Paragraph, Icon on the
   Image (Replace -> Media Library). */
.barbella-topbar {
	min-height: var(--barbella-topbar-height);
	padding: 6px 0;
	/* The links are ~28px tall inside a 46px bar. Without this the bar is a flow
	   container, so they sit at the top and the leftover height all falls below
	   them — the row then reads as misaligned against the navbar underneath,
	   which centres its own contents. `margin: 0 auto` on `.barbella-container`
	   still centres the inner box horizontally as a flex item. */
	display: flex;
	align-items: center;
}

/* renew.css:1106 floats `.p-info` right; flex end here instead, so the old
   markup's clearfix is not needed. This element is also the links row itself —
   a separate wrapper inside it would nest a box that wraps nothing.

   renew.css:1106 + x-child style.css: 12px, not the 11px default.

   No `margin: 8px 0 0` here, despite that being on the approved value list.
   Two reasons. It is inert: core prints
   `:root :where(.is-layout-flow) > :first-child { margin-block-start: 0 }`,
   which outranks a single class and zeroes it — so the approved look was in
   fact produced by `min-height: 46px` plus `padding: 6px 0` on the bar, and it
   renders identically without this. And a `margin` shorthand here overwrites
   `.barbella-container`'s `margin: 0 auto`, which pushed the whole bar 77px
   left of the nav row below it. Vertical nudges on this element belong in
   padding. */
.barbella-topbar-inner {
	display: flex;
	justify-content: flex-end;
	font-size: 12px;
	letter-spacing: 1px;
	line-height: 1.3;
}

/* One link. The row is flex so the pipe generated below sits beside the text
   instead of dropping to a second line under it. */
/* No `gap` here on purpose. The separator below is this row's ::after, which
   makes it a third flex item, so a `gap` would space icon/text/pipe all the
   same. The two distances differ — 0.4em icon-to-text, 10px around the pipe —
   so each is set as a margin on the element it belongs to. */
.barbella-topbar .barbella-topbar-link {
	display: flex;
	align-items: center;
}

.barbella-topbar .barbella-topbar-link .barbella-topbar-text {
	margin: 0;
}

.barbella-topbar .barbella-topbar-link .barbella-topbar-text a {
	color: #fff;
	text-decoration: none;
}

/* The original's `.last` rule carries an invalid value (`margin: 0 0 0 10`) so
   the browser drops it and every link keeps `margin: 0 10px`, leaving the
   topbar's last link 10px short of the container edge.

   Not matched: the main nav below ends flush, and the two rows disagreeing by
   10px reads as a mistake. David's call — the original's bug is corrected here
   rather than reproduced. `:last-child` so it follows whichever link is last,
   not Linkedin specifically. */
/* The separators were literal `|` characters in the old markup, written between
   the anchors as `</a> | <a>`. As content they were not editable and would have
   had to be retyped by hand whenever a link was added, so they are generated
   instead. `margin: 0 10px` on the pipe itself reproduces the original's
   `margin: 0 10px` per link: 10px of space on each side of the separator.

   No pipe after the last link, and no trailing margin with it, so the bar ends
   flush with the nav row below. */
.barbella-topbar .barbella-topbar-link:not(:last-child)::after {
	content: "|";
	/* Not symmetric, because the space either side of the pipe is not built the
	   same way. To its right sits 10px plus the next icon's 0.35em left padding;
	   to its left, only the margin — and `letter-spacing: 1px` puts a further 1px
	   of dead space after the word's last letter. Matching margins therefore
	   render visibly lopsided, tight on the left. The left value adds both
	   differences back so the two gaps read equal. */
	margin-right: 10px;
	margin-left: calc(10px + 0.35em + 1px);
	color: #fff;
}

.barbella-topbar .barbella-topbar-link .barbella-topbar-text a:hover {
	color: var(--wp--preset--color--accent-text);
}

/* Icon sizing lives here, not in the block's width attribute, so every link
   matches without the editor having to set a pixel width per icon. A width set
   in the editor still wins — it lands inline on the <img>. */
.barbella-topbar .barbella-topbar-icon {
	/* core gives <figure> a bottom margin that would push the icon off centre.
	   The right margin is the icon-to-text gap; it sits here rather than in a
	   row `gap` so the pipe's 10px stays independent of it.

	   Padding on both sides, not just a right-hand gap. These icons are drawn to
	   the edge of their viewBox, unlike core's Social Icons glyphs which carried
	   their own inset — so the icon needs breathing room on the pipe side as
	   well as before its word, or it reads as crammed against both. David's
	   call, adjusted by eye against the approved bar. */
	margin: 0;
	padding: 0 0.6em 0 0.35em;
}

.barbella-topbar .barbella-topbar-icon img {
	width: 1.1em;
	height: auto;
	/* block kills the inline-image baseline gap, which otherwise reads as the
	   icon sitting a pixel low against the text */
	display: block;
}

/* This bar ships with sourceless Image blocks — the editor shows the Media
   Library placeholder, which IS the Icon field, and the front end gets an
   `<img>` with no `src`. Collapse those so a link whose icon has not been
   chosen yet is spaced correctly instead of carrying a phantom 1.1em box and
   0.4em gap.

   `img[src]`, not `img`: the stored markup has to contain a bare `<img/>`
   because core's image `save()` always emits one, and content that does not
   match what `save()` regenerates is flagged "unexpected or invalid" the
   moment the header is opened in the editor. So the element is always there;
   only the attribute distinguishes set from unset. */
.barbella-topbar .barbella-topbar-icon:not(:has(img[src])) {
	display: none;
}

/* renew.css:1114 — topbar centres and unfloats at the primary mobile
   breakpoint; margin per x-child style.css. */
@media (max-width: 767px) {
	.barbella-topbar-inner {
		justify-content: center;
	}
}

/* --- Navbar --------------------------------------------------------------
   Source-Homepage.html inline CSS: `.x-navbar-inner { min-height:80px }` */
.barbella-navbar {
	min-height: 80px;
	display: flex;
	align-items: center;
}

/* No mobile collapse. The `height:auto` at ≤979px in the original applies to
   `.x-navbar-wrap`, not to `.x-navbar-inner` — measured on the live site, the
   navbar is 80px at 979, 767 and 375 alike. The header is a constant 126px at
   every width, which is also the figure the hero's calc() uses. */

/* Layout is driven from here, not from the Group block's `layout` attribute.
   Those attributes only become CSS via editor-generated classes
   (`is-content-justification-space-between` and friends), which cannot be
   reliably hand-written into a template part. */
.barbella-navbar-inner {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
}

.barbella-logo {
	margin: 0;
	flex: 0 0 auto;
	/* zero line-height: the wrapper otherwise reserves a text line under the
	   image, making the mobile row 50px instead of the image's 31px */
	line-height: 0;
}

/* Block, not inline: an inline link adds line-box descender space below the
   image, which pushes the logo to the top of the row instead of centring it. */
.barbella-logo a {
	display: block;
}

/* Site Logo caps its own width from the block's `width` attribute, which would
   otherwise beat the 300px/250px pair below at equal specificity. */
.barbella-logo.wp-block-site-logo {
	width: auto;
}

.barbella-logo img {
	display: block;
	width: 300px;
	height: auto;
}

/* x-child style.css: logo drops to 250px on mobile */
@media (max-width: 767px) {
	.barbella-logo img {
		width: 250px;
	}
}

/* Nav links — Source-Homepage.html inline CSS:
   14px, uppercase, letter-spacing 0.071em, colour hsl(0,0%,23%) = #3b3b3b,
   14px of horizontal padding, hover/current #444 with a 2px underline.
   Original set Lato here; the rebuild uses Montserrat throughout (see
   build-decisions.md). */
/* The Search block is a sibling of the nav's <ul>, so the <nav> itself is the
   flex context that has to centre them against each other. */
.barbella-nav {
	flex: 0 1 auto;
	align-items: center;
}

.barbella-nav .wp-block-navigation__container {
	justify-content: flex-end;
	gap: 0;
}

/* 11px, not the original's 14px: Montserrat is wider than the original's Lato,
   which made the row read loose at 14px. David's call, set in the browser. */
.barbella-nav .wp-block-navigation-item {
	padding: 0 11px;
}

/* Prefixed with `.barbella-navbar` for the same reason as the overlay rules:
   core's block-library CSS is printed after the theme's and sets the link
   colour at equal specificity, which otherwise leaves the nav at the body
   grey #7a7a7a instead of #3b3b3b. */
.barbella-navbar .barbella-nav .wp-block-navigation-item__content {
	padding: 0;
	/* Type is the “Navigation Text” style, defined in `styles/` and editable in
	   Appearance > Editor > Styles > Blocks. Deliberately not restated here:
	   the variation emits `:root :where(...)`, which a single class in this
	   file already ties with and beats on source order — so anything left
	   behind would quietly win and the CMS control would look broken. */
	color: #3b3b3b;
	text-decoration: none;
}

.barbella-navbar .barbella-nav .wp-block-navigation-item__content:hover,
.barbella-navbar .barbella-nav .current-menu-item > .wp-block-navigation-item__content,
.barbella-navbar .barbella-nav [aria-current="page"] {
	color: #444;
	box-shadow: 0 2px 0 0 #444;
}

/* Search — core's Search block in button-only + toggle mode replaces
   X-theme's full-screen search overlay. It is a child of the Navigation block,
   not a sibling: only children collapse into the mobile overlay, which is
   where the original puts its search item (Source-Homepage.html:108).

   Do not look for it in parts/header.html — it lives inside the navigation
   menu itself (a wp_navigation post, edited from Appearance > Editor >
   Navigation). Nesting it in the template part instead makes the Navigation
   block non-empty, which stops it resolving to the menu at all. That is also
   why these rules key off `.wp-block-search` rather than a theme class: the
   Navigation screen offers no field for a custom className. */
/* No padding here — the 14px lives on the button, matching the original's
   single 14px of left padding on the search item. Having both made the gap
   before the magnifier 42px against the original's 28px. */
.barbella-nav .wp-block-search {
	margin: 0;
	padding: 0;
}

/* No padding at all: the right side stays flush with the container edge, as
   renew.css:1416 does for the original's last item, and the left gap is now
   just the preceding item's 11px. `display:flex` is what centres the glyph
   vertically against the nav text. */
.barbella-nav .wp-block-search .wp-block-search__button {
	display: flex;
	align-items: center;
	padding: 0;
	border: 0;
	background: none;
	color: #3b3b3b;
}

.barbella-nav .wp-block-search .wp-block-search__button:hover {
	color: #444;
}

.barbella-nav .wp-block-search .wp-block-search__button svg {
	width: 20px;
	height: 20px;
	fill: currentColor;
}

/* Hamburger — renew.css:1377 plus the generated block's #444 / #666 / 22px.
   Core's default open button looks nothing like X-theme's boxed dark one. */
/* px, not the original's em padding: core sets the button's font-size and wins,
   so `0.458em 0.625em` resolved against 16px instead of 22px and produced a
   box 5px too small. These values reproduce the measured 47x43. */
.barbella-navbar .wp-block-navigation__responsive-container-open {
	padding: 10px 13px;
	color: #fff;
	background-color: #444;
	border-radius: 4px;
	box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.25);
}

.barbella-navbar .wp-block-navigation__responsive-container-open:hover {
	background-color: #666;
}

/* --- Mobile panel --------------------------------------------------------
   Measured on the live site at 414px with the menu open: the panel sits IN
   FLOW (the navbar grows from 80px to 266px and the page moves down), spans
   the 88% container, and holds full-width bordered boxes. List margin 25px 0;
   each box 44px tall — 14px/1.5 uppercase text, 1px solid #3b3b3b border,
   10.5px/13.3px padding — with 11px between boxes. Search is the same box,
   centred, magnifier then the word.

   Prefixed with `.barbella-navbar` throughout: core's block-library CSS is
   printed after the theme's and matches these elements at equal specificity,
   so an unprefixed rule loses on source order. */
@media (max-width: 979px) {
	/* `display: contents` dissolves the <nav>'s own box so the hamburger and
	   the panel become items of the navbar row itself. Without it the panel is
	   trapped in the nav's column and cannot span the container. */
	.barbella-navbar .barbella-nav {
		display: contents;
		/* core sets position:relative here, which still captures absolutely
		   positioned descendants and would trap the close button in the panel */
		position: static;
	}

	/* Top-aligned, not centred: in the original the logo and hamburger hold the
	   same position whether the panel is open or shut, and the panel appends
	   below them. Centring would lift both by 19px on open.
	   19px padding reproduces the original's measured row: hamburger at
	   navbar-top +19, logo centred against it, panel starting at +61. */
	.barbella-navbar {
		align-items: flex-start;
	}

	.barbella-navbar-inner {
		flex-wrap: wrap;
		gap: 0 20px;
		padding-top: 19px;
	}

	/* Same method as the original, which uses Bootstrap's collapse:
	   renew.css:847 `.collapsing { height: 0; overflow: hidden; transition:
	   height 0.3s ease }`, with the pixel height set from JS. The panel stays
	   in the layout at zero height rather than being switched in and out of
	   `display: none`, so both directions animate and the content inside never
	   moves — it is clipped, then revealed. `visibility` keeps the shut panel
	   out of the tab order and off screen readers. */
	.barbella-navbar .barbella-navbar-inner .barbella-nav .wp-block-navigation__responsive-container {
		/* flow-root, not block: it establishes a formatting context so the
		   list's 25px top margin stays inside the panel. As a plain block that
		   margin collapses out and drags the whole panel — and its contents —
		   downwards while the height animates. */
		display: flow-root;
		height: 0;
		visibility: hidden;
		/* clip, not hidden: `overflow: hidden` makes this a scrollable box, and
		   core focuses the first link as the menu opens
		   (wp-includes/js/dist/script-modules/block-library/navigation/view.js,
		   focusFirstElement). Focusing scrolls that link into view — measured
		   scrollTop 47 while the panel is still at zero height — which
		   bottom-anchors the contents. The browser then clamps scrollTop back to
		   0 as the height animates up, and the links drift down into place.
		   `overflow: clip` clips identically but cannot scroll, so there is
		   nothing for focus to scroll. Close was never affected: it starts at
		   full height with scrollTop already 0. */
		overflow: clip;
		/* core's fade-in ends on translateY(8px), which misaligns the panel */
		animation: none;
		transform: none;
		position: static;
		order: 3;
		flex-basis: 100%;
		width: 100%;
		margin: 0;
		background-color: transparent;
		z-index: auto;
	}

	.barbella-navbar .barbella-navbar-inner .barbella-nav .wp-block-navigation__responsive-container.is-menu-open {
		height: auto;
		visibility: visible;
	}

	/* assets/js/menu.js adds this while it drives the height between 0 and the
	   panel's own height, in either direction. It carries the transition and
	   keeps the panel visible through a close, since core drops
	   `is-menu-open` the moment the menu is dismissed. */
	.barbella-navbar .barbella-navbar-inner .barbella-nav .wp-block-navigation__responsive-container.barbella-menu-animating {
		visibility: visible;
		transition: height 450ms cubic-bezier(0.33, 0, 0.2, 1);
	}

	/* The 25px above and below the links is padding on the panel's inner block,
	   never a margin on the list: margins collapse against a box whose height is
	   being animated, which drags the links up and down mid-animation instead of
	   holding them still. It sits on the inner block rather than the panel so
	   the shut panel can still measure zero. */
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-navigation__responsive-close {
		padding: 25px 0;
	}

	/* Core's dialog wrapper adds a 46px top margin to clear its close button and
	   is `position: relative`, which would anchor that button to itself. Both
	   are undone so the panel starts right below the logo row and the close
	   button can anchor to the navbar row instead. */
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-navigation__responsive-dialog {
		position: static;
		margin: 0;
	}

	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-content {
		display: block;
		width: 100%;
		margin: 0;
		padding: 0;
	}

	/* renew.css:1270 — `.x-navbar .mobile .x-nav { margin: 25px 0 }`. That
	   spacing lives on the panel as padding here; see above. */
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-navigation__container {
		display: block;
		width: 100%;
		margin: 0;
		padding: 0;
	}

	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-navigation-item,
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search {
		display: block;
		width: 100%;
		margin: 0 0 11px;
		padding: 0;
	}

	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-navigation-item__content,
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search__inside-wrapper {
		display: block;
		width: 100%;
		box-sizing: border-box;
		min-height: 0;
		border: 1px solid #3b3b3b;
		padding: 10.5px 13.3px;
		font-size: 14px;
		line-height: 1.5;
		letter-spacing: 0.071em;
		text-transform: uppercase;
		color: #3b3b3b;
		background: none;
		box-shadow: none;
	}

	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search {
		margin-bottom: 0;
	}

	/* The bordered box is the wrapper, not the button, so the revealed input
	   has the full width of the box to grow into. 44px explicit: the button's
	   own font metrics otherwise render it ~3px taller than the link boxes. */
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search__inside-wrapper {
		display: flex;
		align-items: center;
		height: 44px;
		padding: 0 13.3px;
	}

	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search__button {
		display: flex;
		align-items: center;
		justify-content: center;
		flex: 0 0 auto;
		width: auto;
		height: auto;
		min-height: 0;
		padding: 0;
		border: 0;
		background: none;
		box-shadow: none;
		color: inherit;
		font: inherit;
		letter-spacing: inherit;
		text-transform: inherit;
	}

	/* Shut: the magnifier and the word sit centred in the box, as the original.
	   Open: the button shrinks back to the icon and hands the room to the
	   input. `searchfield-hidden` is the class core toggles. */
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search__searchfield-hidden .wp-block-search__button {
		flex: 1 1 auto;
	}

	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search__searchfield-hidden .wp-block-search__button::after {
		content: "Search";
	}

	/* Space between the field and the magnifier. It has to be margin on the
	   button, not padding on the input: the browser draws its focus ring around
	   the input's border box, so anything inside the input sits under the ring
	   rather than beside it. */
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search:not(.wp-block-search__searchfield-hidden) .wp-block-search__button {
		margin-left: 12px;
	}

	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search:not(.wp-block-search__searchfield-hidden) .wp-block-search__input {
		/* !important throughout: core drives this field's open/shut widths with
		   its own !important declarations, so plain rules never land. */
		flex: 1 1 auto !important;
		width: auto !important;
		min-width: 0 !important;
		height: 100%;
		margin: 0;
		/* Padding on both sides: without the left the typed text sits against
		   the field's own edge, and the right holds Safari's clear button off
		   the magnifier. */
		padding: 0 12px 0 10px !important;
		border: 0;
		background: none;
		color: #3b3b3b;
		/* 16px: anything smaller makes iOS Safari zoom the page on focus */
		font-size: 16px;
		letter-spacing: normal;
		text-transform: none;
	}

	/* core pins the icon with min-width/min-height as well as width/height, so
	   setting width alone leaves it at 24px. */
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search__button svg {
		display: block;
		width: 20px;
		height: 20px;
		min-width: 20px;
		min-height: 20px;
		margin-right: 0.5em;
	}

	/* Core's magnifier is a thin fill-only path, which reads faint next to
	   Safari's clear button in the open field. A hairline stroke in the same
	   colour weights it without redrawing the icon. */
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-search__button svg path {
		stroke: currentColor;
		stroke-width: 0.8;
	}

	/* The original's hamburger toggles the panel and turns lighter (#666) while
	   open. Core's open button only ever opens, so its close button takes that
	   role: parked exactly over the hamburger, same box, lighter, and drawn
	   with bars instead of core's X. */
	.barbella-navbar-inner {
		position: relative;
	}

	.barbella-navbar .barbella-nav:has(.is-menu-open) .wp-block-navigation__responsive-container-open {
		visibility: hidden;
	}

	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-close {
		position: absolute;
		/* Anchored to the navbar row (the inner is the positioned ancestor), so
		   this is the same 19px offset the hamburger sits at. */
		top: 19px;
		right: 0;
		padding: 10px 13px;
		color: #fff;
		background-color: #666;
		border-radius: 4px;
		box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.25);
	}

	/* Core's open button ships a TWO-bar icon; the original's is three bars. Both
	   buttons are drawn the same way here so the icon does not change between
	   states. */
	.barbella-navbar .wp-block-navigation__responsive-container-open svg,
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-close svg {
		display: none;
	}

	.barbella-navbar .wp-block-navigation__responsive-container-open::before,
	.barbella-navbar .barbella-nav .wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-close::before {
		content: "";
		display: block;
		width: 22px;
		height: 22px;
		background:
			linear-gradient(#fff, #fff) 0 3px / 22px 3px no-repeat,
			linear-gradient(#fff, #fff) 0 10px / 22px 3px no-repeat,
			linear-gradient(#fff, #fff) 0 17px / 22px 3px no-repeat;
	}
}

/* Core swaps the nav for the overlay at 600px; the original swaps at 979px
   (Document A §4). Only the button needs re-showing here — the panel itself is
   already collapsed to a zero-height row by the block above. */
@media (min-width: 600px) and (max-width: 979px) {
	.barbella-nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}
}

/* Motion is a preference, not a given. */
@media (prefers-reduced-motion: reduce) {
	.barbella-navbar .barbella-navbar-inner .barbella-nav .wp-block-navigation__responsive-container.barbella-menu-animating {
		transition: none;
	}
}

/* ==========================================================================
   Homepage — Hero

   Every number here was measured off the live barbella.com on 2026-08-07, at
   1440x900, 1024x900, 768x900, 414x896 and 1440x500 — not read out of the
   audit documents. Where the two disagree, the live site wins.

   The original is pure CSS. Its section carries `parallax:false` and no script
   touches it: the height varies because `min-height` is viewport-relative and
   the box grows past it when the content is taller, and the background crop
   varies because `cover` re-frames as the box's aspect ratio changes. There is
   nothing to port from JavaScript.
   ========================================================================== */

/* How much of the viewport the hero gives up at the top.

   210px on the live site, against a header that measures 126px (46 topbar +
   80 navbar) — 84px more than the header accounts for. That surplus is not a
   mistake to correct: it is why the blue band below the hero is visible above
   the fold on barbella.com, and reproducing the site means reproducing it.

   Measured: hero 690px in a 900px viewport at 1440 wide (900 - 210). */
:root {
	--barbella-hero-offset: 210px;
}

/* The custom breakpoint at 1024px is the original's own (x-child style.css
   line 197) and is not one of the framework's — the navbar stays in desktop
   mode until 979px. Only the offset changes here.

   Measured: hero 697px in a 900px viewport at 1024 wide (900 - 203), and
   693px in an 896px viewport at 414 wide (896 - 203). */
@media (max-width: 1024px) {
	:root {
		--barbella-hero-offset: 203px;
	}
}

/* --- Band ------------------------------------------------------------------
   `#HP_Hero_Section` — the full-bleed box that owns the background image.

   Qualified with `.wp-block-cover` for specificity, not for looks: core's
   block-library stylesheet is printed after the theme's and sets both of the
   properties below at a single class, so an unprefixed `.barbella-hero` loses
   on source order. */
.wp-block-cover.barbella-hero {
	/* Both zeroed so the inner container is the only thing deciding the
	   height, exactly as `#HP_Hero` is on the live site. Core ships
	   `min-height: 430px` and `padding: 1em`; the original section has neither
	   (its inline `margin:0;padding:0` overrides the framework's `45px 0`). */
	min-height: 0;
	padding: 0;
	/* `hsl(0,2%,86%)`, inline on the original section. Shows while the image
	   loads, and behind it if it ever fails. */
	background-color: #dcdbdb;
}

/* --- Container -------------------------------------------------------------
   `#HP_Hero` — `.x-container.max.width`, 88% capped at 1200px (Document A §1).
   Measured: 1200 @1440, 901.1 @1024, 675.8 @768. */
.barbella-hero .barbella-hero-inner {
	width: 88%;
	max-width: 1200px;
	margin: 0 auto;
	min-height: calc(100vh - var(--barbella-hero-offset));
	/* `flow-root` where the live site writes `display: table`. Both establish a
	   block formatting context, and that context is the entire reason the
	   original uses a table here: without it the headline's `margin-top: 15%`
	   collapses out through this box and pushes the whole band down the page
	   instead of positioning the headline inside it. `flow-root` says that
	   directly and avoids a table box's sizing quirks.

	   Note this is a real behaviour, not a safeguard — the Cover's own
	   inner-container is a flex item and does establish a BFC, but this Group
	   sits one level inside it and would still leak the margin. */
	display: flow-root;
	/* Containing block for the subheadline, which goes absolute at <=767px. */
	position: relative;
}

/* --- Headline --------------------------------------------------------------
   `#Homepage_Hero_Headline`.

   Three classes deep, which looks heavier than it needs to be. It is not:
   core's global stylesheet prints
   `:root :where(.is-layout-flow) > :first-child { margin-block-start: 0 }`,
   which matches this element at (0,2,0) and would zero the 15% below. A
   two-class selector ties on specificity and then loses or wins on stylesheet
   order, which is not something to leave to chance.

   Font sizes and the line-height live here rather than as block presets on
   purpose: a `has-*-font-size` preset class is printed by WordPress with
   `!important`, so the 30px mobile size could then only be reached with a
   second `!important`. Size is design-system, not content — see the CMS-first
   note in docs/build-decisions.md. Colours, which do not change across
   breakpoints, stay editable block controls. */
.barbella-hero .barbella-hero-inner .barbella-hero-headline {
	display: inline-block;
	/* 15% of this element's containing block — the container's *width*, not its
	   height. That is what makes the headline's vertical position track the
	   viewport's width. Measured: 180px @1440, 135.2px @1024, 101.4px @768.
	   No bottom margin: the original's `margin: 15% 0 0 0` zeroes the `0.2em`
	   that renew.css puts on every heading. */
	margin: 15% 0 0;
	padding: 15px 20px;
	/* Type is the “Hero Title” style, defined in `styles/` and editable in
	   Appearance > Editor > Styles > Blocks. Deliberately not restated here:
	   the variation emits `:root :where(...)`, which a single class in this
	   file already ties with and beats on source order — so anything left
	   behind would quietly win and the CMS control would look broken. */
}

/* --- Subheadline -----------------------------------------------------------
   `#Homepage_Hero_SubHeadline`. In the original this is a wrapper div around a
   `<p>`; here it is a Heading block, so the wrapper's margin and padding land
   directly on it.

   It is the page's H1 — a deliberate split between visual weight and document
   structure. "AGILE LIFE" above it is the larger element but it is a slogan,
   which is not what an H1 is for; this line is what actually describes the
   page, so it carries the H1 and the slogan is demoted to an H2. David's call,
   2026-08-07, on SEO/AEO grounds.

   Being a heading rather than a paragraph means theme.json's `heading` element
   styles now reach it, so the two it would otherwise inherit are pinned back to
   what the live site renders. */
.barbella-hero .barbella-hero-inner .barbella-hero-subheadline {
	display: inline-block;
	margin: 16px 0 0;
	padding: 10px 15px;
	/* Type is the “Hero Subtitle” style, defined in `styles/` and editable in
	   Appearance > Editor > Styles > Blocks. Deliberately not restated here:
	   the variation emits `:root :where(...)`, which a single class in this
	   file already ties with and beats on source order — so anything left
	   behind would quietly win and the CMS control would look broken. */
}

/* --- Hero at <=767px -------------------------------------------------------
   The original's primary mobile breakpoint (x-child style.css line 220). The
   two boxes stop being inline tints beside the image and become full-width
   bands: the headline caps the hero, the subheadline pins to its foot. */
@media (max-width: 767px) {
	/* `#HP_Hero { width: 100% !important }` — the 88% container goes
	   edge-to-edge. Measured 414 @414. */
	.barbella-hero .barbella-hero-inner {
		width: 100%;
		max-width: none;
	}

	/* The live markup wraps the headline text in a `<span>` set to
	   `display:block; text-align:center` here, because the `h1` itself is
	   `inline-block` and could not be centred. This rule makes the `h1` a block
	   directly, so the span has no job left and the Heading block stays a plain
	   editable heading. Measured: h1 63px tall at the very top of the hero,
	   text centred. */
	.barbella-hero .barbella-hero-inner .barbella-hero-headline {
		display: block;
		margin: 0;
		/* The phone size for this style now lives in Appearance > Typography,
		   alongside its desktop one. */
		text-align: center;
	}

	.barbella-hero .barbella-hero-inner .barbella-hero-subheadline {
		display: block;
		/* Out of flow and pinned to the foot of the container, so the hero's
		   height is set by the headline and the min-height alone. No `left`:
		   with `width:100%` and no offsets the box keeps its static position,
		   which is already the container's left edge. Measured at 414x896:
		   bottom edge at 819 = the hero's 126 + 693. */
		position: absolute;
		bottom: 0;
		width: 100%;
		/* The original framework sets `box-sizing: border-box` on everything
		   (renew.css), so its `width:100%` already contains the 15px of side
		   padding. This theme has no such global rule, so without this the box
		   measures 444px in a 414px viewport and the page scrolls sideways. */
		box-sizing: border-box;
		margin: 0;
		/* The phone size AND colour for this style now live in Appearance >
		   Typography. This is the only style in the build whose colour differs
		   between breakpoints — brand blue on desktop, #444444 on a phone — and
		   it used to need an `!important` here to beat the inline colour the
		   block carried. The block carries no inline colour any more, so the
		   settings screen reaches it with an ordinary class. */
		text-align: center;
	}
}

/* ==========================================================================
   Homepage — Intro band
   `HP_Description_Section` / `_Row1` / `_Row1_Col1`. Measured off the live site
   at 1440x900 and 414x896.

   Structurally the simplest band on the page: full-bleed colour, one centred
   paragraph of text, nothing else. The original's three nested divs collapse to
   a single Group here — the section and row carry no styling of their own (the
   row is a bare `.x-container` with neither `.width` nor `.max`, so it is
   already 100%), and the column is only there to hold the background.
   ========================================================================== */

/* 36px above and below, as padding on the band rather than the original's
   `margin: 36px auto` on the heading.

   Not a stylistic preference. As a margin it would collapse straight out of
   this box — nothing here establishes a block formatting context — and the
   blue would then start below the gap instead of containing it. Padding cannot
   collapse, so it needs no `flow-root` to hold it in. Measured band height
   198px = 36 + 126 + 36.

   The 18px on the sides is not on the live site — David's addition. It does
   nothing above ~1236px, where the 1200px cap already holds the text off the
   edges; it earns its keep between 768px and there, where the text otherwise
   runs flush into the viewport edge. Below 767px the band's padding drops to 0
   and the heading's own 22px/12px takes over, so the 18px deliberately does not
   apply there. */
.barbella-intro {
	padding: 36px 18px;
}

.barbella-intro .barbella-intro-text {
	/* The 1200px cap comes from the heading itself on the live site, not from a
	   container — the row around it is full-width. */
	max-width: 1200px;
	margin: 0 auto;
	/* Type is the “Full Bleed Callout - White” style, defined in `styles/` and editable in
	   Appearance > Editor > Styles > Blocks. Deliberately not restated here:
	   the variation emits `:root :where(...)`, which a single class in this
	   file already ties with and beats on source order — so anything left
	   behind would quietly win and the CMS control would look broken. */
}

@media (max-width: 767px) {
	/* The band stops paying for the gap and the text pays for it instead — the
	   live site swaps to `margin: 0; padding: 22px 12px` here, and the 12px of
	   side padding only exists at this width. Measured band height 212px. */
	.barbella-intro {
		padding: 0 var(--barbella-gutter);
	}

	.barbella-intro .barbella-intro-text {
		/* Only the vertical padding is the text's own; the sides are the band's
		   gutter now. The original put all four on the text. */
		padding: 22px 0;
		/* The phone size for this style now lives in Appearance > Typography,
		   alongside its desktop one. */
	}
}

/* ==========================================================================
   Component — Light band
   `HP_Resume_Section` / `_Row1` / `_Row1_Col1`, which the original reuses for
   two different sections of the homepage. Measured off the live site at
   1440x900, 1024x900, 768x900 and 414x896.

   A full-bleed strip of `#f1f6f8` holding a big blue heading, a line of grey
   copy, and one thing under it — a button on the resume band, a jump arrow on
   the blog lead-in. Add `barbella-band` to a Group and the two child classes to
   its heading and paragraph.

   Written as a component because the original writes it twice with the same
   selectors and David expects more pages. The `barbella-band-*` rules are the
   shared design; anything below them is one instance's own.

   Document B §3 reports the 100px desktop padding on the *column* and the 70px
   mobile padding on the *row*, and flags the two as inconsistent. Measuring
   settles it: on the live site both sit on the row. It is one band padding that
   changes at the breakpoint, nothing more.

   The original's section/row/column nest collapses to a single Group — the
   section and row carry no styling beyond the background, and the text is not
   width-capped at all. It runs the full width of the viewport, centred; at
   1440px the heading box measures 1440px, not 1200px.
   ========================================================================== */

/* 100px above and below, as padding on the band — margins collapse straight out
   of a coloured box (see the intro band above), and the light blue would then
   start below the gap. Measured band heights 406.68px (resume) and 418.29px
   (blog lead-in) at 1440px, both 100 + content + 100. */
.barbella-band {
	padding: 100px 0;
}

/* The blog lead-in ends on the jump arrow rather than on text, and an arrow
   carries dead space with it: it is drawn inside a 64.8px line box (see the
   Blog lead-in component further down for why that number) and only occupies
   the top 38 of it, so 27px of empty line sits under the mark before the
   band's padding even starts. Measured: 129px of white below the arrow against
   118px above the heading's capitals, with both paddings at an identical 100.

   David 2026-08-07 — take the arrow's dead space off the bottom. 102px below
   against 118px above: the lower half now carries slightly less air than the
   upper, which is the usual way round for a band that ends on a small mark.

   Placed here, immediately after the rule it modifies and *before* the mobile
   override below, so the phone's `padding: 70px` shorthand still wins. Written
   further down — next to the rest of the lead-in's rules, where it would
   otherwise belong — it would come after that override and quietly reintroduce
   itself on phones, which is the trap recorded three times in
   `build-decisions.md`. */
.barbella-blog-leadin {
	padding-bottom: 73px;
}

.barbella-band-heading {
	/* Type is the “Full Bleed Title - Blue” style, defined in `styles/` and editable in
	   Appearance > Editor > Styles > Blocks. Deliberately not restated here:
	   the variation emits `:root :where(...)`, which a single class in this
	   file already ties with and beats on source order — so anything left
	   behind would quietly win and the CMS control would look broken. */
	/* `h2{margin:0}` on the live site, and the measured gap between the heading
	   and the paragraph below it is exactly 0. Core's own heading margins would
	   otherwise open one. */
	margin: 0;
}

/* The band class is repeated here purely to raise specificity. Core zeroes the
   bottom margin of whatever block sits last inside its container, which is
   exactly what this paragraph is on the blog lead-in — and that band then
   measured 1.8px shorter than the resume band using the same component. One
   class was not enough to outrank the rule; two are. */
.barbella-band .barbella-band-text {
	/* Type is the “Full Bleed Subtitle - Grey” style, defined in `styles/` and editable in
	   Appearance > Editor > Styles > Blocks. Deliberately not restated here:
	   the variation emits `:root :where(...)`, which a single class in this
	   file already ties with and beats on source order — so anything left
	   behind would quietly win and the CMS control would look broken. */
	/* `p{margin:0 0 0.05em 0}` — 1.8px at this size. Not a typo in the original:
	   it is the whole of the gap between this paragraph and whatever follows it,
	   and neither band adds anything on top of it. */
	margin: 0 0 0.05em;
}

/* Line-height is deliberately absent: 36 x theme.json's root 1.8 = the measured
   64.8px already. */

@media (max-width: 767px) {
	/* Measured band heights 466.88px (resume) and 422.09px (blog lead-in) at
	   414px. */
	.barbella-band {
		padding: 70px var(--barbella-gutter);
	}

	/* Two classes again, for the same reason as the desktop rule above. */
	.barbella-band .barbella-band-text {
		/* The phone size and line-height for this style now live in
		   Appearance > Typography. Only the spacing below is still this file's. */
		/* The 0.05em bottom margin becomes a real 20px gap here. The original's
		   12px of side margin is gone: the band's gutter holds the copy off the
		   edge now, and it holds the heading off too, which the original never
		   did. */
		margin: 12px 0 20px;
	}
}

/* --- Resume band ("There's a lot under the hood") ------------------------- */

.barbella-resume .wp-block-buttons {
	/* Core gives the Buttons block its own block margins. The paragraph's
	   0.05em is the whole of the measured gap, so this contributes none. */
	margin: 0;
}

/* The button itself is styled by the shared `.barbella-cta` component near the
   top of this file. Only the one thing unique to this instance is here. */
.barbella-resume .barbella-resume-button .wp-block-button__link {
	/* A fixed 300px, not a fluid width — the original sets it inline
	   (`style="display:block; width:300px; margin:auto"`) and never overrides it
	   at any breakpoint, so the button is 300px on a 1440px desktop and on a
	   414px phone alike. The LinkedIn button in the quote row is deliberately
	   not fixed this way; it sizes to its label. The measured 300px holds at
	   414px too, so there is no mobile override. */
	width: 300px;
	/* Except on a 320px phone, where 300px plus the band's gutter on each side no
	   longer fits. The button shrinks rather than pushing out of its band — the
	   one place the fixed width has to yield. */
	max-width: 100%;
}

/* The cap has to sit on the wrapper as well. `max-width: 100%` on the link
   resolves against the `.wp-block-button` around it, which is itself 300px
   wide, so on its own it can never bite — the wrapper is what overflows the
   row. */
.barbella-resume .barbella-resume-button {
	max-width: 100%;
}

/* --- Blog lead-in ("There's more to engage with…") ------------------------ */

/* The second line of the paragraph is a link that jumps down to the articles.
   On the live site it is a bare FontAwesome `arrow-circle-o-down` glyph with no
   text at all — invisible to a screen reader and impossible to select in the
   editor.

   Here the link keeps real words. They are hidden from sight but read aloud and
   shown in the editor, so the destination is announced properly and David can
   still click into the link to change where it points. The arrow is drawn by
   CSS in their place. */
.barbella-blog-jump a {
	/* A block, so the arrow gets a line to itself and that line is measured from
	   this link alone. Left inline it would share the paragraph's line box, whose
	   30px strut is taller than the 50.4px line asked for below on one side and
	   made the band 6px too tall. A block box has no strut to compete with.
	
	   The markup therefore carries no `<br>` before the link, unlike the
	   original — a block element already starts its own line, and the `<br>`
	   would open an empty one above it. */
	display: block;
	/* Collapse the label to nothing visible without `display:none`, which would
	   take it out of the accessibility tree along with everything else. */
	font-size: 0;
	/* Stated in px, not as a ratio: the ratio would be multiplied by the
	   `font-size: 0` above and collapse the line to nothing. 64.8px is what the
	   live site gives this line — the paragraph's own 36px x 1.8 — and it is
	   what makes the icon's line as tall as a line of the text above it. */
	line-height: 64.8px;
	text-decoration: none;
	color: var(--wp--preset--color--button);
}

.barbella-blog-jump a::before {
	content: "";
	display: inline-block;
	/* 36px on the live site at every width measured — it does not shrink with the
	   paragraph at mobile, so the size is stated here rather than inherited. The
	   glyph measured 30.86px wide, which is 0.857em of it. */
	font-size: 36px;
	width: 0.857em;
	height: 0.857em;
	vertical-align: -0.16em;
	/* Painted as a mask filled with `currentColor` rather than a coloured SVG, so
	   the arrow inherits the link's colour and the global hover transition can
	   fade it. A data URI with the colour baked in could not. */
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 32 32\'%3E%3Ccircle cx=\'16\' cy=\'16\' r=\'14\' fill=\'none\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3Cpath d=\'M14 8h4v8h5l-7 9-7-9h5z\' fill=\'%23fff\'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 32 32\'%3E%3Ccircle cx=\'16\' cy=\'16\' r=\'14\' fill=\'none\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3Cpath d=\'M14 8h4v8h5l-7 9-7-9h5z\' fill=\'%23fff\'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Drawn from primitives — a ring and an arrow — rather than copied from a
   FontAwesome path. The original glyph is `arrow-circle-o-down`, which is
   exactly those two shapes, and the icon fonts this build replaced are not
   worth re-adding for one mark. */

.barbella-blog-jump a:hover,
.barbella-blog-jump a:focus {
	/* The same darkened orange the buttons use, so every orange thing on the site
	   behaves alike on hover. */
	color: #a84300;
	text-decoration: none;
}

/* This media query sits here rather than up with the band's own, because the
   desktop `line-height` above would otherwise come later in the file and win
   the cascade at equal specificity — which is exactly what it did. A
   breakpoint override has to follow the rule it overrides. */
@media (max-width: 767px) {
	.barbella-blog-jump a {
		/* 50.4px on the live site: the paragraph's 30px x 1.4, applied at the
		   icon's 36px. Without it the band measures ~9px short. */
		line-height: 50.4px;
		/* David 2026-08-07: the arrow crowds the copy above it on a phone and is
		   fine on desktop. It is not the arrow that changed — the paragraph's
		   line-height drops from 1.8 to 1.4 here, which tightens the gap above it
		   by about 11px while the arrow stays 36px. This puts that back. */
		margin-top: 12px;
	}
}

/* ==========================================================================
   Homepage — Quote row
   `HP_QuoteContact_Section` / `_Row1` / `_Col1..3`. Measured off the live site
   at 1440x900, 1024x900, 768x900 and 414x896.

   Three equal columns edge to edge: a quote card, the blue LinkedIn panel, a
   second quote card. All three are the same height and grow together as the
   window narrows, because the row is a flex container and core stretches its
   children — the same thing the original got from `display: table`.

   The quote cards are the `barbella/quote-card` pattern, so the two rules under
   "Quote card" below are the component, not this section: they style every copy
   of that pattern wherever it is inserted. Everything under "LinkedIn panel" is
   one-off content that happens to live here.
   ========================================================================== */

.barbella-quote-row {
	/* Core puts a 24px gutter between columns; the original has none — the three
	   cells meet edge to edge. */
	gap: 0;
}

/* Every panel in the row reaches the full height of the tallest one, so the
   backgrounds — two photos and a block of blue — line up top and bottom
   however the text falls. The original got this free from `display: table`;
   core's Columns block stretches the columns but not their contents, and a
   column is a plain block container, so its child is not a flex item and has
   nothing to stretch against. These two rules supply the missing link. */
.barbella-quote-row > .wp-block-column {
	display: flex;
	flex-direction: column;
}

.barbella-quote-row > .wp-block-column > * {
	flex-grow: 1;
}

/* --- Quote card (the `barbella/quote-card` pattern) ----------------------- */

.barbella-quote {
	/* Core's Cover ships `min-height: 430px`, which would hold the row open at
	   a fixed height and stop it growing with its text as the window narrows —
	   the behaviour David specifically asked to keep. Zero lets the content set
	   the height; the LinkedIn panel beside it is what actually makes the row
	   tall. */
	min-height: 0;
	/* 54px top and bottom plus the 12px the original carries as a margin on the
	   card itself. Padding here instead: as a margin it would collapse out of
	   the Cover, and the measured space above the card is 66px. Sides are 2% of
	   the column, matching the original's `padding: 54px 2%`.

	   The original re-declares 2.5% for the left card only, which makes the two
	   cards different widths on the same row. Not reproduced — a component has
	   one value, and the difference reads as an authoring slip rather than a
	   decision.

	   `2vw`, not `2%`. The original's `2%` is a percentage of its *table*, i.e.
	   the full-width row, because that is what a table-cell resolves padding
	   against. A percentage here would resolve against the column, a third as
	   wide, and give a third of the space. `2vw` reproduces the original value
	   at every width measured: 28.8px at 1440 (live 28.7969), 20.48 at 1024
	   (live 20.4766), 15.36 at 768 (live 15.3594), 8.28 at 414 (live 8.27) —
	   and it keeps working when the column count changes, which a percentage
	   would not. */
	padding: 66px 2vw;
	/* Type is the “Small Section Callout - White” style, defined in `styles/` and editable in
	   Appearance > Editor > Styles > Blocks. Deliberately not restated here:
	   the variation emits `:root :where(...)`, which a single class in this
	   file already ties with and beats on source order — so anything left
	   behind would quietly win and the CMS control would look broken. */
}

/* The photo fills the box and crops whatever does not fit, rather than the
   original's two different and neither-quite-right behaviours (the left column
   showed the image at its natural size and tiled it on a wide screen; the right
   stretched it to the column height). David 2026-08-07.

   Which part survives the crop is the Cover block's focal-point control — the
   draggable dot in the sidebar — so each card is positioned in the editor
   rather than here. That replaces the hand-tuned `background-position` values
   the original kept in CSS. */
.barbella-quote .wp-block-cover__image-background {
	object-fit: cover;
}

/* The bordered dark box the quote sits in. `Quote_Text_Container` on the
   original: `padding:10px; border:solid 1px #fff; background:rgba(0,0,0,0.50)`. */
.barbella-quote .barbella-quote-card {
	padding: 10px;
	border: 1px solid #fff;
	background: rgba(0, 0, 0, 0.5);
	/* Core constrains a Group's children to the 1200px content width; inside a
	   third of the window that would do nothing but it costs nothing to be
	   explicit, and it keeps the box full-bleed within its column. */
	max-width: none;
}

.barbella-quote .barbella-quote-card p {
	/* `.HP_Quotes div{margin:12px 0}`. Adjacent paragraphs collapse to a single
	   12px, which is what makes the measured 280px card height work out; the
	   box's own border stops the first and last from collapsing out. */
	margin: 12px 0;
	color: #fff;
}

/* Bold inside a quote is the editor's Bold button rather than the original's
   hard-coded `<span style="font-weight:700">`, so David can set it while
   typing. Montserrat is a variable font declared `100 900` in theme.json, so
   700 is a real weight here, not a browser-synthesised smear. */
.barbella-quote .barbella-quote-card strong {
	font-weight: 700;
}

/* --- LinkedIn panel ------------------------------------------------------- */

.barbella-linkedin {
	/* `padding:64px 2%`. 10px deeper than the quote cards, which is what lines
	   the heading up with the tops of the two quote boxes beside it. `2vw` for
	   the same reason as the quote card above. */
	padding: 64px 2vw;
	/* The panel is stretched to the row's height by the rule at the top of this
	   section. Its content stays at the top and the slack falls below it, which
	   is what the live site does: measured `vertical-align: top`, 64px above the
	   heading and 107.59px below the button in a 412px cell. */
}

.barbella-linkedin .barbella-linkedin-heading {
	/* Type is the “Small Section Title - Black” style, defined in `styles/` and editable in
	   Appearance > Editor > Styles > Blocks. Deliberately not restated here:
	   the variation emits `:root :where(...)`, which a single class in this
	   file already ties with and beats on source order — so anything left
	   behind would quietly win and the CMS control would look broken. */
	margin: 0;
}

.barbella-linkedin .barbella-linkedin-text {
	/* Font size and line-height come from theme.json's root 16px/1.8, which is
	   what the live site computes. Only the space below the paragraph is here. */
	margin: 0 0 24px;
}

@media (max-width: 767px) {
	/* The three columns stack, full width, in source order: quote, LinkedIn,
	   quote. Core would stack them at 781px; 767px is this theme's breakpoint
	   everywhere else and the original's too, so the Columns block's own
	   stacking is switched off in the block and done here instead. */
	/* Both `!important`s are unavoidable, and they are answering core's own.
	   The block is set to "don't stack on mobile" so that core's 781px rule
	   stays out of the way; core enforces that setting with
	   `.is-not-stacked-on-mobile{flex-wrap:nowrap!important}` and stacks with
	   `flex-basis:100%!important`. Nothing but `!important` outranks either.

	   The selector repeats core's own two classes deliberately. Between two
	   `!important` declarations the more specific one wins, so a lone
	   `.barbella-quote-row` (one class) loses to core's two and the row silently
	   refuses to stack — which is exactly what it did before this was written
	   out longhand. */
	.wp-block-columns.is-not-stacked-on-mobile.barbella-quote-row {
		flex-wrap: wrap !important;
	}

	/* Stacked, each panel is the full width of the phone, so the 2vw that gave
	   a third-width column its breathing room is far too little. The shared
	   gutter takes over — same value as every other band below 767px. */
	.barbella-quote,
	.barbella-linkedin {
		padding-inline: var(--barbella-gutter);
	}

	.barbella-quote-row > .wp-block-column {
		flex-basis: 100% !important;
	}

	/* Side padding drops to the same 2% of a now full-width column, which at
	   414px is the measured 8.27px. Nothing else changes: the original has no
	   mobile overrides for this section at all, and the type stays 24px. */
}

/* ==========================================================================
   Homepage — blog grid (`#Home-Blog-Grid`)
   Document B §6 specced the container only and deferred the grid itself: the
   original is the Essential Grid plugin on its "henryharrison" skin, several
   hundred lines of generated CSS. Rebuilt here on core's Query Loop, measured
   off the live homepage on 2026-08-07.

   What the original does, from its own `tpessential()` config and measured at
   1440, 1024 and 768:

     space: 24            24px between tiles
     aspectratio: "16:9"  every tile, at every width
     row: 3               three rows per page
     forceFullWidth: on   the tiles span the window, not the 1200px row
     columns              3 above 1170, 2 from 1024, 1 below 778
     section padding      20px 0 — the only section on the page that has any

   Three tiles per row over three rows is nine per page, which is what David
   chose (2026-08-07). **Per-page count cannot follow the breakpoints the way
   the original's does.** Essential Grid recounts in the browser; WordPress
   decides `perPage` on the server before the markup exists. The original shows
   9/6/3 per page by width; this shows 9 to everyone.
   ========================================================================== */

.barbella-blog-grid {
	/* `#HP_Blog_Section { padding: 20px 0 }`. Every other section on the
	   homepage is zeroed, so this one really is different rather than mis-read. */
	padding: 20px 0;
}

/* --- Tiles ---------------------------------------------------------------- */

/* Two classes, deliberately. Core prints the column count as a single
   `.wp-container-core-post-template-is-layout-<hash>` rule, and that hash is
   derived from the block's attributes — it changes the moment anyone edits the
   section. A one-class selector here would tie with it and depend on source
   order; two classes win outright and survive the hash changing. */
.barbella-blog-grid .barbella-blog-tiles {
	/* Core already emits `repeat(3, minmax(0, 1fr))` and `gap: 24px` from the
	   block's own grid layout, so the desktop case needs nothing. The two
	   breakpoints below are the part it cannot express. */
	margin: 0;
}

/* Below 1170 the original drops to two across. */
@media (max-width: 1169px) {
	.barbella-blog-grid .barbella-blog-tiles {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Below 778 it drops to one. Core has its own single-column rule but only
   under 600px, written with a four-class selector — between 600 and 778 this
   rule is the only thing standing, and below 600 the two agree. */
@media (max-width: 777px) {
	.barbella-blog-grid .barbella-blog-tiles {
		grid-template-columns: 1fr;
	}
}

.barbella-blog-tile {
	/* The anchor for the overlay, which covers the tile. */
	position: relative;
	/* `li.eg-henryharrison-wrapper { background-color: #ffffff }`. Shows only
	   while an image is still loading, but it stops the tile flashing the page
	   background at that moment. */
	background-color: #fff;
}

.barbella-blog-tile .wp-block-post-featured-image {
	/* Core gives the figure a bottom margin; here the image is the tile. */
	margin: 0;
}

.barbella-blog-tile img {
	/* Kills the inline image's descender gap, which would otherwise show as a
	   sliver of white along the bottom of every tile. */
	display: block;
}

/* --- Hover state ---------------------------------------------------------- */

.barbella-blog-overlay {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	/* `.eg-henryharrison-container { background-color: rgba(49,165,203,0.85) }`.
	   Close to the site's fill blue but not it — measured, so written as found
	   rather than swapped for `--wp--preset--color--accent-fill`. */
	background-color: rgba(49, 165, 203, 0.85);
	opacity: 0;
	/* The site's 200ms standard rather than the original's 1000ms fade. The
	   global rule at the top of this file lists only the four properties the
	   theme's hovers change, and opacity is not one of them — a tile is the
	   first thing here that fades as a whole. */
	transition: opacity 200ms ease-out;
}

/* Keyboard focus opens the tile too — without it the link inside is focusable
   but invisible, which is a worse trap than not being reachable at all.

   `:has(a:focus-visible)`, not `:focus-within`. After paging, core moves focus
   into the new results on purpose:

     n.querySelector( '.wp-block-post-template a[href]' )?.focus()

   — which is right for a screen reader, but `:focus-within` cannot tell that
   scripted focus apart from a real one, so the first tile of every new page
   came up already lit with no pointer anywhere near it. David spotted it,
   2026-08-07. `:focus-visible` is exactly this distinction: the browser sets it
   for keyboard interaction and withholds it for a programmatic focus after a
   click, so a keyboard user paging with Enter still sees where they landed and
   a mouse user does not. */
.barbella-blog-tile:hover .barbella-blog-overlay,
.barbella-blog-tile:has(a:focus-visible) .barbella-blog-overlay {
	opacity: 1;
}

/* --- Paging transition ---------------------------------------------------- */

/* The tiles cross-fade when the page changes, driven by `assets/js/blog-grid.js`
   — core swaps the markup with no transition of its own, so nine images
   replaced each other in a single frame.

   200ms, the site's hover standard. Written first at 300 on the reasoning that
   a band of pictures needs longer to read than a link recolouring; David asked
   for quicker, 2026-08-07, and at 200 the whole site now eases at one speed.

   `FADE` in `assets/js/blog-grid.js` has to match this number: the script holds
   the paging click for exactly that long before letting it through. */
.barbella-blog-tiles {
	transition: opacity 200ms ease-out;
}

.barbella-blog-tiles.is-paging {
	opacity: 0;
}

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

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

.barbella-blog-tile-title {
	/* `.eg-henryharrison-element-1`: 16px / 30px / weight 900 / white /
	   uppercase / `padding: 0 20px` / `margin: 0 0 10px`. Not one of the eleven
	   named text styles — it is a component's own type, like the button's. */
	margin: 0 0 10px;
	padding: 0 20px;
	font-size: 16px;
	line-height: 30px;
	font-weight: 900;
	text-transform: uppercase;
	text-align: center;
	color: #fff;
}

.barbella-blog-tile-title a {
	color: #fff;
	text-decoration: none;
}

/* The whole tile is the link, not just the small mark below the title.

   On the live site the only anchor in a tile is `.eg-henryharrison-element-2`,
   the 43px "+" — the picture and the title are inert. That is a hard target to
   hit and it gives a screen reader a link whose entire accessible name is a
   plus sign. David 2026-08-07: same look, easier to hit.

   Done by stretching the title's own link over the tile rather than by wrapping
   the tile in a second anchor, so there is still exactly one link per tile and
   its name is still the article's title. */
.barbella-blog-tile-title a::after {
	content: "";
	position: absolute;
	inset: 0;
}

/* The mark under the title. `.eg-henryharrison-element-2` is a FontAwesome
   `plus` in a 43px box with `border-radius: 0 60px 60px 60px` — three round
   corners and one square, which is what gives it its lopsided look.

   Drawn as a mask like the other two icons in this file. The original's second
   state (`border-radius: 60px 60px 0 60px`, `background: rgba(0,0,0,0.15)`)
   fired on hovering the "+" alone; now that the whole tile is the link, that
   state is unreachable by definition and is not reproduced. */
.barbella-blog-overlay::after {
	content: "";
	display: block;
	width: 43px;
	height: 43px;
	border-radius: 0 60px 60px 60px;
	background-color: #fff;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 43 43\'%3E%3Cpath d=\'M19.5 12h4v19h-4z\' fill=\'%23fff\'/%3E%3Cpath d=\'M12 19.5h19v4h-19z\' fill=\'%23fff\'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 43 43\'%3E%3Cpath d=\'M19.5 12h4v19h-4z\' fill=\'%23fff\'/%3E%3Cpath d=\'M12 19.5h19v4h-19z\' fill=\'%23fff\'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* --- Paging --------------------------------------------------------------- */

/* Numbered pages above the grid, back and forward below it — David's layout,
   and the original's. Core ships Previous, Numbers and Next as three children
   of one Pagination block, i.e. a single row. Two Pagination blocks are used
   instead, one holding the numbers and one holding the two arrows; both read
   the same query and stay in step with each other.

   `.barbella-blog-pages` is the numbers, `.barbella-blog-nav` the arrows. */
.barbella-blog-pages,
.barbella-blog-nav {
	/* The 5px each button carries below itself is the whole gap between the
	   numbers row and the grid — the rows themselves have no margin. */
	margin: 0;
	/* Core's flex layout puts a default gap between the items; the original
	   spaces them with margins on the buttons, and both at once reads loose. */
	gap: 0;
}

/* `.minimal-light` skin: 12px / 700, `line-height: 38px`, `border: 1px solid
   #e5e5e5`, `border-radius: 5px`, white, `color: #999`.

   Open Sans on the original; Montserrat here, like everything else in this
   build — one font file was a deliberate call at the start of the rebuild. */
.barbella-blog-pages .page-numbers,
.barbella-blog-nav a,
.barbella-blog-nav span {
	display: inline-block;
	border: 1px solid #e5e5e5;
	border-radius: 5px;
	background-color: #fff;
	color: #999;
	font-size: 12px;
	font-weight: 700;
	line-height: 38px;
	text-decoration: none;
}

.barbella-blog-pages .page-numbers {
	/* `padding: 0 16px; margin: 0 5px 5px 0`. */
	padding: 0 16px;
	margin: 0 5px 5px 0;
	/* Every number button the same width. The original's Open Sans has
	   even-width digits at this weight; Montserrat's "1" is narrower than its
	   "2", so button 1 measured 39px against button 2's 41 and the row was
	   visibly uneven. 41px is the original's measured width. */
	min-width: 41px;
	box-sizing: border-box;
	text-align: center;
}

.barbella-blog-pages .page-numbers:last-child {
	margin-right: 0;
}

/* Core wraps the numbers in a div of its own and prints them on separate
   lines, so the whitespace between them collapses to a space and adds ~5px to
   every gap on top of the 5px margin. Flex has no text nodes to collapse. */
.barbella-blog-pages .wp-block-query-pagination-numbers {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
}

/* The page you are on: darker text and a darker border, no fill. */
.barbella-blog-pages .page-numbers.current {
	border-color: #bbb;
	color: var(--wp--preset--color--contrast);
}

/* The two arrows, including the disabled placeholder that stands in for
   whichever one has nowhere to go — see `inc/blog-grid.php`. */
.barbella-blog-nav {
	/* Holds the arrows off the bottom row of tiles, which they sat flush
	   against. David 2026-08-07. 24px is the gap between the tiles themselves,
	   so the space under the grid is the same as the space inside it.

	   Not on the numbers row above: its buttons sit against the top of the grid
	   on the original too, and David only asked about these. */
	margin-top: 24px;
}

.barbella-blog-nav a,
.barbella-blog-nav span {
	/* The arrows are narrower than the numbers on the original — `padding:
	   0 11px; margin: 0 2.5px 5px`. */
	padding: 0 11px;
	margin: 0 2.5px 5px;
	/* Both buttons carry their label as `aria-label` rather than as text: the
	   original shows a bare chevron, and a chevron is what David asked to keep.
	   With no text there is nothing to give the box a width, so it is stated —
	   9px of chevron inside 11px each side is the original's measured 41px. */
	width: 41px;
	box-sizing: border-box;
	text-align: center;
}

/* Drawn as a mask from a single stroked path, like the other icons in this
   file. The original's glyphs are `eg-icon-left-open` / `right-open`, a thin
   chevron pair, which is two line segments and not worth an icon font.

   `inline-block`, not `block`, and sized in px rather than percentages. As a
   block it replaces the button's line box, and with the label gone there is no
   text left to hold the box open — the buttons measured 0 and 2px tall. Inline
   keeps the 38px line-height doing the same job it does on the numbers. */
.barbella-blog-nav a::before,
.barbella-blog-nav span::before {
	content: "";
	display: inline-block;
	width: 9px;
	height: 14px;
	vertical-align: middle;
	background-color: currentColor;
	-webkit-mask: var(--barbella-chevron) center / contain no-repeat;
	mask: var(--barbella-chevron) center / contain no-repeat;
}

.barbella-blog-nav .wp-block-query-pagination-previous::before {
	--barbella-chevron: url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 9 14\'%3E%3Cpath d=\'M7.5 1 1.5 7l6 6\' fill=\'none\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3C/svg%3E");
}

.barbella-blog-nav .wp-block-query-pagination-next::before {
	--barbella-chevron: url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 9 14\'%3E%3Cpath d=\'M1.5 1l6 6-6 6\' fill=\'none\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3C/svg%3E");
}

/* The placeholder reads as unavailable rather than as a button that ignores
   you: paler than the live one, and the cursor never changes over it. */
.barbella-blog-nav .is-disabled {
	color: #d5d5d5;
	border-color: #efefef;
}

.barbella-blog-pages a:hover,
.barbella-blog-pages a:focus,
.barbella-blog-nav a:hover,
.barbella-blog-nav a:focus {
	border-color: #bbb;
	color: var(--wp--preset--color--contrast);
}

/* ==========================================================================
   Clients Served — client list
   `CS_ClientList_Section` / `_Row1` / `_Row1_Col1`. Measured off the live
   https://www.barbella.com/clients-served/ on 2026-08-10 at 1600, 1280, 979,
   767 and 480.

   Three of Document B §2's numbers do not survive the measurement:

   - It reports `padding: 80px 0 0 0` on the row. The live row's computed
     padding is 0 on all four sides. Every bit of the space above the heading
     is the heading's own `0.8em` margin — 57.6px at 72px, 38.4px at 48px.
   - It calls the `:nth-child(-n+4){margin-top:0}` override redundant. It is
     not: at 2-up it removes the 5% gap between the two rows of columns, so
     they sit flush. Reproduced below by giving the columns no row gap at all,
     which is what a single CSS-columns list does anyway.
   - Its subheadline copy for the hero ends in a full stop. The live page's
     does not.

   The 72px white heading is the “Full Bleed Title - White” type style, which
   this section is the reason for.
   ========================================================================== */

/* Full-bleed and *asymmetric*: 16px of padding on the left, none on the right,
   so the fourth column runs to the window edge. That is the live page — the
   band is the one region on the site with no width cap, and David's call on
   2026-08-10 was to reproduce it rather than pull it into
   `.barbella-container` like every other band. Measured 1584px of list inside
   a 1600px window. */
.barbella-client-list {
	padding: 0 0 0 16px;
}

/* The band's entire vertical rhythm. `0.8em` of the heading's own size above
   and below it, which is where Document B's phantom 80px of row padding
   actually comes from. */
.barbella-client-list .barbella-client-list-heading {
	margin: 0.8em 0;
}

@media (max-width: 767px) {
	/* Desktop centres the heading, the phone left-aligns it. Two classes to
	   outrank core's `.has-text-align-center`, which is the block attribute
	   that puts it in the middle in the first place. */
	.barbella-client-list .barbella-client-list-heading {
		text-align: left;
	}
}

/* One List block flowed into four CSS columns, not the original's four
   hand-split `<li>` blocks — the decision recorded in `build-decisions.md`
   on 2026-08-06. Adding a client anywhere reflows the columns; the original
   needs all four rebalanced by hand.

   `columns: 4` with a 5% gap reproduces the original's grid exactly:
   (100% - 3 x 5%) / 4 = 21.25%, which is the measured column width to the
   pixel (268.594px inside a 1264px list). */
/* The band class is repeated here purely to raise specificity, the same trick
   and the same reason as `.barbella-band .barbella-band-text` above: core zeroes
   the bottom margin of whatever block sits last inside its container, and this
   list is exactly that. One class measured a 0px margin; two get the 24px. */
.barbella-client-list .barbella-client-names {
	columns: 4;
	column-gap: 5%;
	/* Core's List block ships a bullet and an indent. The original's names are
	   plain lines of text. */
	list-style: none;
	padding-left: 0;
	/* Measured on the live list. It is the only thing between the last name and
	   the section below. */
	margin: 0 0 24px;
}

/* A name is one line and must not break across a column boundary. */
.barbella-client-list .barbella-client-names li {
	break-inside: avoid;
}

/* The framework's own `.four-up` behaviour, which the original inherits and no
   Clients-Served rule overrides. */
@media (max-width: 979px) {
	.barbella-client-list .barbella-client-names {
		columns: 2;
	}
}

@media (max-width: 480px) {
	.barbella-client-list .barbella-client-names {
		columns: 1;
	}
}

/* ==========================================================================
   Single article
   Document B never specced this page. Everything below was measured live on
   https://www.barbella.com/leadership-actions-making-differences/ at 1440 and
   414 on 2026-08-07 with `getComputedStyle`.

   The original's article sits in `.x-container.max.width.offset`. The `.offset`
   part — the vertical margin — is `#Post-Main` below; the width is the shared
   `.barbella-container` further up this file, the same component the header's
   two rows use.

   That reuse is the point, not a shortcut. theme.json's `contentSize` gives the
   1200px cap but not the 88%, so a container relying on it alone matches the
   header only on screens wider than 1364px and runs edge to edge under every
   one of them while the header keeps its margins. David spotted exactly that,
   2026-08-07: "note on mine that the left and right content areas match the
   edges of the logo and navigation banner". Anything that has to line up with
   the header takes the header's container.

   Deliberately not reproduced: the "The Blog" band the original prints above
   every post (`.x-header-landmark` — 30px of padding between two #f2f2f2
   hairlines, holding a 245% heading). David 2026-08-07: the header above it
   already says whose site this is.

   The original's body copy is 16px/1.8 in #7a7a7a, which is already this
   theme's default from theme.json. Nothing restates it below.
   ========================================================================== */

#Post-Main {
	/* Live `.x-container.offset` is `margin: 2.75em auto` against a 12px root,
	   i.e. 33px. Written in px, not em: this theme's root is 16px, where the
	   same ratio would come out at 44 and open a gap the original has not got. */
	margin-block: 33px;
}

/* --- Title ---------------------------------------------------------------- */

.barbella-post-title {
	/* Live: 27.2px / 29.92px / 1.36px letter-spacing / weight 400 / #333.
	   Written as absolute values rather than the original's 170%-of-inherited,
	   which only resolves to 27.2 because X-theme's root is 12px.

	   Not one of the eleven named text styles, so it belongs in this file. If
	   David later wants it on the Appearance > Typography screen it moves there
	   whole and comes out of here — the two must never both hold it. */
	font-size: 27.2px;
	line-height: 1.1;
	letter-spacing: 0.05em;
	font-weight: 400;
	color: var(--wp--preset--color--contrast);
	margin: 0;
}

/* The pale-orange document mark to the left of the title. The original is
   FontAwesome's `file-text-o` glyph on `.entry-title:before`, tinted #f1ba63 by
   the theme options.

   Drawn here as a mask from primitives — a page, a folded corner, three ruled
   lines — for the same reason as the blog lead-in's arrow further up: this
   build dropped the icon fonts, and one mark is not worth re-adding them for. */
.barbella-post-title::before {
	content: "";
	float: left;
	display: block;
	/* 0.88em of the title, measured 23.936px; the glyph box measured
	   20.52 x 23.94, i.e. 0.857em wide. */
	font-size: 0.88em;
	width: 0.857em;
	height: 1em;
	/* Nudges the mark down onto the cap line rather than the top of the line
	   box. `top: 0.1375em` on the original, which is relative-positioned; a
	   margin does the same thing without the extra positioning context. */
	margin: 0.1375em 0.35em 0 0;
	background-color: #f1ba63;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 28\'%3E%3Cpath d=\'M2.5 1.5h12l7 7v18h-19z\' fill=\'none\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3Cpath d=\'M14.5 1.5v7h7\' fill=\'none\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3Cpath d=\'M6 13h12M6 17.5h12M6 22h8\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 28\'%3E%3Cpath d=\'M2.5 1.5h12l7 7v18h-19z\' fill=\'none\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3Cpath d=\'M14.5 1.5v7h7\' fill=\'none\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3Cpath d=\'M6 13h12M6 17.5h12M6 22h8\' stroke=\'%23fff\' stroke-width=\'2\'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* --- Byline --------------------------------------------------------------- */

.barbella-post-meta {
	/* `.p-meta { margin: 8px 0 0; line-height: 1.5 }`. */
	margin: 8px 0 0;
	line-height: 1.5;
	/* Starts the byline at the left margin rather than beside the title's
	   floated mark, which overhangs a single-line title. */
	clear: both;
}

/* Core gives each of the three blocks inside a margin of its own; the row's
   spacing is the separator's job below. */
.barbella-post-meta > * {
	margin: 0;
}

/* The original is `.p-meta > span:after { content: "/"; padding: 0 0.45em }`.
   A pipe here instead — David 2026-08-07, along with dropping the category link
   that used to sit third in this row.

   Generated, not typed, so the blocks stay ordinary blocks that David can
   reorder or delete in the editor without stranding a separator: whichever one
   ends up last loses its pipe automatically. That is what made removing the
   category a one-block deletion with nothing else to tidy up.

   The Group's `blockGap` is set to 0 in the template so this padding is the
   only space between the items; core's default gap would have doubled it. */
.barbella-post-meta > *::after {
	content: "|";
	padding: 0 0.45em;
}

.barbella-post-meta > *:last-child::after {
	content: none;
}

/* --- Featured image ------------------------------------------------------- */

.barbella-post-featured {
	/* `.entry-featured { margin-top: 25px; border: 2px solid #e5e5e5;
	   padding: 6px; background-color: #fff }` — the thin photo frame. */
	margin: 25px 0 0;
	border: 2px solid #e5e5e5;
	padding: 6px;
	background-color: #fff;
}

/* Kills the few pixels of descender space an inline image leaves under itself,
   which would otherwise show as an uneven bottom edge inside the frame. */
.barbella-post-featured img {
	display: block;
}

/* --- Body ----------------------------------------------------------------- */

.barbella-post .wp-block-post-content {
	/* `.entry-content { margin-top: 25px }`. */
	margin-top: 25px;
}

.barbella-post .wp-block-post-content :where(p, ul, ol) {
	/* Live: `0 / 24px`. Stated because the rhythm would otherwise come from
	   theme.json's spacing scale, which is built for page bands, not prose. */
	margin-block: 0 24px;
}

.barbella-post .wp-block-post-content :where(ul, ol) {
	/* Live: `margin-left: 26.48px; padding-left: 0`. The browser default is 40px
	   of padding, which indents the bullets half again as far.

	   The Post Content block deliberately carries no layout of its own — the
	   article wrapper above it already constrains to 1200px. Giving it a
	   constrained layout too makes core emit
	   `.is-layout-constrained > :where(...) { margin-left: auto !important }`,
	   which beat this rule and flattened the indent to zero. */
	margin-left: 26.48px;
	padding-left: 0;
}

.barbella-post .wp-block-post-content > :last-child {
	/* `.entry-content > p:last-child { margin-bottom: 0 }` — otherwise the last
	   paragraph's 24px lands on top of the 33px below the article. */
	margin-bottom: 0;
}

@media (max-width: 767px) {
	#Post-Main {
		/* The original's second `.x-container.offset` rule, `margin: 2em auto`,
		   measured 24px at 414. */
		margin-block: 24px;
	}
}

/* ==========================================================================
   Search results and Page not found

   The two core-default templates, rendered for the first time on 2026-08-10.
   Both work as written; this is the one thing they were missing.

   Neither uses `.barbella-container` or the band component, so neither inherited
   the site's 20px phone gutter — measured at 414px, the heading, the paragraph
   and the search field all sat flush against both screen edges. Every other page
   holds content off the edge.

   Not inside a media query on purpose. `padding-inline` on a constrained layout
   only bites once the window is narrower than the 1200px content cap, so this is
   the desktop measurement unchanged (content stays 1200px inside 1280px) and the
   gutter appears exactly when it is needed — including between 1200 and 1240,
   where a phone-only rule would still have let the text touch the edge.
   ========================================================================== */

#Error-Main,
#Search-Main {
	padding-inline: var(--barbella-gutter);
}

/* ==========================================================================
   Footer

   Measured off the live site's `footer.x-colophon.bottom` on 2026-08-07:
   background #696969 (the `footer` preset), `padding: 50px 0`, contents
   centred, a 54px circular LinkedIn badge over the site menu.

   Two departures from those measurements, both deliberate:

   1. The band's padding is 40px, not 50px — David's call.
   2. The original spaces its two rows with `margin: 20px 0` on each, so the
      badge sits 70px below the band's top edge (50 + 20) and the menu 70px
      above its bottom. Reproducing that here would make "40px of padding"
      render as 60px of visible space. The outer margins are dropped instead
      and only the 20px between badge and menu is kept, so the 40px is the
      gap you actually see.
   ========================================================================== */

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

/* The row, not the badge. It exists to centre a single inline-block child; the
   badge itself stays inline-block so its own width is its circle, not the
   container's. */
.barbella-footer-social {
	text-align: center;
	/* Gap to the menu below. The menu is a Navigation block, whose <ul> core
	   gives no margin of its own, so the whole 20px is stated here. */
	margin-bottom: 20px;
}

/* Not the topbar's Group-of-Image-plus-Paragraph pattern. That one exists so
   the editor can swap the icon and retype the label per link; this badge has
   no label, one fixed destination, and a mark that is part of the design
   rather than content — a wp:html block keeps it out of the Media Library and
   renders with no upload step. */
.barbella-footer-social-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 54px;
	height: 54px;
	border-radius: 50%;
	/* Translucent white, not a fixed grey. The band's colour is a theme.json
	   preset an editor can change; a hard-coded #7d7d7d would stop tracking it
	   the moment they did. Matches the original's rgba(255,255,255,0.2). */
	background-color: rgba(255, 255, 255, 0.2);
	color: #fff;
}

.barbella-footer-social-link:hover {
	color: var(--wp--preset--color--accent-text);
}

/* 22px inside a 54px circle. The original sizes its glyph with an icon font at
   `font-size: 21px`, which renders about this once the font's own inset is
   taken off. `currentColor` on the SVG's fill is what makes the :hover above
   reach the mark. */
.barbella-footer-social-link svg {
	width: 22px;
	height: 22px;
	/* block kills the inline-SVG baseline gap, which otherwise pushes the mark
	   a pixel below the circle's centre */
	display: block;
}

/* --- Menu ----------------------------------------------------------------- */

/* No `gap`. The separator below is a `::before` on each item after the first,
   so it is part of that item's box — a flex gap would sit outside it and add
   to the separator's own margins, splitting one space into two unequal ones.
   theme.json sets blockGap to 0 globally, which already produces this; it is
   restated because core's Navigation block carries a `2em` fallback and the
   spacing here would break silently if that global ever changed. */
.barbella-footer-nav {
	gap: 0;
	/* Size set on the row, not on the link. The `/` separators are generated on
	   the list items and their margins are in `em`, so with the size on the link
	   the separators would still be scaling off the inherited 16px and measure
	   8.8px instead of the live site's 6.05px. */
	font-size: 11px;
	/* Global line height is 1.8, which gives an 11px row 29px of height and
	   leaves the band visibly taller than the reference. */
	line-height: 1.3;
}

/* The header's search icon, hidden here. Neither Navigation block carries a
   `ref`, so both fall back to the same menu in the database — and that menu
   holds the Search block the header's row needs. The live site does the same
   thing from the other direction: its footer prints `#menu-header-2`, the
   header menu output a second time, with the search living outside the menu
   markup entirely. Hiding it is what keeps one editable menu serving both
   rows; giving the footer its own menu would mean maintaining the same two
   links in two places. */
.barbella-footer-nav > .wp-block-search {
	display: none;
}

.barbella-footer-nav .wp-block-navigation-item__content {
	/* Uppercased in CSS, not by typing capitals, so the words stay readable on
	   the menu screen — same reasoning as `.is-style-navigation-text`. */
	text-transform: uppercase;
	letter-spacing: 1px;
	color: var(--wp--preset--color--base);
	text-decoration: none;
}

.barbella-footer-nav .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--accent-text);
}

/* Generated, not typed between the links: as content the slashes would not be
   editable and would have to be retyped by hand whenever a menu item moved.
   Same approach as the topbar's pipe.

   `::before` on every item but the first, rather than `::after` on every item
   but the last, so a menu that wraps to a second line breaks *before* a slash
   and never leaves one dangling at the end of a line. */
.barbella-footer-nav .wp-block-navigation-item:not(:first-child)::before {
	content: "/";
	/* Asymmetric for the same reason as the topbar's pipe: `letter-spacing: 1px`
	   leaves a further pixel of dead space after the preceding word, so equal
	   margins render tight on the left. 0.55em/0.45em at 11px, matching the
	   live site's measured 6.05px/4.95px. */
	margin-right: 0.55em;
	margin-left: 0.45em;
	color: var(--wp--preset--color--base);
}

/* ==========================================================================
   Typography styles — the parts the settings screen does not own

   Size, letter spacing, line height, weight and colour for the eleven named
   text styles are set in Appearance > Typography and printed after this file.
   These three declarations are the remainder: not typography a person would
   reach for, and nowhere else to put them now that the theme.json partials in
   `styles/` are gone.
   ========================================================================== */

/* The hero's two translucent tints. Measured off the live site; they were
   inline on the blocks until 2026-08-07, which put them one careless edit — and
   one KSES pass — away from being lost. */
.is-style-hero-title {
	background-color: rgba(67, 156, 208, 0.65);
}

.is-style-hero-subtitle {
	background-color: rgba(255, 255, 255, 0.7);
}

/* The menu is uppercased in the stylesheet, not by typing capitals, so the
   words stay readable in the editor and the menu screen. */
.is-style-navigation-text .wp-block-navigation-item__content {
	text-transform: uppercase;
}
