/* ==========================================================================
   BYB Global — components.css
   Cross-page primitives that must behave identically everywhere. Loaded after
   tokens.css and before base.css / page CSS.

   Deliberately small. The approved page stylesheets are the visual source of
   truth (project constitution, golden rule 2), so this file does NOT re-implement their
   cards, grids or heroes — extracting those would risk visual drift for no
   functional gain. Shared components are adopted page-by-page as each page is
   rebuilt in its own phase.
   ========================================================================== */

/* ==========================================================================
   BUTTONS — the two the whole site uses
   ==========================================================================
   There are exactly two: PRIMARY (gold, fills and sweeps a highlight across)
   and SECONDARY (white with a gold edge, fills gold and slides an arrow in).
   Both are the header's buttons, promoted here so every page uses the same
   pair — "Contact Us" became the primary, "Book a Consultation" the secondary
   (client instruction, 2026-09-16).

   Each page used to carry its own button styles (.rk-btn, .byb2-btn, .svc-btn,
   .ct-btn, .ab-btn, .faq-btn, .dc-btn) with slightly different sizes, casing
   and hovers. Those blocks are gone from the page stylesheets; the class names
   stay so no template markup had to change, and are mapped onto the two
   variants below. A NEW button should use .byb-btn + .byb-btn--primary or
   --secondary; the prefixed names exist only to keep the approved templates
   working.

   The hover animation works with or without inner markup. The header wraps its
   text in .byb-btn__label and its arrow in .byb-btn__arrow; every other button
   is a plain <a>, and gets the same movement from a generated arrow plus a
   padding shift that slides the label left without changing the button's width.
   ========================================================================== */

.byb-btn,
.rk-btn,
.byb2-btn,
.svc-btn,
.ct-btn,
.ab-btn,
.faq-btn,
.dc-btn {
	position:relative;
	overflow:hidden;
	isolation:isolate;
	display:inline-flex;
	align-items:center;
	justify-content:center;
	white-space:nowrap;
	text-align:center;
	text-decoration:none;
	cursor:pointer;
	font-family:var(--sans);
	font-size:14px;
	font-weight:500;
	letter-spacing:0.02em;
	text-transform:none;
	line-height:1.2;
	padding:13px 32px;
	border:1px solid transparent;
	border-radius:var(--btn-radius);
	transition:
		background .25s ease,
		color .25s ease,
		border-color .25s ease,
		transform .25s cubic-bezier(.4,0,.2,1),
		box-shadow .25s ease,
		padding .3s cubic-bezier(.4,0,.2,1);
}

.byb-btn:active,
.rk-btn:active,
.byb2-btn:active,
.svc-btn:active,
.ct-btn:active,
.ab-btn:active,
.faq-btn:active,
.dc-btn:active { transform:translateY(0); box-shadow:none; }

/* The label sits above the primary's shine and the secondary's fill. */
.byb-btn__label { position:relative; z-index:2; display:inline-block; transition:transform .3s cubic-bezier(.4,0,.2,1); }

/* ---------- PRIMARY — gold, with a highlight sweeping across on hover -----
   Was the header's "Contact Us". */
.byb-btn--primary, .byb-btn--solid,
.rk-btn--gold,
.byb2-btn--primary, .byb2-btn--white,
.svc-btn,
.ct-btn,
.ab-btn--gold,
.faq-btn--gold,
.dc-btn--gold {
	background:var(--gold);
	color:#fff !important;
	border-color:var(--gold);
	box-shadow:0 8px 18px -12px rgba(183,162,106,0.85);
}

.byb-btn--primary::after, .byb-btn--solid::after,
.rk-btn--gold::after,
.byb2-btn--primary::after, .byb2-btn--white::after,
.svc-btn::after,
.ct-btn::after,
.ab-btn--gold::after,
.faq-btn--gold::after,
.dc-btn--gold::after {
	content:"";
	/* z-index:-1 inside the button's own stacking context: the shine passes
	   over the gold ground but behind the label, so the text never washes
	   out — true whether or not the label is wrapped in a span. */
	position:absolute; top:0; left:-130%; z-index:-1;
	width:65%; height:100%;
	background:linear-gradient(120deg, transparent 0%, rgba(255,255,255,0.5) 50%, transparent 100%);
	transform:skewX(-20deg);
	transition:left .6s ease;
}

.byb-btn--primary:hover, .byb-btn--solid:hover,
.rk-btn--gold:hover,
.byb2-btn--primary:hover, .byb2-btn--white:hover,
.svc-btn:hover,
.ct-btn:hover,
.ab-btn--gold:hover,
.faq-btn--gold:hover,
.dc-btn--gold:hover {
	background:var(--gold-dark);
	border-color:var(--gold-dark);
	color:#fff !important;
	transform:translateY(-2px);
	box-shadow:0 14px 28px -12px rgba(162,144,97,0.9);
}

.byb-btn--primary:hover::after, .byb-btn--solid:hover::after,
.rk-btn--gold:hover::after,
.byb2-btn--primary:hover::after, .byb2-btn--white:hover::after,
.svc-btn:hover::after,
.ct-btn:hover::after,
.ab-btn--gold:hover::after,
.faq-btn--gold:hover::after,
.dc-btn--gold:hover::after { left:130%; }

/* ---------- SECONDARY — white with a gold edge; fills gold, arrow slides in
   Was the header's "Book a Consultation". It keeps a solid white ground on
   dark sections too, so the pair reads the same everywhere. */
.byb-btn--secondary, .byb-btn--outline,
.rk-btn--outline, .rk-btn--dark,
.byb2-btn--outline, .byb2-btn--outline-white, .byb2-btn--outline-dark, .byb2-btn--dark,
.ab-btn--outline-dark,
.faq-btn--outline {
	background:#fff;
	color:var(--gold-dark) !important;
	border-color:var(--gold);
}

.byb-btn--secondary:hover, .byb-btn--outline:hover,
.rk-btn--outline:hover, .rk-btn--dark:hover,
.byb2-btn--outline:hover, .byb2-btn--outline-white:hover, .byb2-btn--outline-dark:hover, .byb2-btn--dark:hover,
.ab-btn--outline-dark:hover,
.faq-btn--outline:hover {
	background:var(--gold);
	color:#fff !important;
	border-color:var(--gold);
	transform:translateY(-2px);
	box-shadow:0 12px 24px -12px rgba(183,162,106,0.7);
}

/* Header form: an explicit arrow element next to a .byb-btn__label. */
.byb-btn--secondary .byb-btn__arrow,
.byb-btn--outline .byb-btn__arrow {
	position:absolute; right:18px; top:50%; z-index:2;
	display:inline-flex; color:#fff;
	transform:translate(8px,-50%); opacity:0;
	transition:transform .3s cubic-bezier(.4,0,.2,1), opacity .3s ease;
}
.byb-btn--secondary:hover .byb-btn__label,
.byb-btn--outline:hover .byb-btn__label { transform:translateX(-8px); }
.byb-btn--secondary:hover .byb-btn__arrow,
.byb-btn--outline:hover .byb-btn__arrow { opacity:1; transform:translate(0,-50%); }

/* Plain form: no inner markup, so the arrow is generated and the label is
   moved by shifting the padding — left padding shrinks by exactly what the
   right gains, so the button never changes width or nudges its neighbours. */
.byb-btn--secondary:not(:has(.byb-btn__arrow))::after,
.byb-btn--outline:not(:has(.byb-btn__arrow))::after,
.rk-btn--outline::after, .rk-btn--dark::after,
.byb2-btn--outline::after, .byb2-btn--outline-white::after, .byb2-btn--outline-dark::after, .byb2-btn--dark::after,
.ab-btn--outline-dark::after,
.faq-btn--outline::after {
	content:"\2192";
	position:absolute; right:18px; top:50%; z-index:2;
	color:#fff; line-height:1;
	transform:translate(8px,-50%); opacity:0;
	transition:transform .3s cubic-bezier(.4,0,.2,1), opacity .3s ease;
}
.byb-btn--secondary:not(:has(.byb-btn__arrow)):hover,
.byb-btn--outline:not(:has(.byb-btn__arrow)):hover,
.rk-btn--outline:hover, .rk-btn--dark:hover,
.byb2-btn--outline:hover, .byb2-btn--outline-white:hover, .byb2-btn--outline-dark:hover, .byb2-btn--dark:hover,
.ab-btn--outline-dark:hover,
.faq-btn--outline:hover { padding-right:46px; padding-left:18px; }

.byb-btn--secondary:not(:has(.byb-btn__arrow)):hover::after,
.byb-btn--outline:not(:has(.byb-btn__arrow)):hover::after,
.rk-btn--outline:hover::after, .rk-btn--dark:hover::after,
.byb2-btn--outline:hover::after, .byb2-btn--outline-white:hover::after, .byb2-btn--outline-dark:hover::after, .byb2-btn--dark:hover::after,
.ab-btn--outline-dark:hover::after,
.faq-btn--outline:hover::after { opacity:1; transform:translate(0,-50%); }

/* ---------- Size + width modifiers ---------- */
.byb-btn--sm, .rk-btn--sm { padding:10px 22px; font-size:13px; }
.byb-btn--sm:hover, .rk-btn--sm:hover { padding-right:38px; padding-left:14px; }
.byb-btn--block, .rk-btn--block { width:100%; }

/* Chips are not buttons — they only borrow the radius. */
.byb2-chip,
.ab-chip,
.byb-fab__toggle { border-radius:var(--btn-radius); }

/* ---------- Form controls ------------------------------------------------
   Text controls are curved to match the buttons they sit next to. Checkboxes
   and radios are deliberately excluded — they keep their native shape. */
input[type="text"], input[type="email"], input[type="tel"], input[type="url"],
input[type="search"], input[type="number"], input[type="date"], input[type="password"],
textarea, select {
	border-radius:var(--input-radius);
}

/* ---------- Focus visibility (a11y baseline) -----------------------------
   Keyboard users get a clear gold focus ring on every interactive element.
   :focus-visible only, so mouse clicks are unaffected and no approved page
   changes appearance for a pointer user. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
	outline:2px solid var(--gold);
	outline-offset:3px;
}

/* ---------- Visually-hidden utility (a11y) -------------------------------
   For a heading a section needs for correct outline/landmark structure but
   that the approved visual design doesn't show. */
.byb-vh {
	position:absolute !important;
	width:1px; height:1px;
	overflow:hidden;
	clip:rect(0 0 0 0);
	white-space:nowrap;
}

/* ---------- Form primitives (shared by Contact + Services enquiry forms) --
   Visible small labels (not placeholder-only — placeholders vanish while
   typing and fail WCAG), a honeypot that's invisible to people but present in
   the DOM for bots, and a status banner the handler's redirect populates. */
.byb-field-label {
	display:block;
	font-family:var(--sans);
	font-size:11px;
	letter-spacing:.06em;
	text-transform:uppercase;
	color:var(--muted, #6b6b6b);
	margin-bottom:4px;
}
.byb-field-label .byb-field-optional {
	text-transform:none;
	letter-spacing:0;
	opacity:.7;
}
.byb-field {
	margin-bottom:14px;
	text-align:left;
}
.byb-consent {
	display:flex;
	align-items:flex-start;
	gap:8px;
	font-size:13px;
	line-height:1.5;
	text-align:left;
}
.byb-consent input {
	margin-top:3px;
	flex:none;
	/* Explicit box so a page-level `.<prefix>-form input { width:100% }` rule
	   can never stretch the checkbox across the row again. */
	width:16px;
	height:16px;
	padding:0;
	accent-color:var(--gold);
}
/* The label text is the flex item that must absorb the remaining width. Without
   this it keeps its default `flex-shrink:1` with an auto basis and, inside a
   centred column, collapses to roughly one word per line beside the checkbox
   (seen on the Services enquiry form). Affects the Contact form too — both
   share this component. */
.byb-consent > span {
	flex:1 1 auto;
	min-width:0;
}
.byb-hp {
	position:absolute !important;
	width:1px; height:1px;
	overflow:hidden;
	clip:rect(0 0 0 0);
	white-space:nowrap;
}
.byb-form-status {
	font-family:var(--sans);
	font-size:14px;
	padding:12px 16px;
	margin-bottom:16px;
	border-radius:var(--input-radius, 4px);
}
.byb-form-status--ok {
	background:rgba(90,140,90,0.12);
	border:1px solid rgba(90,140,90,0.35);
	color:#2f5c33;
}
.byb-form-status--error {
	background:rgba(180,70,70,0.10);
	border:1px solid rgba(180,70,70,0.35);
	color:#8a2f2f;
}

/* ---------- Contact Form 7 (Contact, Services, Booking; inc/byb-cf7.php) --
   CF7's own stylesheet is switched off; the forms reuse the field styles
   above and each page's `.<prefix>-form` rules. These cover only the markup
   CF7 adds: field wrappers, the consent checkbox, validation tips and the
   response message (styled as .byb-form-status). */
.wpcf7 .screen-reader-response {
	position:absolute !important;
	width:1px; height:1px;
	overflow:hidden;
	clip:rect(0 0 0 0);
	white-space:nowrap;
}
.wpcf7 .hidden-fields-container,
.wpcf7 form > fieldset { display:none; } /* CF7 hidden inputs; the forms have no fieldsets of their own */
.wpcf7-form-control-wrap { display:block; position:relative; }
.wpcf7 .byb-consent .wpcf7-form-control-wrap,
.wpcf7 .byb-consent .wpcf7-list-item { display:block; margin:0; }
.wpcf7 .byb-consent label { display:flex; align-items:flex-start; gap:8px; }
.wpcf7 .byb-consent .wpcf7-list-item-label { flex:1 1 auto; min-width:0; }
.wpcf7-not-valid-tip {
	display:block;
	margin-top:4px;
	font-family:var(--sans);
	font-size:12px;
	color:#8a2f2f;
}
.wpcf7 .wpcf7-not-valid:not([type="checkbox"]) { border-color:rgba(180,70,70,0.6) !important; }
.wpcf7 .wpcf7-response-output {
	font-family:var(--sans);
	font-size:14px;
	padding:12px 16px;
	margin:16px 0 0;
	border-radius:var(--input-radius, 4px);
	background:rgba(180,70,70,0.10);
	border:1px solid rgba(180,70,70,0.35);
	color:#8a2f2f;
}
.wpcf7 form.sent .wpcf7-response-output {
	background:rgba(90,140,90,0.12);
	border-color:rgba(90,140,90,0.35);
	color:#2f5c33;
}
.wpcf7 form.init .wpcf7-response-output,
.wpcf7 form.resetting .wpcf7-response-output,
.wpcf7 form.submitting .wpcf7-response-output { display:none; }
.wpcf7 form.submitting [type="submit"] { opacity:.6; pointer-events:none; }

/* ---------- Screen-reader-only text (WP core: pagination headings, etc.) --
   Site-wide, not scoped to one page's CSS (R09) — WP core prints
   .screen-reader-text on any template that uses core pagination/widgets. */
.screen-reader-text {
	position:absolute !important; width:1px; height:1px; overflow:hidden;
	clip:rect(0 0 0 0); white-space:nowrap;
}

/* ---------- Reduced motion (global honour) -------------------------------
   design.md §7: always honour prefers-reduced-motion. Page stylesheets repeat
   this for their own animations; this covers anything they miss. */
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration:.01ms !important;
		animation-iteration-count:1 !important;
		transition-duration:.01ms !important;
		scroll-behavior:auto !important;
	}
}

/* ---------- Entity-lifecycle diagram (shared: Services + Homepage + Service
   Detail) --------------------------------------------------------------
   Establish -> Operate -> Comply -> Change/Exit.

   Laid out as a GRID, not a wrapping flex row. The flex version sized each
   stage `flex:1 1 200px` and let the row wrap, which broke on any container
   narrower than ~870px: four stages plus three inline arrows overflowed and
   wrapped 3-then-1, orphaning the last stage under a full-width row and
   leaving a dangling arrow pointing at nothing. The service-detail page's
   900px container hits exactly that case. A viewport media query cannot fix
   it — the constraint is the CONTAINER width, not the screen width, and the
   same component sits in a 1200px container on Services and a 1240px one on
   the homepage where four-across is correct.

   `auto-fit` + `minmax(210px, 1fr)` lets the container itself decide: four
   across when there is room, a clean 2x2 when there is not, one column on
   narrow screens. No partial/ragged wrap is possible in any container. */
.byb-lifecycle {
	display:grid; grid-template-columns:repeat(auto-fit, minmax(210px, 1fr));
	gap:16px; align-items:stretch;
}
.byb-lifecycle__stage {
	position:relative;
	display:flex; flex-direction:column; gap:8px; padding:26px 24px;
	background:#fff; border:1px solid var(--hairline);
	text-decoration:none; color:inherit; transition:background .2s ease, border-color .2s ease;
}
.byb-lifecycle--dark .byb-lifecycle__stage { background:rgba(255,255,255,0.04); border-color:var(--line-dark); }
a.byb-lifecycle__stage:hover, a.byb-lifecycle__stage:focus-visible { background:var(--paper); border-color:var(--gold); cursor:pointer; }
.byb-lifecycle--dark a.byb-lifecycle__stage:hover, .byb-lifecycle--dark a.byb-lifecycle__stage:focus-visible { background:rgba(255,255,255,0.09); border-color:var(--gold-light); }
.byb-lifecycle__num { font-size:13px; color:var(--gold); letter-spacing:.08em; }
.byb-lifecycle__name { font-weight:600; font-size:20px; margin:0; color:var(--text); }
.byb-lifecycle--dark .byb-lifecycle__name { color:#fff; }
.byb-lifecycle__desc { font-size:13px; line-height:1.6; color:var(--muted); margin:0; }
.byb-lifecycle--dark .byb-lifecycle__desc { color:rgba(255,255,255,0.72); }

/* No inter-stage connector.
   The diagram previously drew arrows between stages. They were inline SVG
   elements and therefore real layout items: in any container too narrow for
   four across (the 900px service-detail page) they consumed track space,
   forced a 3-then-1 wrap, and left an arrow pointing at empty space. Drawing
   them as ::after in the grid gap moved the problem rather than solving it —
   knowing whether a stage ends a visual row requires the CONTAINER width, and
   a viewport media query cannot see that. The auto-fit grid already reads as
   a sequence (numbered 01-04, in order), so the arrows earned less than the
   breakage they caused and are gone. Revisit with container queries if the
   connector is genuinely wanted back. */

/* Any arrow element left in older cached markup must never affect layout. */
.byb-lifecycle__arrow { display:none; }

@media (max-width: 620px) {
	.byb-lifecycle { grid-template-columns:1fr; }
}

/* ---------- Hero scroll cue (shared: About, Services, FAQ, Contact, 404) ----
   Same cue the homepage, Service Detail and Resources heroes carry: a fading
   gold hairline over a pulsing chevron, anchored to the hero's bottom edge.
   The hero must be position:relative. */
.byb-hero-scroll { position:absolute; left:50%; bottom:24px; transform:translateX(-50%); z-index:3; display:flex; flex-direction:column; align-items:center; gap:10px; text-decoration:none; }
.byb-hero-scroll::before { content:""; width:1px; height:30px; background:linear-gradient(180deg, transparent, rgba(214,195,130,0.65)); }
.byb-hero-scroll span { display:block; width:10px; height:10px; border-right:1.5px solid var(--gold-light); border-bottom:1.5px solid var(--gold-light); transform:rotate(45deg); animation:byb-hero-scroll 1.9s ease-in-out infinite; }
@keyframes byb-hero-scroll { 0%,100% { transform:rotate(45deg) translate(-2px,-2px); opacity:.45; } 50% { transform:rotate(45deg) translate(2px,2px); opacity:1; } }
@media (prefers-reduced-motion: reduce) { .byb-hero-scroll span { animation:none; } }
