/* Tokens — base palette transcribed from the design book (reference/design-book/
   AX Online - Homepage v2.dc.html); neutral backbone (bg/surface-2/line/line-strong)
   reworked 2026-09 around three brand anchors: Primary Base #513BB7 (Deep Indigo,
   already --ax-accent, unchanged), Muted Highlight #D9C3B0 (Warm Champagne, now
   --ax-surface-2), Soft Contrast #FDFBF7 (Alabaster Cream, now --ax-bg). Dark-mode
   line/surface-2 values are derived, same-hue-family dark counterparts (not real
   anchors — champagne/cream have no dark equivalent to source directly). */
:root {
	--ax-bg: #fdfbf7;
	--ax-surface: #ffffff;
	--ax-surface-2: #d9c3b0;
	--ax-ink: #1c1a19;
	--ax-ink-2: #403d38;
	--ax-ink-3: #474038;
	--ax-line: #e8dcc9;
	--ax-line-strong: #c9ad8f;
	--ax-accent: #513bb7;
	--ax-accent-text: #3f2d93;
	--ax-accent-soft: #ece8fa;
	--ax-on-accent: #ffffff;
	--ax-on-accent-2: #f8f5ff;
	--ax-shadow: 0 1px 2px rgba(28, 26, 25, 0.06);
}

[data-theme='dark'] {
	--ax-bg: #131217;
	--ax-surface: #1c1a22;
	--ax-surface-2: #3a2e22;
	--ax-ink: #f4f2ee;
	--ax-ink-2: #d7d2ca;
	--ax-ink-3: #b6b0a7;
	--ax-line: #4a3b2c;
	--ax-line-strong: #6b5640;
	--ax-accent: #513bb7;
	--ax-accent-text: #bcabff;
	--ax-accent-soft: #241d41;
	--ax-on-accent: #ffffff;
	--ax-on-accent-2: #f8f5ff;
	--ax-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

body {
	background: var(--ax-bg);
	color: var(--ax-ink);
	font-family: Archivo, system-ui, sans-serif;
}

.button {
	display: inline-block;
	text-decoration: none;
	font-weight: 600;
	font-size: 17px;
	padding: 19px 32px;
	border-radius: 4px;
}

.button-primary {
	background: var(--ax-accent);
	color: var(--ax-on-accent);
}

.button-primary:hover {
	filter: brightness(0.9);
}

.button-secondary {
	background: transparent;
	color: var(--ax-accent-text);
	border: 1px solid var(--ax-line-strong);
}

.button-inverted {
	background: var(--ax-on-accent);
	color: var(--ax-accent-text);
}

/* Testimonial (Phase 1/2 — no visual CMS stylesheet existed until now) */
.testimonial {
	margin: 0;
	padding: 24px 0;
	border-top: 1px solid var(--ax-line);
}

.testimonial-quote {
	margin: 0 0 16px;
	font-family: 'Source Serif 4', serif;
	font-style: italic;
	font-size: 19px;
	line-height: 1.5;
	color: var(--ax-ink);
}

.testimonial-author {
	display: flex;
	align-items: center;
	gap: 12px;
}

.testimonial-photo {
	width: 48px;
	height: 48px;
	border-radius: 50%;
	object-fit: cover;
}

.testimonial-author-info {
	display: flex;
	flex-direction: column;
}

.testimonial-name {
	font-weight: 600;
}

.testimonial-role {
	font-size: 14px;
	color: var(--ax-ink-3);
}

/* Business hours */
.business-hours {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	font-size: 14px;
	color: var(--ax-ink-2);
}

.business-hours li {
	display: flex;
	gap: 4px;
}

.business-hours-label {
	font-weight: 600;
}

/* CTA banner */
.cta-banner {
	background: var(--ax-accent);
	color: var(--ax-on-accent);
}

.cta-banner-inner {
	max-width: 1240px;
	margin: 0 auto;
	padding: 80px 28px;
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 40px;
	flex-wrap: wrap;
}

.cta-banner-eyebrow {
	margin: 0 0 20px;
	font-size: 13px;
	letter-spacing: 1.6px;
	font-weight: 600;
	color: var(--ax-on-accent-2);
}

.cta-banner-heading {
	margin: 0;
	font-size: clamp(32px, 3.8vw, 46px);
	line-height: 1.1;
	letter-spacing: -1.6px;
	font-weight: 600;
}

.cta-banner-subtext {
	margin: 8px 0 0;
	color: var(--ax-on-accent-2);
}

.cta-banner-action {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
}

.cta-banner-phone {
	margin: 0;
	color: var(--ax-on-accent-2);
}

.cta-banner-phone-number {
	color: var(--ax-on-accent);
}

/* Team member / team grid */
.team-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: 24px;
}

.team-member {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.team-member-photo {
	width: 120px;
	height: 120px;
	border-radius: 50%;
	object-fit: cover;
}

.team-member-name {
	margin: 0;
	font-size: 19px;
	font-weight: 600;
}

.team-member-role {
	margin: 0;
	font-size: 14px;
	color: var(--ax-ink-3);
}

.team-member-bio {
	margin: 0;
	color: var(--ax-ink-2);
}

.team-member-contact,
.team-member-social {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	font-size: 14px;
}

.team-member-email,
.team-member-phone,
.team-member-social-link {
	color: var(--ax-accent-text);
}

/* Top nav */
.topnav {
	position: sticky;
	top: 0;
	z-index: 20;
	background: var(--ax-bg);
	border-bottom: 1px solid var(--ax-line);
}

.topnav-inner {
	max-width: 1240px;
	margin: 0 auto;
	padding: 0 28px;
	height: 80px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
}

.topnav-toggle {
	display: none;
	width: 44px;
	height: 44px;
	border: 1px solid var(--ax-line-strong);
	background: var(--ax-surface);
	border-radius: 4px;
	cursor: pointer;
	padding: 0;
}

.topnav-toggle-icon,
.topnav-toggle-icon::before,
.topnav-toggle-icon::after {
	display: block;
	width: 18px;
	height: 2px;
	background: var(--ax-ink);
	margin: 0 auto;
}

.topnav-toggle-icon::before {
	content: '';
	transform: translateY(-6px);
}

.topnav-toggle-icon::after {
	content: '';
	transform: translateY(4px);
}

.topnav-right {
	display: flex;
	align-items: center;
	gap: 20px;
}

@media (max-width: 780px) {
	.topnav-center {
		display: none;
	}

	.topnav-toggle {
		display: block;
	}

	.topnav-right {
		display: none;
		position: absolute;
		top: 80px;
		left: 0;
		right: 0;
		background: var(--ax-surface);
		border-bottom: 1px solid var(--ax-line);
		padding: 16px 28px;
		flex-direction: column;
		align-items: flex-start;
		gap: 12px;
	}

	.topnav-right--open {
		display: flex;
	}
}

/* Hero */
.hero {
	position: relative;
	overflow: hidden;
	padding: 88px 28px 96px;
}

.hero-copy {
	position: relative;
	z-index: 1;
	max-width: 640px;
}

.hero-eyebrow {
	margin: 0 0 26px;
	font-size: 13px;
	letter-spacing: 1.6px;
	font-weight: 600;
	color: var(--ax-ink-3);
}

.hero-heading {
	margin: 0 0 26px;
	font-size: clamp(40px, 5vw, 62px);
	line-height: 1.04;
	letter-spacing: -2px;
	font-weight: 600;
}

.hero-text {
	margin: 0;
	font-size: 19px;
	line-height: 1.7;
	color: var(--ax-ink-2);
}

.hero-buttons {
	margin-top: 36px;
	display: flex;
	gap: 24px;
	flex-wrap: wrap;
}

.hero-bg {
	position: absolute;
	inset: 0;
	z-index: 0;
}

.hero-bg-image img,
.hero-bg-video video {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.hero-bg-slider {
	overflow: hidden;
}

.hero-bg-slider-track {
	position: relative;
	width: 100%;
	height: 100%;
}

.hero-bg-slide {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
	transition: opacity 0.6s ease;
}

.hero-bg-slide--active {
	opacity: 1;
}

.hero-bg-slider-prev,
.hero-bg-slider-next {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	border: none;
	border-radius: 50%;
	background: rgba(0, 0, 0, 0.4);
	color: var(--ax-on-accent);
	font-size: 24px;
	cursor: pointer;
	z-index: 1;
}

.hero-bg-slider-prev {
	left: 16px;
}

.hero-bg-slider-next {
	right: 16px;
}

.hero-bg-slider-dots {
	position: absolute;
	bottom: 16px;
	left: 50%;
	transform: translateX(-50%);
	display: flex;
	gap: 8px;
	z-index: 1;
}

.hero-bg-slider-dot {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	border: none;
	background: rgba(255, 255, 255, 0.5);
	cursor: pointer;
	padding: 0;
}

.hero-bg-slider-dot--active {
	background: var(--ax-on-accent);
}

/* Card */
.card {
	background: var(--ax-surface);
	border: 1px solid var(--ax-line);
	display: flex;
	flex-direction: column;
}

.card-bg-image {
	display: block;
	width: 100%;
	height: 210px;
	object-fit: cover;
	border-bottom: 1px solid var(--ax-line);
}

.card-body {
	padding: 28px;
	display: flex;
	flex-direction: column;
	gap: 12px;
	flex: 1;
}

/* Pushes whatever comes after it (the button) to the bottom of
   .card-body, so buttons align across a row regardless of excerpt
   length — .card-body needed flex: 1 first to actually fill .card's
   full grid-stretched height, or this has nothing to push into. */
.card-text {
	flex: 1;
	margin: 0;
}

.card--big .card-heading {
	font-size: 28px;
}

.card--small .card-heading {
	font-size: 22px;
}

/* Footer */
.site-footer {
	border-top: 1px solid var(--ax-line);
}

.site-footer-grid {
	max-width: 1240px;
	margin: 0 auto;
	padding: 56px 28px 28px;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
	gap: 40px;
}

/* Accordion */
.accordion-item {
	border-top: 1px solid var(--ax-line);
	padding: 16px 0;
}

.accordion-question {
	cursor: pointer;
	font-weight: 600;
}

.accordion-answer {
	margin: 12px 0 0;
	color: var(--ax-ink-2);
}

/* Process steps */
.process-steps {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
	gap: 32px;
}

.process-step {
	border-top: 2px solid var(--ax-accent);
	padding-top: 24px;
}

.process-step-number {
	font-family: 'Source Serif 4', serif;
	font-size: 16px;
	font-weight: 600;
	color: var(--ax-accent-text);
}

/* Trust strip */
.trust-strip {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 32px;
}

.trust-strip-logo {
	max-height: 32px;
	filter: grayscale(1);
	opacity: 0.7;
}

/* Form + form fields — shared across render_form() and every
   render_form_field_*() element */
.form {
	display: flex;
	flex-direction: column;
	gap: 16px;
	max-width: 520px;
}

.form-message {
	/* Same "no dedicated error/red token" gap already documented on
	   .form-field-required below — one shared style for success and
	   error, distinguished by wording, not by an invented color. */
	max-width: 520px;
	padding: 12px 16px;
	border-radius: 4px;
	background: var(--ax-accent-soft);
	color: var(--ax-accent-text);
	font-weight: 600;
}

.form-honeypot {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
}

.form-field {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.form-field label,
.form-field legend {
	font-weight: 600;
}

.form-field-required {
	/* No dedicated error/red token exists in --ax-* yet (unlike theme.json's
	   generic palette, which has one) — using the accent color rather than
	   inventing a new hardcoded red. Flagged as a minor CMS/WP asymmetry. */
	color: var(--ax-accent-text);
}

.form-field input[type='text'],
.form-field input[type='email'],
.form-field input[type='tel'],
.form-field textarea,
.form-field select {
	padding: 8px;
	border: 1px solid var(--ax-line);
	border-radius: 4px;
	font: inherit;
}

.form-field textarea {
	min-height: 120px;
}

.form-field-checkbox-single label,
.form-field-option {
	display: flex;
	align-items: center;
	gap: 4px;
	font-weight: 400;
}

/* Comparison table. No direct design-book precedent for a highlighted
   *column* (only a highlighted pricing *card* — Homepage v2's solid-fill
   Pro card). Extrapolated: solid --ax-accent on the header cell only
   (matches the card precedent), --ax-accent-soft (a light tint, already an
   established token) on body cells for the rest of the column — a solid
   fill running the full table height would read as scattering the strong
   accent, which is the exact thing the design book's critique warned
   against for the old prototype. */
.comparison-table {
	width: 100%;
	border-collapse: collapse;
}

.comparison-table th,
.comparison-table td {
	padding: 12px 16px;
	border: 1px solid var(--ax-line);
	text-align: left;
}

.comparison-table-column-label {
	display: block;
	font-weight: 600;
	font-size: 19px;
}

.comparison-table-price {
	display: block;
	font-size: 28px;
	font-weight: 600;
	margin: 4px 0 12px;
}

.comparison-table-column--highlighted {
	background: var(--ax-accent);
	color: var(--ax-on-accent);
}

.comparison-table-cell--highlighted {
	background: var(--ax-accent-soft);
}

.comparison-table-row-label {
	font-weight: 600;
}

/* No --ax-success token exists (same gap as --ax-error, Phase 6) — meaning
   comes from the glyph shape (check vs dash) and aria-label, not color, so
   no hardcoded green is needed here. */
.comparison-table-check,
.comparison-table-cross {
	color: var(--ax-ink);
}

/* Theme toggle */
.theme-toggle {
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 1px solid var(--ax-line-strong);
	background: var(--ax-surface);
	border-radius: 4px;
	cursor: pointer;
	padding: 0;
}

.theme-toggle-icon {
	font-size: 16px;
	line-height: 1;
	color: var(--ax-ink);
}

/* Cookie banner */
.cookie-banner {
	position: fixed;
	left: 16px;
	right: 16px;
	bottom: 16px;
	z-index: 30;
	max-width: 520px;
	margin: 0 auto;
	background: var(--ax-surface);
	border: 1px solid var(--ax-line);
	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
	padding: 20px;
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.cookie-banner-simple {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px;
	justify-content: space-between;
}

.cookie-banner-text {
	margin: 0;
	font-size: 14px;
	color: var(--ax-ink-2);
	flex: 1 1 240px;
}

.cookie-banner-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.cookie-banner-customize-panel {
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.cookie-banner-category {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.cookie-banner-category label {
	display: flex;
	align-items: center;
	gap: 8px;
	font-weight: 600;
}

.cookie-banner-category-desc {
	margin: 0 0 0 24px;
	font-size: 13px;
	color: var(--ax-ink-2);
}

/* Author CSS declaring display: on an element overrides the browser's own
   [hidden]{display:none} UA-stylesheet rule at equal specificity (later in
   the cascade wins) — the hidden attribute alone doesn't actually hide
   .cookie-banner/-simple/-customize-panel once they have their own
   display:flex, unless this is stated explicitly. Caught by looking at an
   actual screenshot, not by reading the hidden property back in JS (which
   reflects the attribute, not what's visually rendered). */
.cookie-banner[hidden],
.cookie-banner-simple[hidden],
.cookie-banner-customize-panel[hidden] {
	display: none;
}

.cookie-settings-trigger {
	position: fixed;
	left: 16px;
	bottom: 16px;
	z-index: 29;
	background: var(--ax-surface);
	border: 1px solid var(--ax-line);
	border-radius: 4px;
	padding: 8px 12px;
	font-size: 13px;
	font: inherit;
	color: var(--ax-ink);
	cursor: pointer;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}

/* Consent Phase (b) — load-gate primitive (assets/js/consent-gate.js) */
.ax-consent-notice {
	position: fixed;
	right: 16px;
	bottom: 16px;
	z-index: 31;
	max-width: 320px;
	background: var(--ax-accent-soft);
	color: var(--ax-accent-text);
	border-radius: 4px;
	padding: 12px 16px;
	font-size: 13px;
	font-weight: 600;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}

/* No real consumer/design exists yet for .ax-embed-placeholder (Maps in
   Consent Phase d, Video later) — this rule isn't styling, it's insurance
   against the exact bug Consent Phase (a) found: the moment a future
   consumer gives .ax-embed-placeholder its own `display:` value, the
   native [hidden] toggle gateEmbed() uses would silently stop working
   again unless this override already exists. */
.ax-embed-placeholder[hidden] {
	display: none;
}

/* .cookie-banner-text's flex-basis (240px) forces a wrap at narrow widths,
   and justify-content:space-between then shoves the lone button off to
   the far right on its own line — stack cleanly instead. Placed here, right
   after the base rule, not in the earlier topnav media query block — a
   media-query rule and an unconditional rule of equal specificity resolve
   by source order, so putting this before the base rule (as originally done)
   let the base rule always win regardless of viewport width. Now targets
   .cookie-banner-simple (Consent Phase a's restructure moved the row
   layout there; .cookie-banner itself is column-stacked at every width). */
@media (max-width: 780px) {
	.cookie-banner-simple {
		flex-direction: column;
		align-items: stretch;
	}

	/* flex-basis (240px, set for the row layout above) applies to *height*
	   once the container becomes flex-direction: column here — pre-existing
	   latent bug in this exact selector/breakpoint (same shape as the
	   original single-row banner had), only actually visible once a real
	   mobile screenshot was checked. Reset to auto so it sizes to content. */
	.cookie-banner-text {
		flex-basis: auto;
	}

	.cookie-banner-actions {
		justify-content: stretch;
	}

	.cookie-banner-actions .button {
		flex: 1 1 auto;
		text-align: center;
	}
}

/* Brand + nav menu (home page build) */
.brand {
	display: flex;
	align-items: center;
	gap: 12px;
	text-decoration: none;
	color: var(--ax-ink);
	font-size: 24px;
	font-weight: 700;
	letter-spacing: -1px;
}

.brand-logo {
	display: block;
	width: 42px;
	height: 42px;
	object-fit: contain;
}

.brand-light {
	font-weight: 400;
	color: var(--ax-ink-2);
}

.navmenu {
	display: flex;
	align-items: center;
	gap: 30px;
	font-size: 15px;
	flex-wrap: wrap;
}

.navmenu a {
	color: var(--ax-ink-2);
	text-decoration: none;
}

/* Card eyebrow/meta (portfolio + journal cards use render_card() with these) */
.card-eyebrow {
	margin: 0 0 14px;
	font-size: 13px;
	letter-spacing: 1.2px;
	font-weight: 600;
	color: var(--ax-accent-text);
}

.card-meta {
	margin: 0 0 20px;
	font-size: 15px;
	color: var(--ax-ink-3);
}

/* Hero / CTA banner two-part heading (plain line + serif-italic accent phrase) */
.hero-heading-accent {
	font-family: 'Source Serif 4', serif;
	font-weight: 400;
	font-style: italic;
	letter-spacing: -1px;
	color: var(--ax-accent-text);
}

.cta-banner-heading-accent {
	font-family: 'Source Serif 4', serif;
	font-weight: 400;
	font-style: italic;
	letter-spacing: -1px;
	/* no color override — inherits on-accent from .cta-banner, matches Homepage v2 */
}

/* Services as rows (no existing element fit — see report) */
.service-rows {
	background: var(--ax-surface);
	border: 1px solid var(--ax-line);
	box-shadow: var(--ax-shadow);
}

.service-row {
	display: grid;
	grid-template-columns: 52px minmax(180px, 1fr) minmax(240px, 1.3fr);
	gap: 26px;
	align-items: center;
	padding: 28px 32px;
	border-bottom: 1px solid var(--ax-line);
	text-decoration: none;
	color: inherit;
}

.service-row:last-child {
	border-bottom: none;
}

.service-row:hover {
	background: var(--ax-surface-2);
}

.service-row-number {
	font-size: 15px;
	font-weight: 600;
	color: var(--ax-accent-text);
}

.service-row-heading {
	margin: 0;
	font-size: 23px;
	letter-spacing: -0.4px;
	font-weight: 600;
	color: var(--ax-ink);
}

.service-row-text {
	margin: 0;
	font-size: 17px;
	line-height: 1.55;
	color: var(--ax-ink-2);
}

/* .service-row's 3-column grid has hard minimum track widths (180px/240px)
   that don't shrink like the auto-fit grids used elsewhere on the page —
   stack it instead of letting it overflow. Placed here, right after the
   base rule, not in the earlier topnav media query block — a media-query
   rule and an unconditional rule of equal specificity resolve by source
   order, so putting this before the base rule (as originally done) let
   the base rule always win regardless of viewport width. */
@media (max-width: 780px) {
	.service-row {
		grid-template-columns: 1fr;
		gap: 8px;
		padding: 20px 4px;
	}
}

/* Pricing card (no existing element fit — see report) */
.pricing-card {
	background: var(--ax-surface);
	border: 1px solid var(--ax-line);
	padding: 34px;
	display: flex;
	flex-direction: column;
	position: relative;
}

.pricing-card--highlighted {
	background: var(--ax-accent);
	color: var(--ax-on-accent);
	border: none;
}

.pricing-card-badge {
	position: absolute;
	top: 0;
	left: 34px;
	background: var(--ax-on-accent);
	color: var(--ax-accent-text);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 1px;
	padding: 6px 12px;
}

.pricing-card-heading {
	margin: 0 0 8px;
	font-size: 28px;
	font-weight: 600;
	letter-spacing: -0.6px;
}

.pricing-card--highlighted .pricing-card-heading {
	margin-top: 22px;
}

.pricing-card-tagline {
	margin: 0 0 26px;
	font-size: 16px;
	color: var(--ax-ink-2);
}

.pricing-card--highlighted .pricing-card-tagline {
	color: var(--ax-on-accent-2);
}

.pricing-card-price {
	margin: 0 0 26px;
	display: flex;
	align-items: baseline;
	gap: 8px;
}

.pricing-card-price-value {
	font-size: 46px;
	font-weight: 600;
	letter-spacing: -1.6px;
}

.pricing-card-price-unit {
	font-size: 16px;
	color: var(--ax-ink-2);
}

.pricing-card--highlighted .pricing-card-price-unit {
	color: var(--ax-on-accent-2);
}

.pricing-card-price-note {
	margin: 0 0 18px;
	font-size: 16px;
	font-weight: 600;
}

.pricing-card-features {
	margin: 0;
	padding: 26px 0 28px;
	list-style: none;
	border-top: 1px solid var(--ax-line);
	font-size: 16px;
	line-height: 1.5;
	color: var(--ax-ink-2);
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.pricing-card--highlighted .pricing-card-features {
	border-top-color: rgba(255, 255, 255, 0.35);
	color: inherit;
}

.pricing-card-text {
	margin: 0 0 22px;
	font-size: 15px;
	line-height: 1.6;
	color: var(--ax-ink-2);
	flex: 1;
}

/* Footer bottom bar */
.site-footer-bottom {
	max-width: 1240px;
	margin: 0 auto;
	padding: 24px 28px 48px;
	border-top: 1px solid var(--ax-line);
	display: flex;
	justify-content: space-between;
	gap: 20px;
	flex-wrap: wrap;
	font-size: 15px;
	color: var(--ax-ink-3);
}

.site-footer-bottom p {
	margin: 0;
}

/* Page section chrome (home page build) — the outer wrapper/spacing/header
   pattern that recurs across every section, not owned by any one element */
.page-section {
	border-top: 1px solid var(--ax-line);
}

.page-section--soft {
	background: var(--ax-surface-2);
}

.page-section-inner {
	max-width: 1240px;
	margin: 0 auto;
	padding: 88px 28px;
}

.section-header {
	display: flex;
	justify-content: space-between;
	align-items: flex-end;
	gap: 32px;
	flex-wrap: wrap;
	margin-bottom: 44px;
}

.section-eyebrow {
	margin: 0 0 20px;
	font-size: 13px;
	letter-spacing: 1.6px;
	font-weight: 600;
	color: var(--ax-ink-3);
}

.section-title {
	margin: 0;
	font-size: clamp(30px, 3.4vw, 42px);
	line-height: 1.12;
	letter-spacing: -1.4px;
	font-weight: 600;
}

.section-header-trailing {
	margin: 0;
	font-size: 17px;
	line-height: 1.6;
	color: var(--ax-ink-2);
	max-width: 370px;
}

.section-header-link {
	font-weight: 600;
	font-size: 16px;
	color: var(--ax-accent-text);
	text-decoration: none;
	border-bottom: 1px solid currentColor;
	padding-bottom: 3px;
}

/* Card grid — shared by portfolio and journal sections (both compose
   render_card() instances) */
.card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 20px;
}

/* render_post_list() (elements/post-list.php) wraps render_post_card()
   output in a plain <div class="post-list"> with no grid rule anywhere
   in this file — same gap .gallery had, found the same way: this site
   has never had a real published post to render, so nobody had actually
   looked at it. Same shape as .card-grid on purpose — post cards ARE
   cards. */
.post-list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 20px;
}

/* render_gallery() (elements/gallery.php) had no styling anywhere in
   this file — not called by this site itself, found missing when the
   bookbinding deployment became its first real caller and images
   rendered at native size with no grid. 2 columns, square thumbnails —
   a generic default any deployment's own theme.css can override. */
.gallery {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 8px;
}

.gallery img {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
}

.pricing-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 20px;
	align-items: stretch;
}

.pricing-grid--services {
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.pricing-note {
	margin: 0 0 36px;
	font-size: 15px;
	color: var(--ax-ink-3);
}

.pricing-services-label {
	margin: 48px 0 24px;
	padding-top: 34px;
	border-top: 1px solid var(--ax-line);
	font-size: 13px;
	letter-spacing: 1.6px;
	font-weight: 600;
	color: var(--ax-ink-3);
}

/* Hero side-by-side layout: render_hero() normally owns its own section
   padding (for the overlay-background case) — when a real screenshot sits
   beside it instead of behind it, this outer wrapper takes over the
   padding/grid and resets .hero's own to avoid doubling up. */
.hero-side-layout {
	max-width: 1240px;
	margin: 0 auto;
	padding: 88px 28px 96px;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
	gap: 56px;
	align-items: center;
}

.hero-side-layout .hero {
	padding: 0;
	overflow: visible;
	position: static;
}

.hero-screenshot-frame {
	background: var(--ax-surface);
	border: 1px solid var(--ax-line);
	padding: 14px;
	box-shadow: var(--ax-shadow);
}

.hero-screenshot-frame img {
	display: block;
	width: 100%;
	height: 390px;
	object-fit: cover;
	object-position: top;
}

.hero-screenshot-caption {
	margin: 16px 0 0;
	font-size: 15px;
	line-height: 1.6;
	color: var(--ax-ink-2);
}

.hero-screenshot-caption strong {
	color: var(--ax-ink);
}

.portfolio-note {
	margin: 26px 0 0;
	padding-top: 22px;
	border-top: 1px solid var(--ax-line);
	font-size: 16px;
	color: var(--ax-ink-2);
}

.portfolio-note strong {
	color: var(--ax-ink);
}

.site-footer-label {
	margin: 0 0 4px;
	font-size: 13px;
	letter-spacing: 1.2px;
	font-weight: 600;
	color: var(--ax-ink-3);
}

.site-footer-nav .navmenu,
.site-footer-legal .navmenu {
	flex-direction: column;
	align-items: flex-start;
	gap: 12px;
}
