/**
 * Omega CRM, the public stylesheet.
 *
 * Two customer-facing surfaces use it and nothing else does. The Keep Updated
 * form, which can be shortcoded on to any page, and the preference centre at
 * /crm-preferences/, which is the same set of controls as the My Account tab.
 *
 * WHY IT IS A FILE AND NOT A <style> BLOCK
 *
 * Both surfaces used to print their own scoped <style> on every render. That
 * carried two copies of the same token fallbacks, could never be cached, cost
 * bytes on every page view of a page holding the form, and meant the tick tile
 * had to be edited twice, in PHP, in two classes that do not know about each
 * other. One file, versioned on OMEGA_CRM_VERSION, enqueued only by the code
 * that draws the markup it styles.
 *
 * WHAT IT DELIBERATELY DOES NOT DO
 *
 * It does not restate the theme. Inputs, labels, hints, errors, buttons and
 * notices are the theme's own .enquiry, .btn and .notice components, and the
 * markup asks for those class names on purpose so a sign-up looks like the shop
 * rather than like a plugin. Everything below is a rule the theme has no
 * selector for.
 *
 * TOKENS, AND WHY EVERY ONE CARRIES A LITERAL
 *
 * Colours, spacing and tap sizes are the theme's custom properties from
 * themes/omega/src/css/tokens.css. Each is written with the value it resolves to
 * today as its fallback, because a plugin outlives the theme it was written
 * beside. Switch the theme and these surfaces still draw a bordered tile in the
 * right navy on the right paper, instead of a borderless one in whatever the
 * browser does with an empty var().
 *
 * The one trap from tokens.css carries over unchanged. White text on the action
 * amber is 1.73:1 and is banned, so amber surfaces take ink text. Nothing here
 * paints an amber surface at all, which is the surest way of honouring it. The
 * two amber buttons on these surfaces are the theme's .btn--primary, which
 * already sets --c-action-ink on itself.
 *
 * ERGONOMICS
 *
 * Tap floor 48px on every tick, 56px on the submit. These are read standing up,
 * on site, in gloves, and the preference page in particular is opened from a
 * link in a text message, so it is a phone screen first and a desktop second.
 *
 * SCOPE
 *
 * Every selector starts at .omega-crm-signup or .omega-crm-prefs, the two
 * wrappers the plugin prints, so nothing here can reach anything the plugin did
 * not draw.
 */

/* ============================================ the tick tile, both surfaces */

/*
 * A whole tile is the target, not the 24px box inside it. The old CRM's form
 * put a bare checkbox next to a bare label with nothing joining them, which on
 * a phone is a 13px target beside an unclickable word.
 */
.omega-crm-signup .omega-crm-grid__item,
.omega-crm-prefs .omega-crm-prefs__tick {
	display: flex;
	gap: var(--s-3, 0.75rem);
	min-height: var(--tap-min, 48px);
	border: 2px solid var(--c-line, #dedcd6);
	border-radius: var(--radius, 10px);
	background: var(--c-surface, #fff);
	cursor: pointer;
}

/*
 * The ring is on the tile, not on the box, because the box is what takes focus
 * and a 24px ring on a 48px target is a keyboard user hunting for their own
 * cursor. --focus-ring is the theme's own ring, declaration and all rather than
 * just a colour, so a change to it in tokens.css reaches this file too. It used
 * to say --c-focus, which no stylesheet here defines.
 */
.omega-crm-signup .omega-crm-grid__item:focus-within,
.omega-crm-prefs .omega-crm-prefs__tick:focus-within {
	border-color: var(--c-brand, #142a42);
	outline: var(--focus-ring, 3px solid #142a42);
	outline-offset: 1px;
}

/* 24px, because the browser default is about 13px and this is used in gloves. */
.omega-crm-signup .omega-crm-grid__item input,
.omega-crm-prefs .omega-crm-prefs__tick input {
	width: 24px;
	height: 24px;
	flex: none;
	accent-color: var(--c-brand, #142a42);
}

/* ================================================== the Keep Updated form */

/* The browser's own fieldset chrome, removed. The legend carries the grouping. */
.omega-crm-signup .omega-crm-grid {
	border: 0;
	padding: 0;
	margin: var(--s-5, 1.5rem) 0 0;
}

/*
 * auto-fit at a 15rem minimum, so twelve trades are one column on a phone and
 * as many as fit on a counter tablet, with no breakpoint to maintain.
 */
.omega-crm-signup .omega-crm-grid__items {
	display: grid;
	gap: var(--s-2, 0.5rem);
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.omega-crm-signup .omega-crm-grid__item {
	align-items: center;
	padding: var(--s-2, 0.5rem) var(--s-3, 0.75rem);
}

/*
 * The consent group's error state. An outline rather than a border, so the
 * fieldset does not resize and shove the submit button down the page when the
 * form comes back invalid. Never colour alone: the message above it is real
 * text, and it is linked from the error summary at the top of the form.
 */
.omega-crm-signup .omega-crm-consent.is-invalid {
	outline: 2px solid var(--c-danger, #b91c1c);
	outline-offset: 4px;
}

/* =================================================== the preference centre */

/*
 * Narrower than the theme's prose measure. This page is a short list of
 * decisions, and a 40rem column keeps the tick and its explanation on the same
 * line of sight on a laptop.
 */
.omega-crm-prefs {
	max-width: 40rem;
}

.omega-crm-prefs__title {
	margin-top: 0;
}

.omega-crm-prefs__notice {
	padding: var(--s-4, 1rem);
	border-radius: var(--radius, 10px);
}

.omega-crm-prefs__who {
	color: var(--c-ink-2, #3f5765);
}

.omega-crm-prefs__set {
	border: 0;
	padding: 0;
	margin: var(--s-5, 1.5rem) 0 0;
}

.omega-crm-prefs__set legend {
	font-weight: var(--fw-bold, 700);
	padding: 0;
}

.omega-crm-prefs__tick {
	align-items: flex-start;
	padding: var(--s-3, 0.75rem);
	margin-top: var(--s-3, 0.75rem);
}

/* Optical alignment: the box sits with the first line of the label, not with
   the top of a two-line block. */
.omega-crm-prefs__tick input {
	margin-top: 2px;
}

/* What the switch is set to right now, under what it does. Two different
   things, so they are not the same weight or the same colour. */
.omega-crm-prefs__tick small {
	display: block;
	color: var(--c-ink-3, #546977);
}

.omega-crm-prefs__note,
.omega-crm-prefs__service,
.omega-crm-prefs__help {
	color: var(--c-ink-2, #3f5765);
	font-size: var(--t-sm, 1rem);
}

/* 56px. This is the button the whole page exists for. */
.omega-crm-prefs__save {
	min-height: var(--tap-primary, 56px);
	margin-top: var(--s-5, 1.5rem);
}

/*
 * "Stop everything", or "put me back on the list", below a rule and away from
 * the save button. Separated because it is the opposite decision and a thumb
 * must not find it by accident, and never hidden, because an unsubscribe that
 * takes hunting for is the reason people press the spam button instead.
 */
.omega-crm-prefs__opposite {
	margin-top: var(--s-6, 2rem);
	padding-top: var(--s-5, 1.5rem);
	border-top: 1px solid var(--c-line, #dedcd6);
}

.omega-crm-prefs__secondary {
	min-height: var(--tap-min, 48px);
}

/* ------------------------------------------------------- the short sign-up
 *
 * The front page version: one address, one tick, one button. It sits inside
 * the theme's own section wrapper, so it sets no page-level spacing of its
 * own and only lays out what is inside it.
 *
 * The input and the button are a single row on a wide screen and stack on a
 * narrow one. The stacking point is set on the CONTENT, not on a device
 * width: below roughly 30rem an email field and a button cannot both be
 * usable side by side, whatever is holding them.
 */
.omega-crm-compact {
	/*
	 * The NARROW shape: one column, centred. Left-aligned at 34rem inside a
	 * band that runs the full width of the page, it read as a section that had
	 * failed to finish loading rather than as a deliberate one. Centring fixed
	 * that on a phone and merely moved it on a desktop, where two thirds of the
	 * band was still empty. The wide shape is at the bottom of this file.
	 */
	max-width: 34rem;
	margin-inline: auto;
}

/* Left, like the form under it: a centred title over left-aligned fields
   read as two things that did not belong together. */
.omega-crm-compact__intro {
	margin-bottom: var(--s-3, 0.75rem);
}

.omega-crm-compact__title {
	margin: 0 0 var(--s-2, 0.5rem);
	font-size: var(--t-lg, 1.375rem);
	line-height: 1.25;
}

/*
 * The fuller pitch, drawn always and shown only in the wide layout.
 *
 * Hidden rather than left out of the markup because the front page is measured
 * at 390px against a height gate it currently clears by about 119px, and three
 * lines of body copy is more than that entire budget. Nothing is lost on a
 * phone: the small print under the button makes the same promise in one line.
 */
.omega-crm-compact__pitch {
	display: none;
}

.omega-crm-compact__note {
	margin: 0;
	color: var(--c-ink-2, #3f5765);
	font-size: var(--t-sm, 1rem);
}

.omega-crm-compact__row {
	display: flex;
	flex-direction: column;
	gap: var(--s-2, 0.5rem);
	margin-bottom: var(--s-3, 0.75rem);
}

.omega-crm-compact__label {
	font-weight: 600;
}

/*
 * 56px, not 48px. This is a primary action on a site used in gloves, and the
 * field is half of it: a tap target that misses the input is the same failure
 * as one that misses the button.
 */
.omega-crm-compact__input {
	width: 100%;
	min-height: var(--tap-primary, 56px);
	padding: var(--s-2, 0.5rem) var(--s-3, 0.75rem);
	border: 1px solid var(--c-line, #dedcd6);
	border-radius: var(--radius, 10px);
	background: var(--c-surface, #fff);
	color: inherit;
	font: inherit;
}

.omega-crm-compact__input:focus-visible {
	outline: var(--focus-ring, 3px solid #142a42);
	outline-offset: 2px;
}

.omega-crm-compact__input[aria-invalid="true"] {
	border-color: var(--c-danger, #a11);
}

/*
 * The whole label is the target, not just the 16px box, which is the
 * difference between a tick a gloved thumb can hit and one it cannot.
 */
.omega-crm-compact__tick {
	display: flex;
	align-items: flex-start;
	gap: var(--s-3, 0.75rem);
	min-height: var(--tap-min, 48px);
	padding: var(--s-3, 0.75rem) 0;
	font-size: var(--t-sm, 0.9375rem);
	line-height: 1.45;
	cursor: pointer;
}

.omega-crm-compact__tick input {
	flex: 0 0 auto;
	width: 1.5rem;
	height: 1.5rem;
	margin-top: 0.125rem;
}

/*
 * NO RESERVED BOX ANY MORE (2026-10-15). It held 65px open for Cloudflare's
 * iframe, which made sense when the challenge always drew. It is now
 * interaction-only and lazy (the theme's turnstile.js): for almost everybody
 * nothing is ever drawn, so the reservation was just a hole in the form that
 * the owner called out. If a visitor is challenged, the box appears then, as
 * a response to what they did - not as a jump on page load.
 */
.omega-crm-compact__challenge {
	min-height: 0;
	margin: 0;
}

.omega-crm-compact__challenge:has(iframe) {
	margin: var(--s-3, 0.75rem) 0;
}

.omega-crm-compact__submit {
	min-height: var(--tap-primary, 56px);
	width: 100%;
}



.omega-crm-compact__small {
	margin: var(--s-3, 0.75rem) 0 0;
	color: var(--c-ink-2, #3f5765);
	font-size: var(--t-xs, 0.875rem);
}

/*
 * No left border. The rest of this project uses a tinted panel and a heavier
 * top rule to mark a message, because a left border reads as a quote and
 * disappears entirely when the text direction flips.
 */
.omega-crm-compact__error {
	margin-bottom: var(--s-3, 0.75rem);
	padding: var(--s-3, 0.75rem);
	border-radius: var(--radius, 10px);
	background: var(--c-danger-tint, #fdf0f0);
	color: var(--c-danger, #a11);
}

.omega-crm-compact__error p {
	margin: 0;
}

.omega-crm-compact__error p + p {
	margin-top: var(--s-2, 0.5rem);
}

.omega-crm-compact__done {
	padding: var(--s-4, 1.25rem);
	border-radius: var(--radius, 10px);
	background: var(--c-success-tint, #eef7ee);
}

.omega-crm-compact__done .omega-crm-compact__title {
	font-size: var(--t-md, 1.125rem);
}

/* --------------------------------------------- the short sign-up, laid wide
 *
 * Two columns: the pitch on the left, the form on the right, centred against
 * each other so the band reads as one composed thing rather than a heading
 * with a form parked under it.
 *
 * THE BREAKPOINT IS THE CONTENT'S, NOT A DEVICE'S. The form column stops being
 * comfortable below about 30rem, the heading and its supporting line break
 * into a stack of single words below about 22rem, and the gap between the two
 * is 3rem. That is 55rem of content, or 58rem of viewport once the theme's
 * container has taken its 3rem of padding. 60rem, so the split happens with a
 * little slack instead of exactly at the width where it fails.
 *
 * Everything above this block is the narrow shape and must stay untouched by
 * it. The front page is measured at 390px against an 8,300px height gate with
 * roughly 119px of headroom, so a rule that leaked below 60rem would be found
 * by test-nav.mjs and test-home-close.mjs rather than by eye.
 */
@media (min-width: 60rem) {
	.omega-crm-compact {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(26rem, 34rem);
		align-items: center;
		gap: var(--s-7, 3rem);
		/*
		 * 74rem, not the container's full 1,552px. Two columns pushed to the
		 * far edges of a band that wide stop being read together, which is the
		 * same fault as the empty band arriving from the other direction.
		 */
		max-width: 74rem;
	}

	.omega-crm-compact__intro {
		margin-bottom: 0;
		text-align: left;
	}

	/*
	 * Scoped to the intro so the thank-you keeps its own quieter title size.
	 */
	.omega-crm-compact__intro .omega-crm-compact__title {
		font-size: var(--t-xl, 1.625rem);
		max-width: 18ch;
		text-wrap: balance;
	}

	.omega-crm-compact__pitch {
		display: block;
		margin: 0;
		max-width: 44ch;
		color: var(--c-ink-2, #3f5765);
		font-size: var(--t-base, 1rem);
		text-wrap: pretty;
	}

	/*
	 * The form becomes a card on the tinted band. Without it the right column
	 * is a stack of controls floating on the same colour as the copy beside
	 * them, and the eye has nothing telling it where the form starts.
	 *
	 * Every token here is one the theme really defines. That was not true when
	 * this file was written: --r-2, --c-paper, --c-focus and --c-error appear in
	 * no stylesheet on this site, so each one silently resolved to the literal
	 * fallback beside it. The page looked right, which is why nobody noticed, and
	 * a change to a brand colour or a corner radius would simply not have reached
	 * any of them.
	 */
	/*
	 * ONE ROW FOR THE ACTION (2026-10-15). Field and button side by side,
	 * the tick and the small print under them: the panel was five stacked
	 * rows and twice the height its content needed. Placed by grid area
	 * rather than reordered in the markup, so the reading and tab order stay
	 * email, tick, button.
	 */
	.omega-crm-compact__form {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		column-gap: var(--s-3, 0.75rem);
	}

	.omega-crm-compact__form > * {
		grid-column: 1 / -1;
	}

	.omega-crm-compact__row {
		grid-column: 1;
		grid-row: 1;
		margin-bottom: 0;
	}

	.omega-crm-compact__submit {
		grid-column: 2;
		grid-row: 1;
		align-self: end;
		min-width: 0;
	}

	.omega-crm-compact__tick {
		margin-top: var(--s-2, 0.5rem);
		padding-bottom: 0;
	}

	.omega-crm-compact__small {
		margin-top: var(--s-2, 0.5rem);
	}

	/*
	 * No card (2026-10-15). The white panel added 50px of padding and a
	 * border round a form that is one field and a button; on the tinted band
	 * the white field already says where the form is.
	 */
	.omega-crm-compact__panel {
		padding: 0;
	}

	/*
	 * After a successful sign-up the thank-you is the only child, and left in
	 * the first track it sits against an empty half of the band. That is the
	 * exact fault this layout was written to fix, reappearing at the one moment
	 * somebody has just done what we asked. It spans both tracks instead.
	 */
	.omega-crm-compact__done {
		grid-column: 1 / -1;
		max-width: 44rem;
		margin-inline: auto;
	}
}

/*
 * 56px on every field of the sign-up, at every width.
 *
 * The theme's .enquiry__input is 48px, which clears this project's tap-target
 * floor and is the right size for the contact form. It is the wrong size here
 * for two reasons: the short version of this same form on the front page uses
 * 56px, so the two sign-ups disagreed about how big a field is; and this is the
 * form most likely to be filled in on site, on a phone, in gloves, where the
 * difference between 48 and 56 is the difference between one tap and three.
 *
 * Scoped to .omega-crm-signup, so the contact and quote forms keep the size
 * they were designed with.
 */
.omega-crm-signup .enquiry__input {
	min-height: var(--tap-primary, 56px);
}

/* ------------------------------------------------ the full form, on a wide screen
 *
 * THE PROBLEM. The theme caps .enquiry at 34rem, which is exactly right for the
 * three-field contact form it was written for and wrong for this one. The
 * sign-up asks nine questions and draws two checkbox grids, and at 1280px it
 * rendered as a 544px ribbon inside a 765px document column: a third of the
 * measure empty, the trades stacked two across when six would fit, and a form
 * twice as tall as it needed to be.
 *
 * THE FIX IS THE DOCUMENT'S OWN COLUMN, NOT THE FULL PAGE. The form fills the
 * measure the prose above it already uses, so the heading, the paragraph and
 * the first field all begin on the same line. Breaking out to the 1184px
 * container would take negative margins and would fight the table-of-contents
 * layout on any document long enough to have one.
 *
 * 48rem, and the number comes from the content rather than from a device: two
 * text fields side by side each need about 20rem to hold a label, a long email
 * address and an error message without wrapping, plus the gap between them and
 * the page's own padding.
 */
@media (min-width: 48rem) {

	/* Both class names, because the theme's .enquiry cap has equal specificity. */
	.omega-crm-signup.enquiry {
		max-width: 100%;
	}

	/*
	 * The fields become a two-track grid. Everything spans both tracks by
	 * default and only the four short, paired questions opt out, so a field
	 * added later is full width and readable rather than silently half width
	 * next to something it has nothing to do with.
	 */
	.omega-crm-signup .enquiry__form {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: var(--s-4, 1.25rem);
	}

	/*
	 * The two inputs in a pair have to sit on the same line, and they did not.
	 * Email carries a two-line hint and phone a one-line hint, so with each row
	 * sized to its own content the boxes landed about 20px apart and the pair
	 * read as two unrelated questions that happened to be near each other.
	 *
	 * Stretching the row to the height of its neighbour and pushing the input to
	 * the bottom of it lines them up whatever the hints say, including after
	 * somebody rewrites one. A fixed height on the hint would look identical
	 * today and break the first time the copy changed.
	 */
	.omega-crm-signup .enquiry__row {
		display: flex;
		flex-direction: column;
	}

	.omega-crm-signup .enquiry__row .enquiry__input {
		margin-top: auto;
	}

	.omega-crm-signup .enquiry__form > * {
		grid-column: 1 / -1;
	}

	/*
	 * A name is two halves of one answer, and so is "how do we reach you".
	 * Matched on the input each row contains rather than on its position, so
	 * reordering the form in register() cannot quietly pair the wrong two.
	 */
	.omega-crm-signup .enquiry__row:has( input[name="omega[first_name]"] ),
	.omega-crm-signup .enquiry__row:has( input[name="omega[last_name]"] ),
	.omega-crm-signup .enquiry__row:has( input[name="omega[email]"] ),
	.omega-crm-signup .enquiry__row:has( input[name="omega[phone]"] ) {
		grid-column: auto;
	}

	/*
	 * The theme stacks rows with a top margin on the second and later ones. In
	 * a grid that margin is added to the gap, so the left column of each pair
	 * sits higher than the right one by exactly one --s-4 and the labels stop
	 * lining up.
	 */
	.omega-crm-signup .enquiry__row + .enquiry__row {
		margin-top: 0;
	}

	/*
	 * Belt and braces. Browsers do not render a hidden input, but a stray one
	 * that ever became a grid item would open an empty cell and shunt the
	 * following field into the wrong column, which is a hard fault to see and
	 * an easy one to prevent.
	 */
	.omega-crm-signup .enquiry__form > input[type="hidden"] {
		display: none;
	}

	/* The submit is a primary action, not a field, so it keeps its own size. */
	.omega-crm-signup .enquiry__submit {
		justify-self: start;
		min-width: 16rem;
	}
}
