/*
Theme Name: Life Ring
Theme URI: https://lifering.co.nz
Author: Life Ring Web Services
Author URI: https://lifering.co.nz
Description: A native WordPress block theme for Life Ring Web Services. Every brand decision (colour, type, spacing) lives in theme.json, so the theme can be copied and re-skinned for a client build by editing that one file. Sections are registered patterns, so pages stay editable from the block editor without touching code.
Requires at least: 6.5
Tested up to: 7.0
Requires PHP: 7.4
Version: 1.2.2
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: lifering
Tags: full-site-editing, block-patterns, blog, business, one-column, accessibility-ready, custom-colors, custom-logo, wide-blocks
*/

/* -------------------------------------------------------------------------
   This file holds only mechanism CSS — behaviour that block supports cannot
   express (sticky header, the hero grid-paper texture, the FAQ +/- marker,
   Gravity Forms integration). Every colour, size and space below resolves to
   a theme.json preset variable, so re-skinning a fork means editing
   theme.json and nothing else.
   ---------------------------------------------------------------------- */

/* --- Accessibility ------------------------------------------------------ */

.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100000;
	padding: 12px 22px;
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font-weight: 600;
	text-decoration: none;
}

.skip-link:focus {
	left: 8px;
	top: 8px;
}

:where(a, button, input, textarea, select, summary, .wp-block-navigation-item__content):focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 3px;
}

/* Dark bands need the brighter logo orange for a visible focus ring. */
.has-contrast-background-color :where(a, button, input, textarea, summary):focus-visible {
	outline-color: var(--wp--preset--color--brand);
}

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

html {
	scroll-behavior: smooth;
}

/* Sticky header must not cover the target of an in-page anchor link. */
:target {
	scroll-margin-top: 96px;
}

/* --- Section stacking ---------------------------------------------------
   WordPress applies --wp--style--block-gap as margin-block-start between
   siblings at two levels, and both show the page background as a stripe
   between coloured bands, breaking the design's colour blocking:

     1. .wp-site-blocks — between header, main and footer.
     2. post-content    — between the stacked page sections.

   The shell (1) is always flush: vertical rhythm comes from each section's
   own padding, never from a gap between them. Inside the content (2) the gap
   is collapsed only where two full-width sections meet, so ordinary blocks
   the client inserts between sections still get their normal spacing.
   ---------------------------------------------------------------------- */

.wp-site-blocks > * + * {
	margin-block-start: 0;
}

.wp-block-post-content > .alignfull + .alignfull,
.block-editor-block-list__layout > .alignfull + .alignfull {
	margin-block-start: 0;
}

/* --- Header ------------------------------------------------------------- */

.lr-header {
	position: sticky;
	top: 0;
	z-index: 40;
	background: color-mix(in srgb, var(--wp--preset--color--base) 94%, transparent);
	border-bottom: 1px solid var(--wp--preset--color--line);
}

@supports (backdrop-filter: blur(6px)) {
	.lr-header {
		backdrop-filter: blur(6px);
	}
}

.lr-logo img {
	height: auto;
	max-height: 44px;
	width: auto;
}

/* Nav links sit in ink, not link-rust, until hovered. */
.lr-nav .wp-block-navigation-item__content {
	color: var(--wp--preset--color--contrast);
	font-weight: 500;
	text-decoration: none;
}

.lr-nav .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--primary);
	text-decoration: underline;
	text-underline-offset: 4px;
}

/* The phone number reads as a mono utility, not a nav item. */
.lr-phone a,
.lr-phone .wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	color: var(--wp--preset--color--ink-muted);
	letter-spacing: 0.02em;
}

/* --- Hero grid-paper texture -------------------------------------------- */

.lr-gridpaper {
	background-image:
		linear-gradient(var(--wp--preset--color--line) 1px, transparent 1px),
		linear-gradient(90deg, var(--wp--preset--color--line) 1px, transparent 1px);
	background-size: 64px 64px;
	background-position: center top;
}

/* --- Hairline card grids ------------------------------------------------
   The grid container carries the hairline colour and a 1px gap, so the gaps
   themselves draw the rules. Children just need their own background.
   ---------------------------------------------------------------------- */

.lr-hairline-grid {
	border: 1px solid var(--wp--preset--color--line);
	padding: 0;
}

.lr-hairline-grid.has-ink-line-background-color {
	border-color: var(--wp--preset--color--ink-line);
}

/* Cards lift slightly on hover where the design calls for it.
   !important is required throughout the hover states below: WordPress emits
   its preset utilities (.has-*-color, .has-*-background-color) with
   !important, so any hover override of a preset-coloured element loses
   without it. */
.lr-card {
	transition: background-color 120ms ease;
}

.lr-card:hover {
	background-color: var(--wp--custom--hover--card) !important;
}

/* --- Registered block styles -------------------------------------------- */

/* core/list — "Spec list" */
.wp-block-list.is-style-spec {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 9px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	line-height: 1.45;
	color: var(--wp--preset--color--ink-muted);
}

.has-contrast-background-color .wp-block-list.is-style-spec {
	color: var(--wp--preset--color--on-dark);
}

/* core/group — "Numbered step" */
.wp-block-group.is-style-step {
	border-top: 2px solid var(--wp--preset--color--contrast);
	padding-top: 22px;
}

/* --- Comparison table ---------------------------------------------------
   core/table with the registered "Comparison table" block style. Using a real
   table keeps it semantic and lets the client edit it like a spreadsheet.
   ---------------------------------------------------------------------- */

.wp-block-table.is-style-compare {
	margin: 0;
}

.wp-block-table.is-style-compare table {
	border-collapse: collapse;
	width: 100%;
	border-top: 1px solid var(--wp--preset--color--contrast);
}

.wp-block-table.is-style-compare thead {
	/* Core draws a 3px rule under the head. The design puts the single dark
	   rule on TOP of the whole block instead, with hairlines between rows. */
	border-bottom: 0;
}

.wp-block-table.is-style-compare :where(th, td) {
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--line);
	text-align: left;
	vertical-align: baseline;
}

.wp-block-table.is-style-compare thead th {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 400;
	letter-spacing: var(--wp--custom--letter-spacing--mono);
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-muted);
	padding: 20px 0;
}

.wp-block-table.is-style-compare thead th:last-child {
	color: var(--wp--preset--color--primary);
}

.wp-block-table.is-style-compare tbody td {
	padding: 22px 0;
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--ink-muted);
}

.wp-block-table.is-style-compare tbody td:first-child {
	font-weight: 600;
	color: var(--wp--preset--color--contrast);
	width: 210px;
}

.wp-block-table.is-style-compare tbody td:last-child {
	color: var(--wp--preset--color--contrast);
}

.wp-block-table.is-style-compare :where(th, td) + :where(th, td) {
	padding-left: clamp(14px, 2vw, 32px);
}

@media (max-width: 600px) {
	.wp-block-table.is-style-compare tbody td:first-child {
		width: auto;
	}
	.wp-block-table.is-style-compare thead {
	/* Core draws a 3px rule under the head. The design puts the single dark
	   rule on TOP of the whole block instead, with hairlines between rows. */
	border-bottom: 0;
}

.wp-block-table.is-style-compare :where(th, td) {
		font-size: var(--wp--preset--font-size--small);
	}
}

/* --- FAQ (core/details) ------------------------------------------------- */

.lr-faq .wp-block-details {
	border-bottom: 1px solid var(--wp--preset--color--line);
	padding: 24px 0;
}

.lr-faq .wp-block-details summary {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 24px;
	list-style: none;
	cursor: pointer;
	font-size: var(--wp--preset--font-size--card-title);
	font-weight: 600;
	letter-spacing: -0.01em;
}

.lr-faq .wp-block-details summary::-webkit-details-marker,
.lr-faq .wp-block-details summary::marker {
	display: none;
	content: "";
}

.lr-faq .wp-block-details summary::after {
	content: "+";
	font-family: var(--wp--preset--font-family--mono);
	font-size: 20px;
	line-height: 1;
	color: var(--wp--preset--color--primary);
	flex: none;
}

.lr-faq .wp-block-details[open] summary::after {
	content: "\2212"; /* minus */
}

.lr-faq .wp-block-details > *:not(summary) {
	margin-top: 14px;
	max-width: 70ch;
	color: var(--wp--preset--color--ink-soft);
	line-height: var(--wp--custom--line-height--relaxed);
}

/* --- Measure ------------------------------------------------------------
   The design constrains individual headings and paragraphs by character
   count rather than by column. Block supports have no max-width control, so
   these are exposed as utility classes — pick one in the block's Advanced >
   Additional CSS class field.
   ---------------------------------------------------------------------- */

:where(h1, h2, h3, h4) {
	text-wrap: balance;
}

:where(p) {
	text-wrap: pretty;
}

/* Slightly recede a label against a saturated band. */
.lr-dim {
	opacity: 0.72;
}

/* A text link that reads as a call to action without being a button. */
.lr-underline a {
	border-bottom: 2px solid var(--wp--preset--color--primary);
	padding-bottom: 4px;
	text-decoration: none;
}

.lr-underline a:hover {
	border-bottom-color: var(--wp--preset--color--primary-deep);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.lr-measure-13 { max-width: 13ch; }
.lr-measure-16 { max-width: 16ch; }
.lr-measure-18 { max-width: 18ch; }
.lr-measure-20 { max-width: 20ch; }
.lr-measure-22 { max-width: 22ch; }
.lr-measure-46 { max-width: 46ch; }
.lr-measure-52 { max-width: 52ch; }
.lr-measure-58 { max-width: 58ch; }
.lr-measure-60 { max-width: 60ch; }
.lr-measure-70 { max-width: 70ch; }

/* --- Media -------------------------------------------------------------- */

/* The hero portrait fills the column but must not dictate the hero's height —
   the design has it stretch to the copy, not the other way round. */
.lr-hero-media {
	height: 100%;
}

.lr-hero-media img {
	height: clamp(340px, 56vh, 600px);
}

.lr-media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* --- Buttons ------------------------------------------------------------
   Core's is-style-outline sets its own padding (0.667em) at a specificity
   that beats theme.json, so an outline button renders ~10px shorter than a
   filled one sitting next to it. Restore the theme.json rhythm on both, then
   add the design's hover states — the filled ones deepen, the outline ones
   fill in.
   ---------------------------------------------------------------------- */

.wp-block-buttons .wp-block-button.is-style-outline > .wp-block-button__link {
	padding-top: 1rem;
	padding-bottom: 1rem;
	padding-left: 1.75rem;
	padding-right: 1.75rem;
}

.wp-block-button__link {
	transition:
		background-color 120ms ease,
		border-color 120ms ease,
		color 120ms ease;
}

/* Outline buttons fill with ink on hover.
   The text colour needs !important: WordPress emits its preset colour
   utilities (.has-contrast-color) with !important, so a plain declaration
   here loses and the label stays ink-on-ink — invisible. */
.wp-block-buttons .wp-block-button.is-style-outline > .wp-block-button__link:hover,
.wp-block-buttons .wp-block-button.is-style-outline > .wp-block-button__link:focus-visible {
	background-color: var(--wp--preset--color--contrast);
	border-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base) !important;
}

/* The header CTA is already ink, so it fills rust instead. */
.lr-header .wp-block-button__link:hover,
.lr-header .wp-block-button__link:focus-visible {
	background-color: var(--wp--preset--color--primary) !important;
	border-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--base) !important;
}

/* On the rust band: the ink button deepens to true black, and the outline
   one veils rather than filling — an ink fill would fight the band. */
#audit .wp-block-button__link.has-contrast-background-color:hover,
#audit .wp-block-button__link.has-contrast-background-color:focus-visible {
	background-color: var(--wp--custom--hover--ink-deep) !important;
	border-color: var(--wp--custom--hover--ink-deep);
}

#audit .wp-block-button.is-style-outline > .wp-block-button__link:hover,
#audit .wp-block-button.is-style-outline > .wp-block-button__link:focus-visible {
	background-color: var(--wp--custom--hover--veil) !important;
	border-color: var(--wp--preset--color--shell);
	color: var(--wp--preset--color--shell) !important;
}

/* --- Gravity Forms -----------------------------------------------------
   GF 2.9 renders with the "Orbital" theme, which is driven by a documented
   CSS custom-property palette rather than by flat classes. Remapping those
   variables onto the theme.json presets is the upgrade-safe way to restyle
   it — GF can change its markup without breaking this. The explicit rules
   underneath only cover typography and the few things the palette does not
   reach.
   ---------------------------------------------------------------------- */

.lr-form .gform_wrapper.gform-theme,
.lr-form .gform_wrapper.gform-theme--orbital {
	/* Accent — buttons, active states. */
	--gf-color-primary: var(--wp--preset--color--primary);
	--gf-color-primary-rgb: 184, 65, 14;
	--gf-color-primary-contrast: var(--wp--preset--color--shell);
	--gf-color-primary-contrast-rgb: 255, 246, 241;
	--gf-color-primary-darker: var(--wp--preset--color--primary-deep);
	--gf-color-primary-lighter: var(--wp--preset--color--brand);

	/* Inside controls — input wells. */
	--gf-color-in-ctrl: var(--wp--preset--color--ink-raised);
	--gf-color-in-ctrl-rgb: 27, 25, 23;
	--gf-color-in-ctrl-contrast: var(--wp--preset--color--base);
	--gf-color-in-ctrl-contrast-rgb: 247, 245, 242;
	--gf-color-in-ctrl-darker: var(--wp--preset--color--contrast);
	--gf-color-in-ctrl-lighter: var(--wp--preset--color--ink-raised);
	--gf-color-in-ctrl-light: var(--wp--preset--color--ink-line);
	--gf-color-in-ctrl-light-darker: var(--wp--preset--color--ink-line);
	--gf-color-in-ctrl-light-lighter: var(--wp--preset--color--ink-line);
	--gf-color-in-ctrl-dark: var(--wp--preset--color--on-dark-mute);
	--gf-color-in-ctrl-dark-darker: var(--wp--preset--color--on-dark);
	--gf-color-in-ctrl-dark-lighter: var(--wp--preset--color--on-dark-mute);
	--gf-color-in-ctrl-primary: var(--wp--preset--color--brand);
	--gf-color-in-ctrl-primary-contrast: var(--wp--preset--color--shell);
	--gf-color-in-ctrl-primary-darker: var(--wp--preset--color--primary-deep);

	/* Outside controls — labels, descriptions, rules. */
	--gf-color-out-ctrl: var(--wp--preset--color--contrast);
	--gf-color-out-ctrl-contrast: var(--wp--preset--color--base);
	--gf-color-out-ctrl-dark: var(--wp--preset--color--on-dark-mute);
	--gf-color-out-ctrl-dark-darker: var(--wp--preset--color--base);
	--gf-color-out-ctrl-dark-lighter: var(--wp--preset--color--on-dark-mute);
	--gf-color-out-ctrl-light: var(--wp--preset--color--ink-line);
	--gf-color-out-ctrl-light-darker: var(--wp--preset--color--ink-line);
	--gf-color-out-ctrl-light-lighter: var(--wp--preset--color--ink-line);

	/* Validation reads in the logo orange, which clears AA on the dark band. */
	--gf-color-danger: var(--wp--preset--color--brand);
	--gf-color-danger-contrast: var(--wp--preset--color--contrast);
	--gf-color-danger-darker: var(--wp--preset--color--primary-deep);
	--gf-color-danger-lighter: var(--wp--preset--color--brand);

	/* Button controls read from their own --gf-ctrl-btn-* family. */
	--gf-ctrl-btn-bg-color-primary: var(--wp--preset--color--primary);
	--gf-ctrl-btn-bg-color-hover-primary: var(--wp--preset--color--brand);
	--gf-ctrl-btn-bg-color-focus-primary: var(--wp--preset--color--brand);
	--gf-ctrl-btn-color-primary: var(--wp--preset--color--shell);
	--gf-ctrl-btn-border-color-primary: var(--wp--preset--color--primary);
	--gf-ctrl-btn-border-color-hover-primary: var(--wp--preset--color--brand);

	/* Square corners, matching every other control in the design. */
	--gf-ctrl-radius: 0;
	--gf-ctrl-btn-radius: 0;
	--gf-ctrl-checkbox-radius: 0;
	--gf-field-gap-y: 1.125rem;
	--gf-field-gap-x: 1.125rem;
	--gf-form-gap-y: 1.125rem;
}

/* Labels take the mono eyebrow treatment used everywhere else. */
.lr-form .gform_wrapper .gfield_label,
.lr-form .gform_wrapper .gform-field-label {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 400;
	letter-spacing: var(--wp--custom--letter-spacing--mono);
	text-transform: uppercase;
	color: var(--wp--preset--color--on-dark-mute);
	margin-bottom: 0.5rem;
}

.lr-form .gform_wrapper .gfield_required {
	color: var(--wp--preset--color--brand);
	font-family: var(--wp--preset--font-family--mono);
	letter-spacing: 0;
}

.lr-form .gform_wrapper.gform-theme--orbital :where(input, textarea, select) {
	background-color: var(--wp--preset--color--ink-raised);
	border: 1px solid var(--wp--preset--color--ink-line);
	border-radius: 0;
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--medium);
	padding: 0.875rem;
}

.lr-form .gform_wrapper.gform-theme--orbital :where(input, textarea)::placeholder {
	color: var(--wp--preset--color--on-dark-mute);
	opacity: 1;
}

.lr-form .gform_wrapper.gform-theme--orbital :where(input, textarea, select):focus {
	border-color: var(--wp--preset--color--brand);
	outline: 2px solid var(--wp--preset--color--brand);
	outline-offset: 1px;
	box-shadow: none;
}

.lr-form .gform_wrapper.gform-theme--orbital textarea {
	min-height: 7.5rem;
	resize: vertical;
}

.lr-form .gform_wrapper.gform-theme--orbital .gform_footer :where(input, button).gform_button,
.lr-form .gform_wrapper.gform-theme--orbital input[type="submit"].gform_button,
.lr-form .gform_wrapper.gform-theme--orbital button.gform_button {
	--gf-local-bg-color: var(--wp--preset--color--primary);
	--gf-local-color: var(--wp--preset--color--shell);
	--gf-local-border-color: var(--wp--preset--color--primary);
	background-color: var(--wp--preset--color--primary);
	border: 1px solid var(--wp--preset--color--primary);
	border-radius: 0;
	color: var(--wp--preset--color--shell);
	cursor: pointer;
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 600;
	padding: 1.0625rem 1.75rem;
	width: 100%;
	transition: background-color 120ms ease, border-color 120ms ease;
}

.lr-form .gform_wrapper.gform-theme--orbital .gform_footer :where(input, button).gform_button:hover,
.lr-form .gform_wrapper.gform-theme--orbital input[type="submit"].gform_button:hover,
.lr-form .gform_wrapper.gform-theme--orbital button.gform_button:hover,
.lr-form .gform_wrapper.gform-theme--orbital input[type="submit"].gform_button:focus,
.lr-form .gform_wrapper.gform-theme--orbital button.gform_button:focus {
	--gf-local-bg-color: var(--wp--preset--color--brand);
	--gf-local-border-color: var(--wp--preset--color--brand);
	background-color: var(--wp--preset--color--brand);
	border-color: var(--wp--preset--color--brand);
}

.lr-form .gform_wrapper.gform-theme--orbital .gform_footer {
	display: block;
	padding: 0;
	margin: 0.25rem 0 0;
}

/* Orbital nests the submit inside a shrink-to-fit wrapper, so the wrapper has
   to be stretched before width:100% on the button means anything. */
.lr-form .gform_wrapper.gform-theme--orbital .gform_footer > * {
	display: block;
	width: 100%;
	max-width: none;
}

.lr-form .gform_wrapper.gform-theme--orbital .gform_footer :where(input, button).gform_button {
	width: 100%;
	max-width: none;
	justify-content: center;
	text-align: center;
}

.lr-form .gform_wrapper .gform_validation_errors {
	background: var(--wp--preset--color--ink-raised);
	border: 1px solid var(--wp--preset--color--brand);
	border-radius: 0;
	box-shadow: none;
}

.lr-form .gform_wrapper .gform_validation_errors > h2,
.lr-form .gform_wrapper .validation_message {
	color: var(--wp--preset--color--brand);
	font-size: var(--wp--preset--font-size--small);
}

.lr-form .gform_confirmation_message {
	color: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--x-large);
	line-height: var(--wp--custom--line-height--body);
	border-left: 3px solid var(--wp--preset--color--brand);
	padding-left: var(--wp--preset--spacing--50);
}

/* --- Print -------------------------------------------------------------- */

@media print {
	.lr-header,
	.lr-form,
	.wp-block-navigation {
		display: none !important;
	}
}
