/**
 * Better Moving — base layer.
 *
 * Every value here comes from a semantic token in tokens.css. No literal colour
 * or font appears below; that is what makes the rebrand a one-file change.
 */

*, *::before, *::after { box-sizing: border-box; }

/*
 * The hidden attribute wins, everywhere.
 *
 * The browser's own rule for [hidden] is display: none at the user-agent level,
 * which ANY author rule outranks. So an element given a display by its class -
 * and almost every component here is given one - stays on screen when code sets
 * hidden on it, silently and with no error anywhere.
 *
 * The QA pass on 2026-09-01 found it three times, each with a different cost:
 *
 *   .bm-calc__done  the contact page shipped its "Thanks, that has reached us"
 *                   panel to every visitor who had sent nothing, with an empty
 *                   reference, read aloud by screen readers.
 *   .bm-calc__nav   the calculator's button bar survived onto the confirmation
 *                   step; one more press ran the stepper past its last step,
 *                   threw, and blanked the confirmation and the reference.
 *   .bm-btn         still visible after being hidden - so the contact form's
 *                   Send button stayed live after a successful send, inviting
 *                   the customer to file the same enquiry twice.
 *
 * Three symptoms, one cause, and the next component to be given a display would
 * have been the fourth. Fixed once, here, rather than per class: this file
 * loads on all four surfaces - the public site, the calculator, the board and
 * the office - which is exactly the reach the problem had.
 *
 * !important is correct and not a shortcut. Nothing should ever be styled to be
 * visible while it is carrying hidden, and the drawer, the scrim and the
 * address list animate through their own .is-open classes rather than through
 * this attribute, so none of them is affected.
 */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
	margin: 0;
	background-color: var(--bm-surface);
	color: var(--bm-text);
	font-family: var(--bm-font-body);
	font-size: var(--bm-text-base);
	line-height: var(--bm-leading-normal);
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/*
 * Headings are set heavy to match the logo, which is a bold geometric sans.
 * Sizes are pulled back from the previous identity: a high-contrast serif can
 * carry 5.25rem gracefully, but geometric sans at that weight becomes a wall.
 * Negative tracking is essential — the round wide forms fall apart without it.
 */
h1, h2, h3, h4 {
	font-family: var(--bm-font-display);
	font-weight: var(--bm-weight-display);
	line-height: var(--bm-leading-tight);
	letter-spacing: var(--bm-tracking-tight);
	text-wrap: balance;
	margin: 0;
}
h1 { font-size: clamp(2.25rem, 5.2vw, 3.75rem); }
h2 { font-size: clamp(1.75rem, 3.6vw, 2.75rem); }
h3 { font-size: var(--bm-text-xl); line-height: 1.25; letter-spacing: -0.01em; }

/*
 * Emphasis, taken straight from the mark.
 *
 * The logo differentiates its two words by COLOUR — navy above teal — rather
 * than by weight or style. Reusing that as the site emphasis device makes
 * every headline echo the identity, and it replaces the italic the previous
 * serif provided (Poppins ships no italic here, and a synthesised slant would
 * look exactly like the mistake it is).
 *
 * teal-600 is 3.17:1, which clears AA only for large text — so it is scoped to
 * headings. Anywhere else emphasis falls back to teal-800 at 6.01:1.
 */
.bm-em { color: var(--bm-teal-800); font-style: normal; }
h1 .bm-em, h2 .bm-em { color: var(--bm-teal-600); }

p, ul, ol { margin: 0; }
p { max-inline-size: var(--bm-measure); }

a { color: var(--bm-text-link); text-underline-offset: 0.15em; }
a:hover { text-decoration-thickness: 2px; }

img, svg, video { max-inline-size: 100%; block-size: auto; }

:focus-visible {
	outline: 2px solid var(--bm-border-focus);
	outline-offset: 3px;
	border-radius: var(--bm-radius-sm);
}

/* Keyboard users must be able to bypass the header. Visible on focus only. */
.bm-skip {
	position: absolute;
	inset-inline-start: -9999px;
	z-index: 999;
	padding: var(--bm-space-3) var(--bm-space-6);
	background: var(--bm-action-bg);
	color: var(--bm-action-text);
	border-radius: 0 0 var(--bm-radius-md) 0;
}
.bm-skip:focus { inset-inline-start: 0; }

/* --- layout -------------------------------------------------------------- */
.bm-wrap {
	inline-size: 100%;
	max-inline-size: 72rem;
	margin-inline: auto;
	padding-inline: clamp(1.25rem, 5vw, 3rem);
}
.bm-wrap--narrow { max-inline-size: 46rem; }

.bm-section { padding-block: clamp(3rem, 8vw, 6rem); }
.bm-section--sunken { background: var(--bm-surface-sunken); }
.bm-stack { display: flex; flex-direction: column; gap: var(--bm-space-6); }
.bm-stack--tight { gap: var(--bm-space-3); }

/*
 * Eyebrows now carry the teal. In the previous identity the accent was a rare
 * luxury; in this one it is the brand's energy and should appear on every
 * section, small and repeated, the way the mark uses it.
 */
.bm-eyebrow {
	font-family: var(--bm-font-display);
	font-size: var(--bm-text-xs);
	font-weight: 600;
	letter-spacing: var(--bm-tracking-wide);
	text-transform: uppercase;
	color: var(--bm-teal-800);
}
.bm-lede { font-size: var(--bm-text-lg); color: var(--bm-text-muted); }

/* --- header -------------------------------------------------------------- */
.bm-header {
	position: sticky;
	inset-block-start: 0;
	z-index: 50;
	background: color-mix(in srgb, var(--bm-surface) 88%, transparent);
	backdrop-filter: saturate(140%) blur(10px);
	border-block-end: 1px solid var(--bm-border-subtle);
}
.bm-header__actions { display: flex; align-items: center; gap: var(--bm-space-3); }

/* Everything else about the header and its navigation lives in nav.css.
   The rules that were here hid the nav on small screens with nothing to
   replace it, which left phone visitors no way through the site at all. */

/* --- buttons ------------------------------------------------------------- */
/*
 * Buttons carry the display face and a pill radius. The mark is geometric and
 * the wordmark is built from circles; a tight 6px corner on a button would
 * read as a different design system sitting next to the logo.
 */
.bm-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--bm-space-2);
	font-family: var(--bm-font-display);
	font-size: 0.9375rem;
	font-weight: 600;
	letter-spacing: -0.01em;
	padding: 0.8rem 1.6rem;
	border-radius: var(--bm-radius-pill);
	border: 1px solid transparent;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 140ms ease, transform 90ms ease, box-shadow 140ms ease;
}
.bm-btn--primary { box-shadow: var(--bm-shadow-sm); }
.bm-btn--primary:hover { box-shadow: var(--bm-shadow-md); }
.bm-btn:active { transform: translateY(1px); }
.bm-btn--primary { background: var(--bm-action-bg); color: var(--bm-action-text); }
.bm-btn--primary:hover { background: var(--bm-action-bg-hover); }
.bm-btn--ghost {
	background: var(--bm-action-secondary-bg);
	color: var(--bm-action-secondary-text);
	border-color: var(--bm-action-secondary-border);
}
.bm-btn--ghost:hover { background: var(--bm-surface-sunken); }
/* On a sunken band that hover colour is the ground itself, so the button
   would appear to do nothing. Invert it there. */
.bm-section--sunken .bm-btn--ghost:hover { background: var(--bm-surface); }
.bm-btn--lg { font-size: var(--bm-text-base); padding: 0.95rem 1.9rem; }

/* --- hero ---------------------------------------------------------------- */
/* --------------------------------------------------------------------------
 * Hero
 *
 * The photograph is the thesis: a calm, organised Australian home mid-move.
 * It is the LCP element, so it is served as WebP with a JPEG fallback, sized
 * responsively, and given explicit dimensions so it reserves its space and
 * costs no layout shift.
 * ----------------------------------------------------------------------- */

.bm-hero {
	position: relative;
	padding-block: clamp(3rem, 7vw, 5rem) 0;
	overflow: hidden;
}
.bm-hero__inner { display: grid; gap: var(--bm-space-6); }
.bm-hero__lede { max-inline-size: 46ch; }
.bm-hero__actions { display: flex; flex-wrap: wrap; gap: var(--bm-space-3); align-items: center; }

/* A hero with a full-bleed photograph below it closes itself: the image is its
   bottom edge. A hero without one had nothing, so its buttons sat directly on
   the next section with no air at all. Only the second kind needs padding. */
.bm-hero:not(:has(.bm-hero__bleed)) { padding-block-end: clamp(2.5rem, 5vw, 4rem); }

/* The hero photograph is now full-bleed and lives in sections.css together
   with its caption. The earlier contained-image rules were deleted rather
   than left here to compete on specificity with the ones that replaced them. */

/*
 * Two columns, one balanced block.
 *
 * The heading and the supporting column used to be tied to a shared BOTTOM
 * edge: the middle row took 1fr, so every bit of slack in a tall heading
 * collected above the lede, and the lede and buttons sat together on the
 * heading's last line. That held the two columns together, and it also opened
 * a rectangle of empty ground in the top-right corner — about 135px of it on
 * the home page, bounded by the eyebrow above and the copy below. Space
 * enclosed on both sides does not read as space. It was reported as a block
 * that had failed to load.
 *
 * So the slack is split rather than stacked. All three rows are auto, the
 * heading spans the lower two and centres itself across them, and a spanning
 * item's extra height is divided equally between the tracks it crosses. The
 * lede sits at the bottom of the first of those tracks and the buttons at the
 * top of the second, which keeps the two of them a pair; the leftover height
 * lands half above them and half below. Whichever column is the shorter — the
 * copy on the home page and the service pages, the heading on Contact and the
 * services index — is then centred against the taller one, and no hero can
 * open a void against its own top edge again.
 *
 * A hero with no buttons is the exception: About leaves the third track empty,
 * and an empty track takes all of the distributed space instead of half, which
 * put its lede back at the top. There the lede spans both tracks and centres
 * itself, which is the same result by a shorter route.
 *
 * The row gap read var(--bm-space-5), and there is no --bm-space-5 in
 * tokens.css — the scale runs 1, 2, 3, 4, 6, 8, 12, 16, 24. An undefined
 * custom property makes the declaration invalid at computed-value time, so the
 * gap resolved to 0 and the buttons sat flush against the last line of the
 * lede, with no air at all. The gap is a token that exists now, and it stays
 * small on purpose: the same gap separates the eyebrow from the heading, and
 * an eyebrow belongs against its heading. The air the buttons need is a margin
 * on the buttons instead, so the two distances can differ.
 *
 * Every hero on the site is this same markup — the home page, the five service
 * pages, the services index, the calculator, Contact and About — so this holds
 * them all in one place.
 */
@media (min-width: 60rem) {
	.bm-hero__inner {
		grid-template-columns: 1.25fr 1fr;
		grid-template-rows: auto auto auto;
		column-gap: var(--bm-space-12);
		row-gap: var(--bm-space-2);
	}
	.bm-hero .bm-eyebrow { grid-column: 1 / -1; grid-row: 1; }
	.bm-hero h1 { grid-column: 1; grid-row: 2 / span 2; align-self: center; max-inline-size: 13ch; }
	.bm-hero__lede { grid-column: 2; grid-row: 2; align-self: end; margin-block-end: 0; }
	.bm-hero__actions {
		grid-column: 2;
		grid-row: 3;
		align-self: start;
		margin-block-start: var(--bm-space-4);
	}
	.bm-hero__inner:not(:has(.bm-hero__actions)) .bm-hero__lede {
		grid-row: 2 / span 2;
		align-self: center;
	}
}

/* --------------------------------------------------------------------------
 * Motion
 *
 * One idea, applied consistently: content settles into place as it arrives.
 * No parallax, no scroll-jacking, nothing that delays reading. Elements are
 * visible by default and only animate once the script confirms it may — so a
 * failed script or a reduced-motion preference leaves a perfectly readable
 * page rather than a blank one.
 * ----------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
	.js-motion [data-reveal] {
		opacity: 0;
		transform: translateY(10px);
		/*
		 * 400ms, not 600. Content that takes most of a second to become
		 * readable is not elegance, it is an obstacle — someone scrolling at
		 * normal speed would be reading blank space. Motion should land
		 * before the eye arrives, never after.
		 */
		transition: opacity 400ms cubic-bezier(0.22, 1, 0.36, 1),
					transform 400ms cubic-bezier(0.22, 1, 0.36, 1);
		transition-delay: var(--reveal-delay, 0ms);
	}
	.js-motion [data-reveal].is-in {
		opacity: 1;
		transform: none;
	}
}

/* Printing does not scroll, so nothing would ever be revealed. */
@media print {
	[data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* --- cards --------------------------------------------------------------- */
.bm-grid {
	display: grid;
	gap: var(--bm-space-4);
	grid-template-columns: repeat(auto-fit, minmax(16.5rem, 1fr));
}

/*
 * Cards were the weakest thing on the page: small type inside a hairline box,
 * which is the most generic pattern on the web. Fixed by giving them room and
 * letting the display face into the heading, so they read as part of the same
 * typographic system as everything above rather than as a widget.
 */
.bm-card {
	display: flex;
	flex-direction: column;
	gap: var(--bm-space-3);
	padding: var(--bm-space-8) var(--bm-space-6);
	background: var(--bm-surface-raised);
	border: 1px solid var(--bm-border-subtle);
	border-radius: var(--bm-radius-lg);
	transition: border-color 160ms ease, transform 160ms ease, box-shadow 160ms ease;
}
.bm-card h3 { font-size: 1.5rem; line-height: 1.1; }
.bm-card p { font-size: 0.9375rem; color: var(--bm-text-muted); line-height: 1.55; }

.bm-card:hover {
	border-color: var(--bm-ink-300);
	transform: translateY(-2px);
	box-shadow: var(--bm-shadow-md);
}

/*
 * A card heading that is also a link should not carry a default underline —
 * the whole card already reads as one target. The underline returns on hover
 * and focus so the affordance is never lost, and focus stays visible for
 * keyboard users.
 */
.bm-card h3 a { color: var(--bm-text); text-decoration: none; }
.bm-card h3 a:hover { color: var(--bm-text-link); text-decoration: underline; }
.bm-card:has(h3 a:hover) { border-color: var(--bm-border-interactive); }

/* --------------------------------------------------------------------------
 * Split comparison
 *
 * Deliberately NOT cards. Three identical bordered boxes was the page's most
 * generic moment, and this section is making a comparison — two things set
 * against each other — so it is drawn as a comparison: a rule between them,
 * larger type, no boxes.
 * ----------------------------------------------------------------------- */

.bm-split { display: grid; gap: var(--bm-space-8); }
.bm-split__half { display: flex; flex-direction: column; gap: var(--bm-space-3); }
.bm-split__label {
	font-size: var(--bm-text-xs);
	font-weight: 600;
	letter-spacing: var(--bm-tracking-wide);
	text-transform: uppercase;
	color: var(--bm-text-muted);
}
.bm-split__claim { font-size: clamp(1.75rem, 3.5vw, 2.5rem); }
.bm-split__half p { color: var(--bm-text-muted); }

@media (min-width: 52rem) {
	.bm-split { grid-template-columns: 1fr 1fr; column-gap: var(--bm-space-12); }
	.bm-split__half + .bm-split__half {
		padding-inline-start: var(--bm-space-12);
		border-inline-start: 1px solid var(--bm-border-subtle);
	}

	/*
	 * Three across, for a heading that promises three.
	 *
	 * About says "Three things we decided at the start" and carried two halves
	 * and a footnote, because .bm-split is a pair and the third had nowhere to
	 * go. The gap and the padding come in, because three columns of this copy at
	 * the two-column spacing leaves each one too narrow to read.
	 */
	.bm-split--three {
		grid-template-columns: repeat(3, 1fr);
		grid-template-rows: auto auto auto;
		column-gap: var(--bm-space-8);
		row-gap: var(--bm-space-3);
	}
	.bm-split--three .bm-split__half + .bm-split__half { padding-inline-start: var(--bm-space-8); }
	.bm-split--three .bm-split__claim { font-size: clamp(1.375rem, 2.2vw, 1.75rem); }

	/*
	 * Label, heading and paragraph line up across all three columns.
	 *
	 * "Told, not discovered." fits on one line and the other two headings take
	 * two, so the paragraphs started at three different heights and the row read
	 * as ragged. Subgrid is the fix rather than a min-height on the heading: a
	 * fixed height is a guess about one viewport and one wording, and it breaks
	 * the first time either changes. Here each card hands its three rows back to
	 * the parent, so every row is as tall as the tallest card needs and they all
	 * start together — at any width, with any copy.
	 *
	 * Behind @supports because a browser without subgrid must not be left with
	 * three broken cards. Without it each card stays the flex column it already
	 * is, headings ragged exactly as they are today, which is the current state
	 * rather than a new fault.
	 */
	@supports (grid-template-rows: subgrid) {
		.bm-split--three .bm-split__half {
			display: grid;
			grid-template-rows: subgrid;
			grid-row: span 3;
			row-gap: var(--bm-space-3);
		}
	}
}

/* A single emphasised aside. The accent rule is the only place the signal
   colour appears in this section, which is what keeps it meaning something. */
.bm-note {
	padding: var(--bm-space-6);
	background: var(--bm-surface-raised);
	border-radius: var(--bm-radius-md);
	border-inline-start: 3px solid var(--bm-signal-500);
}
.bm-note p { max-inline-size: 80ch; font-size: var(--bm-text-base); }
.bm-note strong { color: var(--bm-text); }

/* --------------------------------------------------------------------------
 * Closing call to action
 *
 * Inverted, full width. The page has been light throughout; going dark at the
 * end gives the close weight and stops the last screen reading like one more
 * section.
 * ----------------------------------------------------------------------- */

.bm-cta {
	background: var(--bm-ink-900);
	color: var(--bm-paper-50);
	padding-block: clamp(4rem, 9vw, 7rem);
}
.bm-cta__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--bm-space-4);
	text-align: center;
}
.bm-cta h2 { color: var(--bm-paper-50); max-inline-size: 16ch; }
.bm-cta p { color: var(--bm-ink-300); max-inline-size: 46ch; }
.bm-btn--invert { background: var(--bm-paper-50); color: var(--bm-ink-900); }
.bm-btn--invert:hover { background: var(--bm-paper-200); }

/* --- steps --------------------------------------------------------------- */
.bm-steps { display: grid; gap: var(--bm-space-6); grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); list-style: none; padding: 0; }
.bm-steps li { display: flex; flex-direction: column; gap: var(--bm-space-2); }
.bm-steps .n {
	font-family: var(--bm-font-mono);
	font-size: var(--bm-text-xs);
	font-variant-numeric: tabular-nums;
	color: var(--bm-text-muted);
	padding-block-end: var(--bm-space-2);
	border-block-end: 1px solid var(--bm-border-subtle);
}

/* --- footer -------------------------------------------------------------- */
.bm-footer { background: var(--bm-surface); border-block-start: 1px solid var(--bm-border-subtle); padding-block: var(--bm-space-12); }
.bm-footer__inner { display: grid; gap: var(--bm-space-8); grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.bm-footer h2 { font-size: var(--bm-text-sm); font-family: var(--bm-font-body); letter-spacing: var(--bm-tracking-wide); text-transform: uppercase; color: var(--bm-text-muted); }
.bm-footer ul { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--bm-space-2); }
.bm-footer a { color: var(--bm-text); text-decoration: none; font-size: var(--bm-text-sm); }
.bm-footer a:hover { color: var(--bm-text-link); text-decoration: underline; }
.bm-colophon {
	margin-block-start: var(--bm-space-8);
	padding-block-start: var(--bm-space-6);
	border-block-start: 1px solid var(--bm-border-subtle);
	font-size: var(--bm-text-xs);
	color: var(--bm-text-muted);
}

/* --- article / prose ----------------------------------------------------- */
.bm-prose { display: flex; flex-direction: column; gap: var(--bm-space-4); }
.bm-prose h2 { margin-block-start: var(--bm-space-6); }
.bm-prose ul, .bm-prose ol { padding-inline-start: 1.25rem; display: flex; flex-direction: column; gap: var(--bm-space-2); }

/* --- 404 ----------------------------------------------------------------- */
.bm-404 { padding-block: clamp(4rem, 12vw, 8rem); }
.bm-404 h1 { font-size: var(--bm-text-4xl); }

/* Said by postcode.js when a typed postcode contradicts the chosen state. It
   corrects nobody — it points out that one of the two is a typo. */
.bm-postcode-note {
	display: block;
	margin-block-start: 0.3rem;
	font-size: 0.8125rem;
	color: var(--bm-text-muted, #54687f);
}
.bm-postcode-note[data-warn] { color: #8a5a00; font-weight: 600; }

/* The G-NAF attribution. Small, but present on every page — the licence on the
   suburb data requires it wherever the data is used. */
.bm-colophon__attribution {
	margin: 0.6rem 0 0;
	font-size: 0.75rem;
	line-height: 1.5;
	color: var(--bm-text-muted, #54687f);
	max-inline-size: 68ch;
}
.bm-colophon__attribution a { color: inherit; text-decoration: underline; }

/* A reminder aimed at staff, never at a visitor. Shown only to a signed-in
   administrator while a piece of gated copy is still unpublished. */
.bm-staff-flag {
	position: fixed;
	inset-block-end: 1rem;
	inset-inline-start: 1rem;
	z-index: 90;
	max-inline-size: 26rem;
	padding: 0.85rem 1.1rem;
	border-radius: 12px;
	border: 1px solid #8a5a00;
	border-inline-start-width: 4px;
	background: #fdf3e0;
	color: #6b4600;
	font-size: 0.8125rem;
	line-height: 1.5;
	box-shadow: 0 8px 24px rgb(6 23 47 / 16%);
}
.bm-staff-flag strong { display: block; margin-block-end: 0.15rem; }

/* Social profiles. The markup only renders when bm_social_links() finds any,
   so this styles a row that is absent until the accounts have something on
   them — see functions.php for why an empty profile is worse than no icon. */
.bm-social { display: flex; gap: 0.6rem; list-style: none; margin: var(--bm-space-4) 0 0; padding: 0; }

.bm-social__link {
	display: grid;
	place-items: center;
	inline-size: 2.25rem;
	block-size: 2.25rem;
	border: 1px solid var(--bm-border-subtle);
	border-radius: 50%;
	color: inherit;
	transition: border-color 160ms ease, background-color 160ms ease;
}
.bm-social__link:hover { border-color: currentColor; background: rgb(255 255 255 / 8%); }

.bm-social__icon {
	inline-size: 1.05rem;
	block-size: 1.05rem;
	background: currentColor;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

/* Masks rather than <img>, so each icon inherits the surrounding colour and
   costs no extra request. */
.bm-social__icon--facebook {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M14 9h3V6h-3c-2.2 0-4 1.8-4 4v2H8v3h2v7h3v-7h3l1-3h-4v-2c0-.6.4-1 1-1z'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M14 9h3V6h-3c-2.2 0-4 1.8-4 4v2H8v3h2v7h3v-7h3l1-3h-4v-2c0-.6.4-1 1-1z'/%3E%3C/svg%3E");
}
.bm-social__icon--instagram {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 2h10a5 5 0 0 1 5 5v10a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5V7a5 5 0 0 1 5-5zm0 2a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V7a3 3 0 0 0-3-3H7zm5 3.5a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9zm0 2a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM17.8 6a1.2 1.2 0 1 1 0 2.4 1.2 1.2 0 0 1 0-2.4z'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 2h10a5 5 0 0 1 5 5v10a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5V7a5 5 0 0 1 5-5zm0 2a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V7a3 3 0 0 0-3-3H7zm5 3.5a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9zm0 2a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM17.8 6a1.2 1.2 0 1 1 0 2.4 1.2 1.2 0 0 1 0-2.4z'/%3E%3C/svg%3E");
}
.bm-social__icon--linkedin {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5zM3 9h4v12H3zM9 9h3.8v1.7h.05c.53-1 1.83-2.05 3.77-2.05C20.5 8.65 21 11.3 21 14.2V21h-4v-6c0-1.43-.03-3.27-2-3.27-2 0-2.3 1.56-2.3 3.17V21H9z'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5zM3 9h4v12H3zM9 9h3.8v1.7h.05c.53-1 1.83-2.05 3.77-2.05C20.5 8.65 21 11.3 21 14.2V21h-4v-6c0-1.43-.03-3.27-2-3.27-2 0-2.3 1.56-2.3 3.17V21H9z'/%3E%3C/svg%3E");
}
.bm-social__icon--youtube {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23 12s0-3.5-.45-5.18a2.6 2.6 0 0 0-1.83-1.84C19.05 4.5 12 4.5 12 4.5s-7.05 0-8.72.48A2.6 2.6 0 0 0 1.45 6.8C1 8.5 1 12 1 12s0 3.5.45 5.18a2.6 2.6 0 0 0 1.83 1.84C4.95 19.5 12 19.5 12 19.5s7.05 0 8.72-.48a2.6 2.6 0 0 0 1.83-1.84C23 15.5 23 12 23 12zM9.75 15.25v-6.5L15.5 12z'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23 12s0-3.5-.45-5.18a2.6 2.6 0 0 0-1.83-1.84C19.05 4.5 12 4.5 12 4.5s-7.05 0-8.72.48A2.6 2.6 0 0 0 1.45 6.8C1 8.5 1 12 1 12s0 3.5.45 5.18a2.6 2.6 0 0 0 1.83 1.84C4.95 19.5 12 19.5 12 19.5s7.05 0 8.72-.48a2.6 2.6 0 0 0 1.83-1.84C23 15.5 23 12 23 12zM9.75 15.25v-6.5L15.5 12z'/%3E%3C/svg%3E");
}

/* Defined here too: the theme uses it for the social labels and never had it. */
.screen-reader-text {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ============================================================================
 * MOBILE ADAPTATION
 * ============================================================================
 * Everything below is additive and everything that changes layout is inside a
 * max-width query, so none of it can reach 1280px. That is deliberate: the
 * brief was to adapt the site to a phone without redesigning it, and a query
 * that cannot match is a stronger guarantee of "desktop is unchanged" than any
 * amount of review.
 *
 * Measured on the live site at 320px before this block existed: no horizontal
 * overflow anywhere, but fourteen tap targets under 44px on the home page —
 * eleven of them footer links 18px tall on a 31px pitch, where a mis-tap lands
 * on the neighbour.
 * ========================================================================== */

/* --- global, and deliberately so ------------------------------------------
   These three change no geometry, so they need no breakpoint.

   `break-word` and not `anywhere`: `anywhere` alters an element's min-content
   size contribution, which changes flex and grid track sizing at EVERY width,
   1280px included. `break-word` only breaks a word that would otherwise
   overflow its own line. The selectors are named rather than universal for the
   same reason — this is for boxes that hold data somebody else typed. */
.bm-footer a,
.bm-colophon,
.bm-colophon__attribution,
.bm-prose,
.bm-policy,
.bm-lede {
	overflow-wrap: break-word;
}

/* Deliberately NOT here: a global `overscroll-behavior-y: none` on html. It
   would stop the drawer chaining its scroll to the page behind it, which is a
   real defect, but it also switches off pull-to-refresh on Android for every
   visitor at every width — a behaviour change well outside "adapt it to a
   phone". Scroll chaining is contained on the panel that scrolls, in the file
   that owns that panel. */


@media (max-width: 79.99rem) {

	/* --- the tap-target utility ------------------------------------------
	   Defined only in here, so it is provably empty at desktop. Components
	   apply the class instead of each file inventing its own 44px rule and
	   letting stylesheet load order decide which one wins. */
	.bm-tap {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-block-size: var(--bm-tap-min);
		min-inline-size: var(--bm-tap-min);
	}

	/* --- the iOS zoom guard ----------------------------------------------
	   Safari zooms the viewport when a control under 16px takes focus, and it
	   does not zoom back: the visitor finishes the form at 1.3x with a
	   horizontal scrollbar they cannot get rid of.

	   This is a floor for controls nothing else styles — the price form in the
	   operations system has bare inputs that inherit the UA default of about
	   13.3px.

	   The types are enumerated rather than excluded with :not(), and that is
	   the whole point. A chain of :not([type=...]) carries the specificity of
	   its arguments, which would have put this rule above every component's own
	   input styling and let one line in this file quietly resize controls in
	   five other stylesheets. Enumerated attribute selectors tie with those
	   component rules instead, and base.css loads first, so the component keeps
	   its own value. Only genuinely unstyled controls land here.

	   Every control that IS styled below 16px is therefore fixed where it is
	   declared: address.css, office.css and the load board's app.css. */
	input[type="text"], input[type="email"], input[type="tel"],
	input[type="number"], input[type="password"], input[type="search"],
	input[type="url"], input[type="date"], input[type="datetime-local"],
	input[type="month"], input[type="time"], input[type="week"],
	select, textarea {
		font-size: 1rem;
	}

	/* --- the footer ------------------------------------------------------
	   Fifteen links stacked at a 31px pitch is the largest single cluster of
	   under-size targets on the public site. Padding the anchor rather than
	   growing the gap keeps the visual rhythm and moves the hit area.

	   Declared as a minimum rather than computed from padding: 0.65rem either
	   side of a 23px line comes to 43.8px, which rounds to 44 in a report and
	   is still under it in the hand. A floor cannot be got wrong by arithmetic. */
	.bm-footer ul { gap: 0; }
	.bm-footer a {
		display: flex;
		align-items: center;
		min-block-size: var(--bm-tap-min);
		padding-block: 0.4rem;
	}

	/* The G-NAF attribution sits inside a sentence of licence text, and WCAG
	   2.5.8 exempts a link in that position for good reason: growing it to 44px
	   would mean opening up 12px fine print until it no longer reads as fine
	   print, which is a redesign nobody asked for.

	   Padding on an INLINE box extends the hit area without entering the line
	   box, so the target grows and the paragraph does not move. Making it
	   inline-block would do the opposite — it would shift the layout AND cost
	   the element its exemption.

	   The selector names .bm-footer because the rule above makes every anchor
	   in the footer a 44px flex box, and at equal specificity it had been
	   winning: "Geoscape Australia" sat on a line of its own, with the rest of
	   the sentence starting on the next line at a comma. */
	.bm-footer .bm-colophon__attribution a {
		display: inline;
		min-block-size: 0;
		padding-block: 0.5rem;
	}

	/* Renders only once a social account has something on it, but it would
	   have shipped at 36px. */
	.bm-social__link { inline-size: var(--bm-tap-min); block-size: var(--bm-tap-min); }
}


@media (max-width: 61.99rem) {

	/* A blurred backdrop behind a sticky header repaints every scroll frame,
	   which a mid-range Android feels. Below the nav switch there is no
	   translucent nav to see through anyway, so it buys nothing. */
	.bm-header {
		backdrop-filter: none;
		background: var(--bm-surface);
	}

	/* Shown only to a signed-in administrator, and only while gated copy is
	   unpublished — but it is position:fixed with a start inset, no end inset
	   and a 26rem max, so it shrink-to-fits up to 432px and hangs 112px off a
	   320px screen. Pinning both insets makes it follow the viewport, and the
	   safe-area inset keeps it off the home indicator. */
	.bm-staff-flag {
		inset-inline: 1rem;
		max-inline-size: none;
		inset-block-end: calc(1rem + env(safe-area-inset-bottom, 0px));
	}

	/* --- the footer, centred ---------------------------------------------
	   On a phone the footer is one column, and it was half centred: the links
	   sat in the middle only by accident, because `.bm-tap` brings a
	   justify-content that the footer's own display:flex never overrides,
	   while the headings, the line under the mark and the colophon stayed on
	   the left. Everything now shares one axis.

	   The link lists alone keep the full width, so each link's tap area is
	   still the whole row rather than the width of its words. */
	.bm-footer__inner { text-align: center; }
	.bm-footer__inner > .bm-stack { align-items: center; }
	.bm-footer__inner > .bm-stack > ul { align-self: stretch; }
	.bm-footer a { justify-content: center; }

	/* Both axes, because `.bm-footer ul` outranks `.bm-social` and turns the
	   row into a column; centred either way. It renders only once a social
	   account exists. */
	.bm-footer .bm-social { align-items: center; justify-content: center; }

	.bm-colophon { text-align: center; }
	.bm-colophon__attribution { margin-inline: auto; }
}


@media (max-width: 47.99rem) {

	/* A hard 3rem that overrides the h1 clamp, so the 404 heading is set
	   larger than every other h1 on the site at exactly the width where there
	   is least room for it. */
	.bm-404 h1 { font-size: clamp(2rem, 8vw, var(--bm-text-4xl)); }

	/* the_posts_pagination() emits .nav-links and the theme has never styled
	   it, so it renders as bare inline text about 20px tall. Only the fallback
	   blog template reaches this, which is why nobody has noticed. */
	.bm-prose + .nav-links a,
	.nav-links .page-numbers {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-block-size: var(--bm-tap-min);
		min-inline-size: var(--bm-tap-min);
		padding-inline: 0.9rem;
	}
}
