.fx-loop-frame .fx-one-record-node.fx-one-record-node--mcc { fill: color-mix(in srgb, var(--wp--preset--color--accent) 20%, var(--wp--preset--color--surface)) !important; stroke: var(--wp--preset--color--accent); stroke-width: 1.4; }
.fx-one-record-label { fill: var(--wp--preset--color--contrast); font-family: var(--wp--preset--font-family--mono); font-size: 16px; font-weight: 800; text-anchor: middle; }
/* One record: compact portrait graphic and equal-height card stack. */
figure.fx-loop-figure { margin: 0; }
.fx-loop-frame { max-width: 660px; margin: 0 auto; }
.fx-loop-frame svg { display: block; width: 100%; height: auto; }
.fx-one-record-loop { fill: none; stroke: var(--wp--preset--color--border); stroke-width: 1.4; stroke-dasharray: 4 8; }
.fx-one-record-loop--mcc { stroke: var(--wp--preset--color--accent); stroke-opacity: 0.55; }
.fx-one-record-link { fill: none; stroke: var(--wp--preset--color--border); stroke-width: 1; stroke-dasharray: 4 8; }
.fx-one-record-node { fill: var(--wp--preset--color--surface); stroke: var(--wp--preset--color--border); stroke-width: 1; }
.fx-one-record-flow { offset-rotate: 0deg; }
@keyframes fx-one-record-run { 0% { offset-distance: 0%; } 8% { offset-distance: 0%; } 88% { offset-distance: 100%; } 100% { offset-distance: 100%; } }
@keyframes fx-one-record-fade { 0% { opacity: 0; } 5% { opacity: 1; } 92% { opacity: 1; } 100% { opacity: 0; } }
@keyframes fx-one-record-l1-move { 0% { offset-distance: 0%; } 5% { offset-distance: 0%; } 27.5% { offset-distance: 18.24%; } 32.5% { offset-distance: 18.24%; } 66.5% { offset-distance: 68.24%; } 71.5% { offset-distance: 68.24%; } 94% { offset-distance: 100%; } 100% { offset-distance: 100%; } }
@keyframes fx-one-record-l2-move { 0% { offset-distance: 0%; } 5% { offset-distance: 0%; } 33% { offset-distance: 36.49%; } 38% { offset-distance: 36.49%; } 63.4% { offset-distance: 68.24%; } 68.4% { offset-distance: 68.24%; } 94% { offset-distance: 100%; } 100% { offset-distance: 100%; } }
@keyframes fx-one-record-r1-move { 0% { offset-distance: 0%; } 5% { offset-distance: 0%; } 20% { offset-distance: 10.75%; } 25% { offset-distance: 10.75%; } 47% { offset-distance: 52.69%; } 52% { offset-distance: 52.69%; } 66% { offset-distance: 70.97%; } 71% { offset-distance: 70.97%; } 94% { offset-distance: 100%; } 100% { offset-distance: 100%; } }
@keyframes fx-one-record-r2-move { 0% { offset-distance: 0%; } 5% { offset-distance: 0%; } 50% { offset-distance: 60%; } 55% { offset-distance: 60%; } 94% { offset-distance: 100%; } 100% { offset-distance: 100%; } }
@keyframes fx-one-record-r3-move { 0% { offset-distance: 0%; } 5% { offset-distance: 0%; } 12% { offset-distance: 14.87%; } 17% { offset-distance: 14.87%; } 38% { offset-distance: 41.75%; } 43% { offset-distance: 41.75%; } 64% { offset-distance: 70.88%; } 69% { offset-distance: 70.88%; } 94% { offset-distance: 100%; } 100% { offset-distance: 100%; } }
@keyframes fx-one-record-r4-move { 0% { offset-distance: 0%; } 5% { offset-distance: 0%; } 43% { offset-distance: 48%; } 48% { offset-distance: 48%; } 94% { offset-distance: 100%; } 100% { offset-distance: 100%; } }
@media (max-width: 900px) {
	/* The diagram now sits below the headline and above the cards, so it scales
	   to the column instead of forcing a sideways scroll. A 540px min-width made
	   a 796-unit-wide illustration wider than a 272px phone column, so the
	   figure scrolled horizontally rather than fitting. min-width is dropped to
	   240px purely to stop the 16px label text collapsing to unreadable; past
	   that the SVG scales with width and the labels hold their size. */
	.fx-loop-frame > svg { min-width: 240px; }
}
@media (prefers-reduced-motion: reduce) {
	.fx-one-record-flow { animation: none !important; opacity: 1 !important; }
	.fx-one-record-l1 { offset-distance: 14%; }
	.fx-one-record-l2 { offset-distance: 20%; }
	.fx-one-record-r1 { offset-distance: 45%; }
	.fx-one-record-r2 { offset-distance: 30%; }
	.fx-one-record-r3 { offset-distance: 25%; }
	.fx-one-record-r4 { offset-distance: 25%; }
	.fx-one-record-m3 { offset-distance: 30%; }
	.fx-one-record-m4 { offset-distance: 55%; }
	.fx-one-record-m5 { offset-distance: 35%; }
	.fx-one-record-m6 { offset-distance: 60%; }
	.fx-one-record-o1 { offset-distance: 55%; }
	.fx-one-record-o2 { offset-distance: 70%; }
	.fx-one-record-o3 { offset-distance: 45%; }
	.fx-one-record-o4 { offset-distance: 30%; }
}

.fx-one-record-l1 { offset-path: path("M 418 350 L 688 350 L 688 150 L 148 150 L 148 350 L 418 350"); animation: fx-one-record-l1-move 14s linear 0s infinite, fx-one-record-fade 14s linear 0s infinite; }
.fx-one-record-l2 { offset-path: path("M 148 150 L 688 150 L 688 350 L 418 350 L 148 350 L 148 150"); animation: fx-one-record-l2-move 11s linear -4s infinite, fx-one-record-fade 11s linear -4s infinite; }
.fx-one-record-r1 { offset-path: path("M 148 610 L 148 410 L 418 410 L 538 410 L 538 800 L 688 800 L 688 610 L 148 610"); animation: fx-one-record-r1-move 19s linear 0s infinite, fx-one-record-fade 19s linear 0s infinite; }
.fx-one-record-r2 { offset-path: path("M 418 410 L 298 410 L 298 800 L 148 800 L 148 610"); animation: fx-one-record-r2-move 9s linear -3s infinite, fx-one-record-fade 9s linear -3s infinite; }
.fx-one-record-r3 { offset-path: path("M 538 800 L 298 800 L 688 610 L 688 410 L 418 410 L 148 410 L 148 610"); animation: fx-one-record-r3-move 16s linear -7s infinite, fx-one-record-fade 16s linear -7s infinite; }
.fx-one-record-r4 { offset-path: path("M 538 800 L 148 610 L 148 410 L 418 410"); animation: fx-one-record-r4-move 10s linear -5s infinite, fx-one-record-fade 10s linear -5s infinite; }
.fx-one-record-m3 { offset-path: path("M 538 800 L 538 410 L 418 410"); animation: fx-one-record-run 11s linear -2s infinite, fx-one-record-fade 11s linear -2s infinite; }
.fx-one-record-m4 { offset-path: path("M 298 800 L 298 410 L 418 410"); animation: fx-one-record-run 12s linear -6s infinite, fx-one-record-fade 12s linear -6s infinite; }
.fx-one-record-m5 { offset-path: path("M 688 150 L 688 350 L 418 350"); animation: fx-one-record-run 8.5s linear -4s infinite, fx-one-record-fade 8.5s linear -4s infinite; }
.fx-one-record-m6 { offset-path: path("M 148 150 L 148 350 L 418 350"); animation: fx-one-record-run 7.5s linear -2.5s infinite, fx-one-record-fade 7.5s linear -2.5s infinite; }
.fx-one-record-o1 { offset-path: path("M 418 410 L 688 410 L 688 610"); animation: fx-one-record-run 5.5s linear -0.5s infinite, fx-one-record-fade 5.5s linear -0.5s infinite; }
.fx-one-record-o2 { offset-path: path("M 418 410 L 148 410 L 148 610"); animation: fx-one-record-run 6s linear -3s infinite, fx-one-record-fade 6s linear -3s infinite; }
.fx-one-record-o3 { offset-path: path("M 418 410 L 538 410 L 538 800"); animation: fx-one-record-run 7s linear -1.5s infinite, fx-one-record-fade 7s linear -1.5s infinite; }
.fx-one-record-o4 { offset-path: path("M 418 410 L 298 410 L 298 800"); animation: fx-one-record-run 7.5s linear -5s infinite, fx-one-record-fade 7.5s linear -5s infinite; }
/* One record: compact portrait graphic and equal-height card stack.

   The eyebrow + headline block is its own grid item rather than the first
   child of the card column, so the three items can be placed independently:

     desktop   graphic | intro
               graphic | cards

     mobile    intro
               graphic
               cards

   That gives the phone order headline -> graphic -> cards while leaving the
   desktop composition identical to the previous nested-column layout. */
.fx-one-record-layout { display: grid !important; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); grid-template-areas: "graphic intro" "graphic cards"; gap: clamp(24px, 3vw, 40px) !important; align-items: stretch !important; width: 100%; max-width: 1240px; margin-inline: auto; }
.fx-one-record-layout > * { min-width: 0; margin: 0; }
.fx-one-record-graphic { grid-area: graphic; min-width: 0; height: 100%; display: flex; align-items: center; margin: 0; align-self: stretch; }
.fx-one-record-graphic .fx-loop-frame { width: 100%; max-width: 660px; margin: 0 auto; }
.fx-one-record-intro { grid-area: intro; min-width: 0; margin: 0; align-self: start; }
.fx-one-record-cards { grid-area: cards; }
/* .fx-one-record-graphic IS the figure now, so there is no
   .fx-one-record-graphic .fx-loop-figure wrapper left to style. */
.fx-one-record-graphic .fx-loop-frame { width: 100%; max-width: 660px; margin: 0 auto; }
.fx-loop-frame svg { display: block; width: 100%; height: auto; }
.fx-one-record-cards { display: grid !important; grid-template-rows: repeat(3, minmax(0, 1fr)); grid-auto-rows: minmax(0, 1fr); gap: 16px; align-content: stretch; height: 100%; min-height: 0; margin: 0; align-self: stretch; }
/* The intro block reuses .fx-copy, whose margins are declared later in this file.
   Reset them here so the grid gap alone controls spacing under the headline. */
.fx-one-record-intro { margin-block: 0 4px; }
.fx-one-record-intro .fx-eyebrow { margin-block: 0 12px; }
.fx-one-record-intro .fx-one-record-title { margin-block: 0; }
/* Match the module card h3 scale while keeping the section-level h2 tag. */
.fx-one-record-title { font-size: 1.375rem; line-height: 1.15; letter-spacing: -0.01em; font-weight: 600; }
.fx-one-record-cards > .wp-block-group.is-style-spec-card { display: flex !important; flex-direction: column; justify-content: center; align-content: center; align-items: flex-start; height: 100% !important; min-height: 0; width: 100%; max-width: none; margin: 0; padding: 22px 24px; box-sizing: border-box; overflow: hidden; }
.fx-one-record-cards > .wp-block-group.is-style-spec-card > * { margin-block: 0; max-width: none; }
.fx-one-record-cards > .wp-block-group.is-style-spec-card > .fx-card-eyebrow { margin-block-end: 12px; }
@media (max-width: 900px) {
	/* One column, in reading order: headline first, then the diagram, then the
	   three cards. The diagram is capped so a phone does not scroll a full-height
	   portrait illustration before reaching any copy. */
	.fx-one-record-layout {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: auto auto auto;
		grid-template-areas: "intro" "graphic" "cards";
		align-items: start !important;
	}
	.fx-one-record-graphic, .fx-one-record-cards { height: auto; }
	.fx-one-record-cards { grid-template-rows: none; }
	.fx-one-record-intro { margin-block-end: 4px; }
	.fx-one-record-graphic .fx-loop-frame { max-width: 320px; }
}

/* SynConnect layout: writing left, network graphic right, stats below. */
.wp-block-columns.fx-synconnect-columns { display: grid !important; grid-template-columns: minmax(0, 0.6fr) minmax(0, 0.4fr); gap: clamp(32px, 5vw, 72px); align-items: center !important; }
.fx-synconnect-columns > .wp-block-column { min-width: 0; width: auto; }
.fx-net { margin: 0; }
.fx-net svg { display: block; width: 100%; height: auto; }
/* synConnect title and subtitle use the default h2 / body paragraph styles, the
   same pairing as the Modules desk section. Only the measure is scoped here, to
   match `.fx-modules-copy` (20ch heading, 64ch paragraph). */
.fx-synconnect-copy h2 { max-width: 20ch; }
.fx-synconnect-copy p { max-width: 64ch; }

/* Lifecycle rail: closes the writing column beneath the subtitle, so it needs
   only a top gap and no bottom margin. */
.fx-synconnect-lifecycle { margin-block: 32px 0; }
.fx-synconnect-lifecycle .fx-lifecycle-track { display: flex; min-width: 0; flex-wrap: nowrap; overflow-x: auto; margin-block-end: 0; padding-block-end: 4px; }
.fx-synconnect-lifecycle .fx-chip-static { flex: 0 0 auto; white-space: nowrap; }

/* Zero-height flex item that forces a wrap. Hidden on desktop, where the track
   is a single non-wrapping row. */
.fx-lifecycle-break { display: none; }

@media (max-width: 720px) {
	/* Three chips on the first line and two on the second, both centred, rather
	   than one long row that has to be scrolled sideways. The break element
	   between 03 and 04 is what puts the split there; flex alone would pack as
	   many as fitted per line and the split would move between devices. */
	.fx-synconnect-lifecycle .fx-lifecycle-track {
		flex-wrap: wrap;
		justify-content: center;
		overflow-x: visible;
		padding-block-end: 0;
		row-gap: 8px;
	}
	.fx-lifecycle-break { display: block; flex-basis: 100%; height: 0; margin: 0; padding: 0; }
	.fx-synconnect-lifecycle .fx-chip-static { padding: 9px 13px; font-size: 11px; letter-spacing: 0.06em; }
}

@media (max-width: 360px) {
	/* The three-chip row needs about 260px at this size. On a 320px phone the
	   track is 272px, so padding, tracking and type step down once more to keep
	   the requested 3 + 2 split rather than spilling to a third line. */
	.fx-synconnect-lifecycle .fx-lifecycle-track { gap: 5px 6px; }
	.fx-synconnect-lifecycle .fx-chip-static { padding: 8px 11px; font-size: 9.5px; letter-spacing: 0.04em; }
}

/* Modules band: muted video backdrop behind the copy and desk cards.
   The clip is pushed well down — desaturated, dimmed and heavily scrimmed — so
   it reads as depth rather than footage, and body text keeps AA contrast
   against the surface tone. The section's own surface background carries the
   brand colour; the video only layers texture over it. */
.fx-modules-video {
	position: relative;
	isolation: isolate;
}
.fx-modules-media {
	position: absolute;
	inset: 0;
	width: 100%;
	z-index: 0;
	overflow: hidden;
	pointer-events: none;
}
/* alignfull gets us max-width: none and opts out of the constrained layout's
   `margin-left/right: auto !important` centring. Core also gives alignfull
   negative margins to escape the root gutter, but this element is absolutely
   positioned and inset:0 already fills the section's padding box, so those
   escapes would push it past the right edge. Same specificity as core's
   `.has-global-padding > .alignfull`, declared later, so it wins. */
.fx-modules-media.alignfull {
	margin-inline: 0;
}
.fx-modules-media video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.fx-modules-media::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		/* The vertical wash ramps to fully opaque surface over the last fifth of
		   the band, so the clip resolves to exactly the next section's surface
		   colour at the seam instead of stopping a few shades darker and reading
		   as a gap. */
		linear-gradient(180deg, rgba(18, 22, 29, 0.88) 0%, rgba(18, 22, 29, 0.8) 78%, rgba(18, 22, 29, 1) 100%),
		linear-gradient(90deg, rgba(10, 13, 18, 0.5) 0%, rgba(10, 13, 18, 0.12) 65%);
}
/* Lift the content above the media layer. */
.fx-modules-video > *:not(.fx-modules-media) {
	position: relative;
	z-index: 1;
}

/* Flat surface bands. These take the plain surface color, and sections with no
   band class fall back to the base page color, so the page alternates down. The
   gold-wash bands are grouped with the hero's rule further down. */
.fx-cost-band,
.fx-modules-band,
.fx-roles-band,
.fx-trend-band {
	background: var(--wp--preset--color--surface);
}
.fx-modules-copy { margin-block-end: 0; }
.fx-modules-copy h2 { max-width: 20ch; }
.fx-modules-copy p { max-width: 64ch; }
.fx-modules {
	display: grid;
	grid-template-columns: 0.92fr 1fr 1fr 1fr;
	gap: 24px;
	margin-block-start: 56px;
	align-items: stretch;
}
.fx-modules-record,
.fx-modules-card {
	min-width: 0;
	border-radius: var(--wp--custom--radius--md);
}
/* Event-file panel: black ground so the live record reads apart from the desk cards. */
.fx-modules-record {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	padding: 22px;
	font-family: var(--wp--preset--font-family--mono);
}
/* Desk cards sit over the video backdrop, so they are held back to 0.8. This
   fades the copy inside them as well as the panel. If the body text reads thin
   over the moving clip, drop the opacity and instead give the panel a
   semi-transparent background (e.g. color-mix in srgb, surface 80%, transparent)
   so only the ground fades and the text stays fully opaque. */
.fx-modules-card {
	display: flex;
	flex-direction: column;
	padding: 28px;
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	opacity: 0.8;
}
.fx-modules-card h3 { margin: 0; font-family: var(--wp--preset--font-family--heading); font-size: 1.375rem; line-height: 1.3; font-weight: 600; letter-spacing: -0.01em; color: var(--wp--preset--color--contrast); }
.fx-modules-record-head,
.fx-modules-record-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.fx-modules-record-head { padding-block-end: 14px; border-block-end: 1px solid var(--wp--preset--color--border); }
.fx-modules-record-head > span:first-child { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--wp--preset--color--muted); }
.fx-modules-record-tail { font-size: 11px; letter-spacing: 0.1em; color: var(--wp--preset--color--contrast); }
.fx-modules-record-row { padding-block: 14px; border-block-end: 1px solid var(--wp--preset--color--surface-raised); }
.fx-modules-record-row.is-last { padding-block-end: 0; border-block-end: 0; }
.fx-modules-record-row > span:first-child { font-size: 12px; color: var(--wp--preset--color--muted); }
.fx-modules-record-row > span:last-child { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--wp--preset--color--contrast); }
/* Status values in the event-file panel, mapped to shared tokens.
   The neutral `.fx-modules-record-row > span:last-child` rule above scores (0,2,1),
   so these must out-specify it or every status renders as neutral contrast. */
.fx-modules-record .fx-modules-record-row > span.is-ok { color: var(--fx-ok); }
.fx-modules-record .fx-modules-record-row > span.is-accent { color: var(--wp--preset--color--accent); }
.fx-modules-record .fx-modules-record-row > span.is-info { color: var(--fx-info); }
.fx-modules-record .fx-modules-record-row > span.is-alert { color: var(--fx-alert); }

.fx-modules-card > p { margin: 12px 0 20px; color: var(--wp--preset--color--muted); font-size: 15px; line-height: 1.6; }
.fx-modules-card ul { margin: 0; padding: 0; list-style: none; }
.fx-modules-card li { padding: 8px 0 8px 18px; border-block-start: 1px solid var(--wp--preset--color--surface-raised); color: var(--wp--preset--color--muted); font-size: 15px; }

@media (max-width: 1100px) {
	.fx-modules { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 782px) {
	.fx-modules { grid-template-columns: minmax(0, 1fr); }
}

/* rectifAI section: pitch + verification panel, metric strip, capability cards, trend chart. */
.fx-rc-split { display: grid; grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr); gap: 56px; align-items: center; }
/* Body copy in this copy block. This section has no kicker, so `:not(.fx-eyebrow)`
   is purely defensive: `.fx-rc-copy > p` is (0,1,1) and would outrank
   `.fx-eyebrow` (0,1,0), forcing a kicker back to 17px muted body styling if one
   is ever added here directly. */
.fx-rc-copy > p:not(.fx-eyebrow) { max-width: 58ch; color: var(--wp--preset--color--muted); font-size: 17px; line-height: 1.65; margin: 22px 0 0; }
.fx-rc-copy > p + p { margin-block-start: 18px; }
/* rectifAI wordmark from assets/img/rectifAI.svg, used as the identity in the
   verification panel head. Kept as an <img> rather than inlined so it stays a
   cacheable static asset and carries real alt text. Intrinsic size is 200x50
   (4:1), and those width/height attributes reserve the box to prevent layout
   shift; CSS then scales by width only so the ratio is never distorted.
   Sized to ~26px tall so it sits level with the "Ready in < 2 s" badge, which
   drives the head's height. The mark is white + amber, so it needs the dark
   panel ground this section already sits on. */
.fx-rc-logo { display: block; width: 104px; max-width: 100%; height: auto; }
.fx-rc-title { max-width: 20ch; }
/* Single link, so this is a plain block that only carries the top spacing —
   flex and the 28px column gap are no longer doing any work. */
.fx-rc-links { margin-block-start: 32px; }
.fx-rc-link { font-family: var(--wp--preset--font-family--mono); font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none; color: var(--wp--preset--color--accent); }
.fx-rc-link:hover { text-decoration: underline; }

/* Vertical rhythm inside the verification panel. Three values: a label sits 8px
   above the value it labels, groups are separated by 22px, and the panel body
   clears the head's divider by 28px. Only the label carries a top margin, so
   every in-panel gap is set by a single declaration instead of depending on two
   adjacent margins collapsing to the same number. The head keeps its own 20px so
   the wordmark and tabs stay tied to the rule; the larger gap belongs below it. */
.fx-rc-verify { background: var(--wp--preset--color--surface); border: 1px solid var(--wp--preset--color--border); border-radius: var(--wp--custom--radius--md); padding: 28px; --fx-rc-gap-label: 8px; --fx-rc-gap-group: 22px; --fx-rc-gap-rule: 28px; }
.fx-rc-verify-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding-block-end: 20px; border-block-end: 1px solid var(--wp--preset--color--border); }
/* The tablist now lives in the head, so it carries no block margin: the head's
   own padding and border separate it from the panels below. `flex-end` keeps the
   tabs right-aligned if they ever wrap in a narrow panel. */
.fx-rc-tabs { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.fx-rc-tab { flex: none; font-family: var(--wp--preset--font-family--mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--wp--preset--color--muted); background: transparent; border: 1px solid var(--wp--preset--color--border); border-radius: 3px; padding: 7px 14px; cursor: pointer; }
.fx-rc-label { font-family: var(--wp--preset--font-family--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--wp--preset--color--muted); }
.fx-rc-label.is-accent { color: var(--wp--preset--color--accent); }
.fx-rc-tab:hover { border-color: var(--wp--preset--color--accent); color: var(--wp--preset--color--contrast); }
.fx-rc-tab[aria-selected="true"] { border-color: var(--wp--preset--color--accent); background: color-mix(in srgb, var(--wp--preset--color--accent) 12%, transparent); color: var(--wp--preset--color--accent); }
/* Padding, not margin, so it cannot collapse with the first label's zeroed
   top margin. Constant across all three tabs, so the 300px min-height still
   holds the panel steady when switching. */
.fx-rc-panels { min-height: 300px; padding-block-start: var(--fx-rc-gap-rule); }
.fx-rc-panel .fx-rc-label { margin-block-start: var(--fx-rc-gap-group); }
.fx-rc-panel .fx-rc-label:first-child { margin-block-start: 0; }
.fx-rc-workflow { margin-block: var(--fx-rc-gap-label) 0; font-size: 17px; color: var(--wp--preset--color--contrast); }
.fx-rc-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-block: var(--fx-rc-gap-label) 0; }
.fx-rc-chip { padding: 7px 12px; border: 1px solid var(--wp--preset--color--border); border-radius: 3px; background: var(--wp--preset--color--base); font-size: 13px; color: var(--wp--preset--color--muted); }
.fx-rc-guidance { margin-block: var(--fx-rc-gap-label) 0; padding: 16px 18px; border-inline-start: 2px solid var(--wp--preset--color--accent); background: var(--wp--preset--color--base); font-size: 16px; line-height: 1.55; color: var(--wp--preset--color--contrast); }
/* margin is zeroed explicitly rather than omitted: this is a <p>, so dropping
   the declaration would hand it back to the UA default `margin: 1em 0`, which
   adds 14px below as well and re-introduces the gap inside the panel. The top
   padding uses the panel's group gap so the footnote sits on the same rhythm
   as the groups above it. */
.fx-rc-note { margin: 0; padding-block-start: var(--fx-rc-gap-group); border-block-start: 1px solid var(--wp--preset--color--border); font-size: 12px; color: var(--wp--preset--color--muted); }

/* rectifAI capability cards and trend chart. */
.fx-rc-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; margin-block-start: 56px; }
.fx-rc-card { background: var(--wp--preset--color--surface); border: 1px solid var(--wp--preset--color--border); border-radius: var(--wp--custom--radius--md); padding: 28px; }
.fx-rc-card h3 { margin: 0; font-family: var(--wp--preset--font-family--heading); font-size: 21px; line-height: 1.3; letter-spacing: -0.01em; font-weight: 600; color: var(--wp--preset--color--contrast); }
.fx-rc-card-eyebrow { margin: 8px 0 18px; font-family: var(--wp--preset--font-family--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--wp--preset--color--accent); }
.fx-rc-card ul { margin: 0; padding: 0; list-style: none; }
.fx-rc-card li { padding: 12px 0; border-block-start: 1px solid var(--wp--preset--color--surface-raised); font-size: 15px; line-height: 1.55; color: var(--wp--preset--color--muted); }
/* Own section now, so no top offset — the section padding sets the rhythm. */
.fx-trend { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 56px; align-items: center; }
.fx-trend-copy h3 { margin: 0; max-width: 20ch; font-family: var(--wp--preset--font-family--heading); font-size: 28px; line-height: 1.2; letter-spacing: -0.02em; font-weight: 600; color: var(--wp--preset--color--contrast); }
.fx-trend-copy p { margin: 18px 0 0; max-width: 58ch; color: var(--wp--preset--color--muted); font-size: 17px; line-height: 1.65; }
.fx-trend-chart svg { display: block; width: 100%; height: auto; }
.fx-tr-axis { stroke: var(--wp--preset--color--border); stroke-width: 1; }
.fx-tr-grid { stroke: var(--wp--preset--color--surface-raised); stroke-width: 1; }
.fx-tr-bar { fill: #1F2733; }
.fx-tr-bar.is-flag { fill: var(--wp--preset--color--accent); }
.fx-tr-bracket { stroke: var(--wp--preset--color--accent); stroke-width: 1; }
.fx-tr-flag-label { font-family: var(--wp--preset--font-family--mono); font-size: 11px; letter-spacing: 0.1em; fill: var(--wp--preset--color--accent); }
.fx-tr-axis-label { font-family: var(--wp--preset--font-family--mono); font-size: 10px; letter-spacing: 0.1em; fill: var(--wp--preset--color--muted); }

@media (max-width: 1024px) {
	.fx-rc-split, .fx-trend { grid-template-columns: minmax(0, 1fr); gap: 40px; }
	.fx-rc-cards { grid-template-columns: minmax(0, 1fr); }
}

/* Data sovereignty: pitch beside the environment-boundary diagram. */
.fx-ds-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 56px; align-items: center; }
.fx-ds-title { max-width: 20ch; }
/* See the note on `.fx-rc-copy` above: the eyebrow is excluded so the shared
   kicker treatment is not overridden by the body-copy rule. */
.fx-ds-copy > p:not(.fx-eyebrow) { max-width: 58ch; color: var(--wp--preset--color--muted); font-size: 17px; line-height: 1.65; margin: 22px 0 0; }
.fx-ds-copy > p + p { margin-block-start: 18px; }
.fx-ds-chart svg { display: block; width: 100%; height: auto; }
.fx-ds-boundary { fill: var(--wp--preset--color--base); stroke: var(--wp--preset--color--accent); stroke-width: 1; stroke-dasharray: 6 6; }
.fx-ds-boundary-label { font-family: var(--wp--preset--font-family--mono); font-size: 11px; letter-spacing: 0.14em; fill: var(--wp--preset--color--accent); }
.fx-ds-box { fill: var(--wp--preset--color--surface); stroke: var(--wp--preset--color--border); stroke-width: 1; }
.fx-ds-box-label { font-family: var(--wp--preset--font-family--mono); font-size: 12px; letter-spacing: 0.1em; fill: var(--wp--preset--color--contrast); }
.fx-ds-box-sub { font-family: var(--wp--preset--font-family--mono); font-size: 10px; letter-spacing: 0.12em; fill: var(--wp--preset--color--muted); }
.fx-ds-wire { stroke: var(--wp--preset--color--border); stroke-width: 1; }
.fx-ds-wire.is-dashed { stroke-dasharray: 5 5; }
.fx-ds-cut { stroke: var(--fx-alert); stroke-width: 1.5; }
.fx-ds-outside { fill: var(--wp--preset--color--base); stroke: var(--wp--preset--color--border); stroke-width: 1; stroke-dasharray: 4 4; }
.fx-ds-outside-label { font-family: var(--wp--preset--font-family--mono); font-size: 11px; letter-spacing: 0.1em; fill: var(--wp--preset--color--muted); }
.fx-ds-outside-sub { font-family: var(--wp--preset--font-family--mono); font-size: 10px; letter-spacing: 0.12em; fill: var(--wp--preset--color--muted); }

.fx-net-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }

/* Who uses it: six role cards separated by hairlines. */
.fx-roles-copy .fx-eyebrow { margin-block-end: 12px; }
.fx-roles-title { max-width: 24ch; }
.fx-roles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; margin-block-start: 48px; background: var(--wp--preset--color--border); border: 1px solid var(--wp--preset--color--border); border-radius: var(--wp--custom--radius--md); overflow: hidden; }
/* Non-interactive role tiles: plain divs, so no text-decoration reset and no
   hover lift — a hover state that doesn't navigate is a false affordance. */
.fx-role { padding: 30px 28px; background: var(--wp--preset--color--base); color: var(--wp--preset--color--contrast); }
.fx-role h3 { margin: 0; font-family: var(--wp--preset--font-family--heading); font-size: 19px; line-height: 1.3; font-weight: 600; color: var(--wp--preset--color--contrast); }
.fx-role p { margin: 10px 0 0; color: var(--wp--preset--color--muted); font-size: 15px; line-height: 1.6; }

/* Talk to us: closing action band. The surface background comes from the
   shared flat band rule at the top of this file. */
.fx-talk-title { max-width: 18ch; }
.fx-talk-split { display: grid !important; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 56px; align-items: center !important; }
.fx-talk-split > .wp-block-column { min-width: 0; width: auto; }
.fx-talk-actions { margin-block-start: 28px !important; }

@media (max-width: 1024px) {
	.fx-ds-split, .fx-talk-split { grid-template-columns: minmax(0, 1fr); gap: 40px; }
	.fx-roles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 782px) {
	.fx-roles { grid-template-columns: minmax(0, 1fr); }
}
/* Reach cards sit on the synConnect section, which is base after its band was
   dropped in 1.2.31. A base fill here is invisible against base, so the cards
   take surface and read as the lighter panel — the inverse of the Modules
   event file, which is base on a surface band. */
.fx-net-stat { min-width: 0; padding: 28px; background: var(--wp--preset--color--surface); border: 1px solid var(--wp--preset--color--border); border-radius: var(--wp--custom--radius--md); }
.fx-net-stat-value { color: var(--wp--preset--color--contrast); font-family: var(--wp--preset--font-family--heading); font-size: clamp(2rem, 3vw, 2.125rem); font-weight: 600; letter-spacing: -0.02em; line-height: 1.1; }
.fx-net-stat-label { margin-block-start: 10px; color: var(--wp--preset--color--accent); font-family: var(--wp--preset--font-family--mono); font-size: 11px; letter-spacing: 0.14em; line-height: 1.4; text-transform: uppercase; }
.fx-net-stat p { margin: 12px 0 0; color: var(--wp--preset--color--muted); font-size: 15px; line-height: 1.6; }

@media (max-width: 782px) {
	.wp-block-columns.fx-synconnect-columns { grid-template-columns: minmax(0, 1fr); gap: 32px; }
	.fx-net-stats { grid-template-columns: minmax(0, 1fr); }
}

/**
 * Synops theme CSS.
 * All colors, fonts, and scale tokens come from theme.json presets.
 * No hardcoded brand values in this file.
 */

/* ---------- Base ---------- */

html { -webkit-text-size-adjust: 100%; color-scheme: dark; }

body {
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/* Filled inputs keep the dark surface: browsers otherwise repaint autofill
	fields with a white background and black text. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
	-webkit-box-shadow: 0 0 0 1000px var(--wp--preset--color--surface) inset;
	-webkit-text-fill-color: var(--wp--preset--color--contrast);
	caret-color: var(--wp--preset--color--contrast);
	transition: background-color 9999s ease-out;
}

p { margin-block-end: 1em; }

h1, h2, h3, h4, h5, h6 { margin-block-start: 0; }

/* ---------- Long-form content standard: pages + posts share one rhythm ---------- */

/* H1: tight to the breadcrumb above, clear handoff to the meta/body below. */
.wp-block-post-title { margin-block: 0 12px; }

/* The shared article header prints a date line; pages are timeless, so only
	posts (articles, press releases) show it. */
.page .wp-block-post-date { display: none; }

/* Meta rows: post date, featured image, author line get explicit separation. */
.wp-block-post-date { margin-block-end: 24px; }
.wp-block-post-featured-image { margin-block-end: 48px; }

/* In-body headings: one predictable rhythm on every page and post. Sizes
	are one step below the page headline so the H1 stays dominant, and the
	vertical offsets stay modest. */
.entry-content h2,
.wp-block-post-content h2 {
	font-size: var(--wp--preset--font-size--xxxl);
	margin-block: 1.5rem 0.5rem;
}

.entry-content h3,
.wp-block-post-content h3 {
	font-size: var(--wp--preset--font-size--xxl);
	margin-block: 1.25rem 0.4rem;
}

.entry-content h4,
.wp-block-post-content h4 {
	font-size: var(--wp--preset--font-size--xl);
	margin-block: 1rem 0.4rem;
}

.entry-content h5,
.entry-content h6,
.wp-block-post-content h5,
.wp-block-post-content h6 {
	font-size: var(--wp--preset--font-size--lg);
	margin-block: 1rem 0.4rem;
}

/* Anchored headings land below the fixed header, never underneath it. */
.entry-content [id],
.wp-block-post-content [id] { scroll-margin-top: calc(var(--fx-header-h, 86px) + 24px); }

/* A heading that opens the content carries no top offset. */
.entry-content > :first-child,
.wp-block-post-content > :first-child { margin-block-start: 0; }

/* Tables: token borders, left-aligned cells, readable padding, scrollable
	on phones so wide legal tables never break the column. */
.entry-content .wp-block-table { overflow-x: auto; }

.entry-content .wp-block-table td,
.entry-content .wp-block-table th { padding: 10px 16px; text-align: left; }

.entry-content .wp-block-table thead { border-bottom: 2px solid var(--wp--preset--color--border); }

.entry-content .wp-block-table thead th {
	background: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--contrast);
	font-weight: 600;
}

/* Figures and captions: consistent vertical rhythm, centered caption. */
.entry-content figure { margin-block: 2rem; }

.entry-content figcaption { text-align: center; margin-block-start: 8px; }

.entry-content img { max-width: 100%; height: auto; }

/* Lists: standard indent and item rhythm. */
.entry-content ul,
.entry-content ol { padding-inline-start: 1.5em; }

.entry-content li + li { margin-block-start: 0.4em; }

/* Links inside content: accent (theme.json), steady underline geometry. */
.entry-content a { text-underline-offset: 3px; text-decoration-thickness: 1px; }

/* ---------- Accessibility: skip link + focus ---------- */

.skip-link {
	position: absolute;
	left: -9999px;
	top: 16px;
	z-index: 100000;
	padding: 10px 20px;
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	text-transform: uppercase;
	letter-spacing: 0.12em;
	border-radius: var(--wp--custom--radius--sm);
}

.skip-link:focus {
	left: 16px;
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: 2px;
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* Screen-reader only utility. Only the core class is styled: the theme's own
   .synops-visually-hidden was never used by any pattern, part or shortcode. */
.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* ---------- Motion: reveals (gated rules live at EOF) ---------- */

@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;
	}
}

@media (prefers-reduced-motion: no-preference) {
	html { scroll-behavior: smooth; }
}

/* ---------- Texture underlay (route-line grid, under 4% ink) ---------- */

.has-fx-texture { position: relative; isolation: isolate; }

.has-fx-texture::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: var(--fx-texture);
	background-size: 340px 340px;
	opacity: 0.04;
	pointer-events: none;
}

:root {
	--fx-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='340' height='340' viewBox='0 0 340 340'%3E%3Cpath d='M0 60 H340 M0 140 H340 M0 220 H340 M0 300 H340 M60 0 V340 M140 0 V340 M220 0 V340 M300 0 V340' stroke='%238B95A5' stroke-width='1'/%3E%3C/svg%3E");
	/* Status indicator colors: operational semantics, deliberately outside the brand palette. */
	--fx-ok: #5CBE93;
	--fx-alert: #D9614E;
	--fx-info: #4FBFD0;
}

/* ---------- Photography treatment ---------- */

/* Scrim wrapper: photo sits inside the palette. */

/* Dark duotone for client-side band photos. */

/* Background photo sections need a heavy scrim to hold AA text. */

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

.site-header {
	position: fixed;
	width: 100%;
	top: 0;
	z-index: 100;
	/* Always solid — no transparency, no animation */
	background: color-mix(in srgb, var(--wp--preset--color--base) 88%, transparent);
	-webkit-backdrop-filter: blur(12px);
	backdrop-filter: blur(12px);
	border-bottom: 1px solid var(--wp--preset--color--border);
}

.site-header-inner {
	align-items: center;
	padding-block: 16px;
	gap: 24px;
}

/* Logo: 1.5× bigger than default, 24px left margin */
.site-header .site-logo,
.site-header .custom-logo-link {
	margin-left: 24px;
}

.site-header .site-logo img,
.site-header .custom-logo img {
	max-height: 60px;
	width: auto;
}

/* Nav refinement */
.site-header .wp-block-navigation {
	flex-grow: 1;
	justify-content: flex-end;
	/* Keep the About / Careers / Contact Us group 36px off the right edge. */
	margin-right: 36px;
}

.site-header .wp-block-navigation-item__content {
	color: var(--wp--preset--color--contrast);
}

/* External glyph removed */

/* Header CTA sits tight to the right */
.site-header .wp-block-button { margin: 0; padding: 10px; }

.site-header .wp-block-button__link { white-space: nowrap; }

/* ---------- Mobile navigation (hamburger + full-screen overlay) ----------

   Core only shows the overlay below its 600px breakpoint, so this section is
   scoped to match: a real 44px thumb target for the trigger, full-width
   hairline rows for the items, and an explicitly lit close button pinned to
   the header line (it otherwise inherits core's black overlay text color and
   disappears against the dark panel). */
@media (max-width: 599px) {
	/* Solid header bar on phones. The desktop bar's backdrop-filter makes the
	   header the containing block for position:fixed descendants, which traps
	   the open menu inside the ~64px header strip instead of covering the
	   viewport. Dropping the blur restores the full-screen overlay. */
	.site-header {
		background: var(--wp--preset--color--base);
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
	}

	/* Trigger: 44px square; inset 12px so the icon optically matches the
	   16px logo gutter on the opposite side. */
	.site-header .wp-block-navigation { margin-right: 12px; }

	.wp-block-navigation__responsive-container-open {
		width: 44px;
		height: 44px;
		padding: 10px;
		border-radius: var(--wp--custom--radius--sm);
		color: var(--wp--preset--color--contrast);
		transition: color var(--wp--custom--motion--fast) ease-out;
	}
	.wp-block-navigation__responsive-container-open:hover,
	.wp-block-navigation__responsive-container-open:focus-visible {
		color: var(--wp--preset--color--accent);
	}

	/* Overlay panel: surface tone so the blurred header bar reads on top.
	   !important is required: core paints the default overlay white. The
	   explicit contrast color is equally load-bearing: core sets the open
	   container to #000 at higher specificity, and every item inherits it. */
	.wp-block-navigation__responsive-container.is-menu-open {
		background: var(--wp--preset--color--surface) !important;
		color: var(--wp--preset--color--contrast) !important;
	}

	/* Close: 20px padding centers the 24px X on the ~64px header line and
	   gives it a 64px tap box; explicit color beats core's inherited #000. */
	.wp-block-navigation__responsive-container-close {
		top: 0;
		right: 0;
		padding: 20px;
		color: var(--wp--preset--color--contrast);
		transition: color var(--wp--custom--motion--fast) ease-out;
	}
	.wp-block-navigation__responsive-container-close:hover,
	.wp-block-navigation__responsive-container-close:focus-visible {
		color: var(--wp--preset--color--accent);
	}

	/* Menu body: starts under the real header height, page gutters either side.
	   The :not() bumps specificity above core's own content rules, which
	   otherwise win the padding-top and the item justification. */
	.wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) .wp-block-navigation__responsive-container-content {
		padding: calc(var(--fx-header-h, 86px) + 16px) 20px 40px;
		align-items: stretch;
	}

	/* Items: full-width rows with hairline separators. The 12px right padding
	   is an inline style on each link for desktop spacing — zero it here. */
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item {
		width: 100%;
		padding: 0 !important;
		border-bottom: 1px solid var(--wp--preset--color--border);
	}
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:last-child {
		border-bottom: 0;
	}
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
		width: 100%;
		padding-block: 20px;
	}
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__label {
		font-family: var(--wp--preset--font-family--heading);
		font-size: var(--wp--preset--font-size--xl);
		font-weight: 600;
		letter-spacing: -0.01em;
	}
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:hover,
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:active {
		color: var(--wp--preset--color--accent);
	}
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon { color: var(--wp--preset--color--accent); }
}

/* ---------- Buttons ---------- */

.wp-block-button .wp-block-button__link {
	transition: background-color var(--wp--custom--motion--fast) ease-out,
		color var(--wp--custom--motion--fast) ease-out,
		border-color var(--wp--custom--motion--fast) ease-out;
}

/* ---------- Eyebrow / mono label utility ---------- */

.fx-eyebrow {
	display: flex;
	align-items: center;
	gap: 12px;
	color: var(--wp--preset--color--accent);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	margin-block-end: 24px;
}
/* Accent dash before every eyebrow, matching the hero kicker. */
.fx-eyebrow::before,
.fx-hero-kicker::before {
	content: "";
	display: block;
	flex: none;
	width: 26px;
	height: 1px;
	background: var(--wp--preset--color--accent);
}

/* Mono spec value pairs */

/* ---------- Stats: glass strip overlaid on the hero, single row ---------- */

/* Override the layout container's centered auto margins with higher specificity. */

/* Ensure all stat children are identical height — override WP core wp-block-group defaults */

/* ---------- Service / spec cards ---------- */

.fx-card {
	position: relative;
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: 32px;
	transition: border-color var(--wp--custom--motion--fast) ease-out,
		transform var(--wp--custom--motion--fast) ease-out;
}

.fx-card:hover {
	border-color: var(--wp--preset--color--accent);
	transform: translateY(-1px);
}

/* Services sit beneath the proof section on the tight rhythm. */

/* Icon-free service cards: centered titles. */
#services .fx-card h3 { text-align: center; }

/* Hide any icon left in saved post content until re-saved from the pattern. */

/* ---------- Process timeline ---------- */

/* ---------- Client logos: single-line auto-scrolling marquee ---------- */

/* Viewport window: clips the moving strip. */

/* Full-bleed window: alignfull frees the strip from the section's centered margins,
   then negative margins cancel the remaining content padding so it spans edge to edge. */

/* The strip: two identical logo sets ride one flex row so the -50% loop is seamless. */

/* The duplicated set is presentational only (screen readers hear the logos once). */

/* Logos at 0.8x the 108px height (86.4px); width follows each logo's aspect ratio. */

/* Drift to the right: content enters from the left edge and exits right, so every logo gets shown. */
@keyframes fx-marquee {
	from { transform: translateX(-50%); }
	to   { transform: translateX(0); }
}

/* No motion under reduced-motion preference: fall back to a manually scrollable strip. */

/* Client band: full-width surface + gold wash + hairline, same band treatment as process/CTA. */

/* Break out of the constrained 1240px main so the band spans edge to edge. */

/* Statement sits beside the eyebrow label at 70% ink so the logos stay the focus. */

/* 24px breathing room between the heading row and the logo strip. */

/* ---------- Proof heading + transition-file visual ---------- */

/* Tight rhythm: overrides the default 96/160px .fx-section padding. Slim bottom keeps the services cards close. */

/* No trailing margin: the section padding already supplies the gap below the proof visual. */

/* Nudge the copy down so "Where this fits" sits level with "TRANSITION FILE". */

@keyframes fx-draw { to { stroke-dashoffset: 0; } }
@keyframes fx-row-in { to { opacity: 1; } }
@keyframes fx-ping { 0%, 100% { opacity: 1; } 50% { opacity: 0.2; } }
@keyframes fx-dash { to { stroke-dashoffset: -22; } }
@keyframes fx-taxi { from { transform: translateX(0); } to { transform: translateX(418px); } }

/* ---------- Synops band ---------- */

/* Keep the Synops section edge-to-edge so inner content lands on the 1240px grid. */

/* Synops logo at half size on the text column. */

/* ---------- CTA band ---------- */

/* Synops heading: same technical styling as eyebrows */

/* ---------- Synops product layer ---------- */

/* Status chips and telemetry strips: mono numerals, hairline borders. */
.fx-chip-static {
	display: inline-block;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--sm);
	padding: 10px 16px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--contrast);
	background: transparent;
}

/* Scroll reveal lives in the EOF "Motion" block (gated by html.js). */

/* ---------- Code blocks (static highlight + copy button) ---------- */

.fx-code {
	position: relative;
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: 16px 16px 16px 20px;
	margin-block: 16px;
	overflow: auto;
}
.fx-code pre {
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.6;
	color: var(--wp--preset--color--contrast);
	white-space: pre;
}
.fx-method {
	color: var(--wp--preset--color--accent);
	font-weight: 600;
}
.fx-code-copy {
	position: absolute;
	top: 10px;
	right: 10px;
	background: transparent;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--sm);
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	padding: 4px 10px;
	cursor: pointer;
	transition: border-color var(--wp--custom--motion--fast) ease-out, color var(--wp--custom--motion--fast) ease-out;
}
.fx-code-copy:hover,
.fx-code-copy:focus-visible {
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--accent);
}

/* ---------- Forms ---------- */

.fx-form { display: grid; gap: 24px; }

.fx-field { display: grid; gap: 8px; }

.fx-field label {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--wp--preset--color--muted);
}

.fx-field input,
.fx-field select,
.fx-field textarea {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--sm);
	color: var(--wp--preset--color--contrast);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--sm);
	padding: 12px 16px;
	width: 100%;
	transition: border-color var(--wp--custom--motion--fast) ease-out;
}

.fx-field input:focus-visible,
.fx-field select:focus-visible,
.fx-field textarea:focus-visible {
	border-color: var(--wp--preset--color--accent);
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 1px;
}

/* Honeypot: present in the DOM for bots, never visible to humans and takes
   zero layout space (!important guards against block/editor styles).
   Belt-and-braces: wpautop may inject stray <br>/<p></p> around the form, so
   hide those too. */
.fx-newsletter-form > br,
.fx-newsletter-form > p:empty,
.fx-newsletter-form .fx-hp + br,
.fx-newsletter-form .fx-hp br,
.fx-newsletter-form .fx-consent-label > br,
.fx-newsletter-form .fx-field > p:empty,
.fx-newsletter-form .fx-field > br {
	display: none !important;
	margin: 0 !important;
	padding: 0 !important;
	height: 0 !important;
	line-height: 0 !important;
}
.fx-hp {
	position: absolute !important;
	left: -9999px !important;
	top: auto !important;
	display: block !important;
	width: 1px !important;
	max-width: 1px !important;
	height: 1px !important;
	max-height: 1px !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	overflow: hidden !important;
	clip: rect(0, 0, 0, 0) !important;
	clip-path: inset(50%) !important;
	white-space: nowrap !important;
	font-size: 0 !important;
	line-height: 0 !important;
	opacity: 0 !important;
	pointer-events: none !important;
}
.fx-hp label,
.fx-hp input {
	display: block !important;
	width: 1px !important;
	max-width: 1px !important;
	height: 1px !important;
	max-height: 1px !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	font-size: 0 !important;
	line-height: 0 !important;
	opacity: 0 !important;
}

/* ---------- Jobs ---------- */

/* Job detail spec strip: one minimal row of label/value pairs.
	No box — just the type in an aligned, wrap-ready row. */

/* Hairline between pairs keeps the row scannable without a box. */

/* Application form extras on top of .fx-form base. */

.fx-field input[type="file"] { padding: 10px 16px; }

.fx-field input[type="file"]::file-selector-button {
	background: var(--wp--preset--color--surface-raised);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--sm);
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--sm);
	margin-inline-end: 16px;
	padding: 8px 16px;
}

.fx-consent { grid-template-columns: auto 1fr; }

.fx-consent input {
	accent-color: var(--wp--preset--color--accent);
	height: 18px;
	margin-block-start: 3px;
	width: 18px;
}

.fx-consent label {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--sm);
	letter-spacing: 0;
	text-transform: none;
}

/* Section heading, deliberately smaller than the description's H2s. */

/* WP core gives every .wp-site-blocks child a 24px block-start margin and pads
   the block container by 24px at the bottom. The footer is the last child on
   every template, so both leave a bare strip above and below it. Target the
   footer part directly so the fix holds whatever precedes it — the CTA band,
   main, or a section — rather than only the previous CTA-band case. */
.wp-block-template-part:has(.site-footer) {
	margin-block-start: 0;
}
.wp-site-blocks:has(.site-footer) {
	padding-bottom: 0;
}

/* ---------- Footer ---------- */

.site-footer {
	background: var(--wp--preset--color--surface);
	border-top: 1px solid var(--wp--preset--color--border);
	padding-block: 64px 48px;
}

/* ---------- Responsive ---------- */

@media (max-width: 782px) {
	.site-header .wp-block-button { display: none; }
}

/* ---------- Breadcrumb ---------- */

.fx-breadcrumb {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--wp--preset--color--muted);
	margin-block-end: 48px;
}

.fx-breadcrumb a { color: var(--wp--preset--color--muted); text-decoration: none; }
.fx-breadcrumb a:hover { color: var(--wp--preset--color--accent); text-decoration: underline; }
.fx-breadcrumb [aria-current] { color: var(--wp--preset--color--contrast); }

/* ---------- Footer extras ---------- */

.fx-footer-grid { gap: 48px 64px; }

.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }

.site-footer a { text-decoration: none; }
.site-footer a:hover { text-decoration: underline; color: var(--wp--preset--color--accent); }

.site-footer .wp-block-site-logo img { max-height: 40px; width: auto; }

.site-footer hr.wp-block-separator { margin-block: 48px; opacity: 0.3; }

/* Footer newsletter form: name row + email/consent row.
   NOTE: theme.css (.fx-field label + .fx-field input) styles every label as an
   uppercase grid item and every input as width:100% -- both must be undone
   here or the consent checkbox stretches/misaligns. */
.fx-newsletter-form .fx-name-row { display: flex; gap: 8px; margin-bottom: 8px; }
.fx-newsletter-form .fx-name-row .fx-field { flex: 1 1 0; min-width: 0; }
.fx-newsletter-form .fx-email-row { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
.fx-newsletter-form .fx-email-row > .fx-field { flex: 1 1 0; min-width: 0; }
.fx-newsletter-form .fx-email-row > .fx-consent { margin: 0; }
.fx-newsletter-form .fx-consent { display: block; margin: 0; padding: 0; }
.fx-newsletter-form .fx-consent-label {
	display: flex !important;
	flex-direction: row !important;
	align-items: center !important;
	justify-content: flex-start !important;
	gap: 5px !important;
	margin: 0 !important;
	padding: 0 !important;
	font-family: var(--wp--preset--font-family--body) !important;
	font-size: 10px !important;
	font-weight: 400 !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	color: #8B95A5 !important;
	cursor: pointer;
	line-height: 1.4 !important;
	text-align: left !important;
}
.fx-newsletter-form .fx-consent-label input[type="checkbox"] {
	flex: 0 0 auto !important;
	align-self: center !important;
	width: auto !important;
	min-width: 13px !important;
	height: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	border: revert !important;
	background: revert !important;
	border-radius: revert !important;
	color: revert !important;
	font-family: revert !important;
	font-size: revert !important;
	transition: none !important;
}
.fx-newsletter-form .fx-consent-label span { flex: 1 1 auto; min-width: 0; }
/* Turnstile: interaction-only appearance keeps the Managed widget hidden
   unless Cloudflare decides an interactive checkbox is needed. The wrapper
   collapses to zero height when there is nothing to show. */
.fx-newsletter-form .fx-turnstile { margin: 0 !important; padding: 0 !important; line-height: 0; min-height: 0; }
.fx-newsletter-form .fx-turnstile:empty { display: none !important; }
.fx-newsletter-form .fx-turnstile .cf-turnstile:empty { display: none !important; }
@media (max-width: 420px) {
	.fx-newsletter-form .fx-name-row { flex-direction: column; }
	/* align-items needs !important: the row carries an inline
	   align-items:center (from the shortcode markup) that would otherwise
	   win and leave the stacked email input narrow and centered. */
	.fx-newsletter-form .fx-email-row {
		flex-direction: column;
		align-items: stretch !important;
	}
}

/* ---------- Service detail layout ---------- */

/* ---------- Legal TOC ---------- */

/* ---------- FAQ details ---------- */

.wp-block-details summary {
	cursor: pointer;
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 600;
	font-size: var(--wp--preset--font-size--lg);
}

.wp-block-details summary:hover { color: var(--wp--preset--color--accent); }

.wp-block-details[open] summary { color: var(--wp--preset--color--accent); }

.wp-block-details { margin-block: 16px; transition: border-color var(--wp--custom--motion--fast) ease-out; }
.wp-block-details[open] { border-color: var(--wp--preset--color--accent); }

/* ---------- Checklist (service pages) ---------- */

/* ---------- Form status + submit ---------- */

.fx-form-status {
	border: 1px solid var(--wp--preset--color--accent);
	background: var(--wp--preset--color--accent-dim);
	border-radius: var(--wp--custom--radius--md);
	padding: 16px 20px;
	margin-block-end: 24px;
}

.fx-form-status--success p { color: var(--wp--preset--color--contrast); margin: 0; }
.fx-form-status--error { border-color: var(--wp--preset--color--accent); }
.fx-form-status--error p { color: var(--wp--preset--color--accent); margin: 0; font-family: var(--wp--preset--font-family--mono); font-size: var(--wp--preset--font-size--xs); }

.fx-field-actions button {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
	border: 0;
	border-radius: var(--wp--custom--radius--sm);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	letter-spacing: 0.02em;
	padding: 14px 24px;
	cursor: pointer;
	transition: background-color var(--wp--custom--motion--fast) ease-out;
}

.fx-field-actions button:hover { background: var(--wp--preset--color--accent-deep); }

/* ---------- Careers role cards ---------- */

/* ---------- Spec dl grid ---------- */

/* ---------- Synops graphic ---------- */

/* ---------- Hero copy stack ---------- */

/* Tagline as a technical stamp between copy and CTAs. */

/* Compact buttons: any button link set to the XS font size. */
.wp-block-buttons .wp-block-button__link.has-xs-font-size {
	padding: 10px 18px;
	letter-spacing: 0.06em;
}

/* ---------- Tighter rhythm for sections that follow the hero/stats card ---------- */

/* ---------- Process band: tight 12px rhythm, full-width like CTA band ---------- */

/* Same surface + gold wash + texture + hairline as the CTA band, 12px rhythm. */

/* Break out of the constrained 1240px main so the background spans edge to edge. */

/* Keep the dot fill matched to the band so the timeline line stays masked. */

/* Breathing room inside the tight outer rhythm. */

/* Process heading: keep on one line by allowing the wider column. */

/* ---------- Mobile interface + reader polish ---------- */

/* Phone header: shorter chrome, smaller mark, so content owns the fold.
   (The full-screen menu has its own section near the header styles.) */
@media (max-width: 782px) {
	.site-header-inner { padding-block: 12px; gap: 12px; }
	.site-header .site-logo,
	.site-header .custom-logo-link { margin-left: 16px; }
	.site-header .site-logo img,
	.site-header .custom-logo img { max-height: 40px; }
}

/* Reading view: relaxed long-form rhythm and legible type on phones. */
@media (max-width: 600px) {
	/* Long-form: taller leading and even paragraph spacing. */
	.entry-content,
	.wp-block-post-content { line-height: 1.75; }

	.entry-content p,
	.wp-block-post-content p { margin-block: 1.15em 0; }

	.entry-content li + li,
	.wp-block-post-content li + li { margin-block-start: 0.6em; }

	.entry-content a,
	.wp-block-post-content a { padding-block: 2px; }

	/* Tap targets stay >= 44px tall. */
	.wp-block-button__link,
	.fx-field-actions button { min-height: 44px; }

	/* Hero copy: less sky above the headline, shorter fold. */
	.fx-hero { min-height: 68vh; max-height: 68vh; }

	/* Breadcrumb and meta rows breathe less on small screens. */
	.fx-breadcrumb { margin-block-end: 24px; gap: 6px; }
	.wp-block-post-date,
	.wp-block-post-featured-image { margin-block-end: 24px; }

	/* Wide content keeps its shape by scrolling instead of cramping. */
	.entry-content .wp-block-table { font-size: var(--wp--preset--font-size--xs); }
	.entry-content .wp-block-table td,
	.entry-content .wp-block-table th { padding: 8px 10px; }
	.wp-block-code,
	.wp-block-preformatted,
	pre { overflow-x: auto; max-width: 100%; }
	.wp-block-table,
	.wp-block-group.is-nowrap.is-layout-flex { max-width: 100%; }

	/* Footer: leaner chrome; the two link columns share one half-width row. */
	.site-footer .fx-footer-grid { gap: 32px 20px; }
	.fx-footer-grid > .fx-footer-links { flex-basis: calc(50% - 10px); }
	.site-footer { padding-block: 40px 32px; }
	.site-footer hr.wp-block-separator { margin-block: 32px; }

	/* FAQ rows are taller targets on touch. */
	.wp-block-details summary { padding-block: 8px; }
}

/* Very small phones: never let text butt against the edges. */
@media (max-width: 420px) {
	.site-header-inner { gap: 8px; }
	.entry-content .wp-block-table { font-size: 0.75rem; }
}

/* ---------- Homepage + footer mobile layout ----------

   Sections that live inside main (proof, services, capability splits,
   stats, long-form) get their gutter from main itself; full-bleed bands
   (hero, process, clients, synops, CTA, footer) get their own inset so
   copy never touches or slides behind a screen edge on phones. */

@media (max-width: 781px) {
	/* Global content gutter: every main child inherits this inset. */
	main#fx-content { padding-inline: 24px; }

	/* Hero is full-bleed; give the copy its own inset (the media edge stays
	   flush to the viewport even though main is now padded). */
	main#fx-content .fx-hero {
		margin-inline: calc(50% - 50vw);
		width: 100vw;
	}

	/* Footer is full-bleed; inset the whole grid. */
	.site-footer { padding-inline: 24px; }

	/* Columns stack full-width, but the two link lists share one row
	   (basis = 50% minus half the 24px column gap so the pair fits exactly). */
	.site-footer .fx-footer-grid { gap: 40px 24px; }
	.fx-footer-grid > .wp-block-group { flex-basis: 100%; min-width: 0; }
	.fx-footer-grid > .fx-footer-links { flex-basis: calc(50% - 12px); }

	/* Column interiors use constrained layouts sized for desktop; the
	   generated rules center their children in a 248px box with
	   margin:auto !important, which on phones reads as a phantom left
	   indent. Reset the children so copy sits flush like the subscribe
	   column already does. */
	.fx-footer-grid > .wp-block-group > * {
		max-width: 100% !important;
		margin-left: 0 !important;
		margin-right: 0 !important;
	}

	/* Stats band: rely on the parent gutter and stay centered. */
	

}

@media (max-width: 600px) {
	/* Process timeline: one column so step copy never sits in half-width. */
	

	/* Service cards: keep the padding comfortable rather than boxy. */
	.fx-card { padding: 24px; }

	/* Any wide content may only scroll inside its own box, never the page. */
	.wp-block-columns { min-width: 0; }
}

/* Belt-and-braces: no horizontal page scroll from the marquee, full-bleed
   bands, or wide tables on any viewport. */
body { overflow-x: clip; }
/* ---------- PDF section break: 100px headline bar + export button ---------- */

/* Headline sits on the same center line as the icon inside the 100px bar. */

/* Dark PDF glyph on a light chip; gold on hover. */

/* Printing the whole page (Cmd/Ctrl+P) never shows the export buttons. */

/* ============================================================
   Synops v2 - one layout system, components, motion, restraint
   Appended last so these rules win over the inherited Foxtrot CSS.
   Footer/header/newsletter clone styles above are intentionally untouched.
   ============================================================ */

/* ---------- 1. One layout system ---------- */

.fx-section { padding-block: clamp(36px, 3vw, 56px); }

/* Core puts a 24px block-start margin on every child of a constrained layout
   (`:root :where(.is-layout-constrained) > *`). Between two full-bleed sections
   that opens a 24px strip of the page background — the gap seen between the
   Modules band and "Who uses it". Each section already carries its own padding,
   so the margin is redundant here.
   Scoped to direct `alignfull` children, which is exactly the set of full-bleed
   sections (all 21 template patterns use `alignfull`), so the utility templates
   that put an `h1` or a `wp:query` directly in `main` keep their own spacing.
   The id wins on specificity (1,1,0) vs core (0,1,0) instead of depending on
   stylesheet order.

   Alignfull sections are edge-to-edge bands. Core escapes main's root padding
   with negative margins, so the 24px content gutter is re-applied here to keep
   text at the same inset at every width while backgrounds run to the edge. */
main#fx-content > .alignfull {
	margin-block-start: 0;
	padding-left: var(--wp--style--root--padding-left, 24px);
	padding-right: var(--wp--style--root--padding-right, 24px);
}

/* Left-aligned copy block: prose capped to a 65ch measure, headings run wider. */
.fx-copy { text-align: left; margin-inline: 0; margin-block-end: 32px; }
.fx-copy .fx-eyebrow { margin-block-end: 12px; }
.fx-copy h2, .fx-copy h1 { margin-block-end: 16px; max-width: none; }
.fx-copy p { max-width: 65ch; margin-block-end: 0; }
.fx-copy p + p { margin-block-start: 12px; }

/* ---------- 2. Hero (true full-bleed, real video, scrim over video) ---------- */

.fx-hero {
	position: relative;
	display: flex;
	align-items: center;
	overflow: hidden;
	min-height: clamp(580px, 82vh, 880px);
	max-height: none;
	margin-top: calc(-1 * var(--fx-header-h, 86px) - 24px);
	background: var(--wp--preset--color--base);
	isolation: isolate;
}
main#fx-content .fx-hero {
	margin-inline: calc(50% - 50vw) !important;
	width: 100vw;
	max-width: 100vw;
}
.fx-hero-media { position: absolute; inset: 0; z-index: 0; }
.fx-hero-media video,
.fx-hero-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: saturate(0.82) brightness(0.72) contrast(1.06); }
.fx-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(90deg,
		rgba(10,13,18,0.94) 0%,
		rgba(10,13,18,0.82) 42%,
		rgba(10,13,18,0.42) 72%,
		rgba(10,13,18,0.30) 100%);
}

/* Header clearance for every page whose first section doesn't self-clear.
   Exempt: the split hero carries its own header-aware top padding. */
main#fx-content:not(:has(.fx-hero)):not(:has(.fx-split-hero)) { padding-top: calc(var(--fx-header-h, 80px) + 24px); }

/* ---------- 2b. Split hero (ported from sample-landing-page.html) ---------- */

/* Gold-wash bands. The hero sets the tone and the closing "Talk to us" band
   mirrors it, so the page bookends itself. Flat surface bands are grouped near
   the top of this file. */
.fx-split-hero,
.fx-talk-band {
	background: linear-gradient(180deg, rgba(197, 167, 0, 0.08) 0%, rgba(197, 167, 0, 0.03) 100%), var(--wp--preset--color--surface);
}

.fx-hero-split {
	display: grid;
	grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
	gap: 56px;
	align-items: center;
}
.fx-split-hero .fx-hero-split > * { margin-block: 0; }
.fx-hero-kicker {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 0 0 24px;
	color: var(--wp--preset--color--accent);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 500;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}
.fx-hero-title {
	margin: 0;
	max-width: none;
	font-family: var(--wp--preset--font-family--heading);
	font-size: clamp(2rem, 3.2vw, 2.875rem);
	font-weight: 600;
	line-height: 1.12;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--contrast);
}
.fx-hero-sub {
	margin: 28px 0 0;
	max-width: 56ch;
	color: var(--wp--preset--color--muted);
	font-size: 18px;
	line-height: 1.6;
}
.fx-hero-art svg { display: block; width: 100%; height: auto; }
.fx-hero-board {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	background: var(--wp--preset--color--surface);
	margin-top: 22px;
	overflow: hidden;
}
/* Fleet board lives in the copy column, hugged to its right edge. */
.fx-hero-copy .fx-hero-board {
	width: fit-content;
	margin-left: auto;
}
.fx-board-cell { padding: 14px 16px; border-right: 1px solid var(--wp--preset--color--border); }
.fx-board-cell:last-child { border-right: 0; }
.fx-board-label {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}
.fx-board-value {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 6px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 14px;
	color: var(--wp--preset--color--contrast);
}
.fx-board-dot { display: block; width: 7px; height: 7px; border-radius: 50%; flex: none; }
.fx-board-dot--ok { background: var(--fx-ok); }
.fx-board-dot--mel { background: var(--wp--preset--color--accent); }
.fx-board-dot--aog { background: var(--fx-alert); }

/* Aircraft art: annotation groups ride the shared fx-reveal observer; the halo pulse
   keeps the sample-landing-page timing. */
.fx-halo { animation: fx-halo 2.8s ease-out infinite; transform-box: fill-box; transform-origin: center; }
.fx-halo.fx-d2 { animation-delay: .7s; }
.fx-halo.fx-d3 { animation-delay: 1.4s; }
.fx-halo.fx-d4 { animation-delay: 2.1s; }
@keyframes fx-halo { 0% { transform: scale(.4); opacity: .35; } 70%, 100% { transform: scale(1.7); opacity: 0; } }

@media (max-width: 1080px) {
	.fx-hero-split { grid-template-columns: minmax(0, 1fr); gap: 40px; }
	/* The board reads as one status strip, so it keeps all four cells on a single
	   line at every width where the hero is stacked, rather than reflowing to a
	   2x2 block and then to four tall rows. Type, tracking and padding step down
	   together so the labels never wrap or clip, and the columns are
	   minmax(0,1fr) so they can shrink below their content width. */
	.fx-hero-board { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.fx-hero-copy .fx-hero-board { width: 100%; margin-left: 0; }
	.fx-board-cell {
		padding: 12px 14px;
		border-right: 1px solid var(--wp--preset--color--border);
		border-bottom: 0;
		min-width: 0;
	}
	.fx-board-cell:last-child { border-right: 0; }
	.fx-board-label {
		font-size: 9.5px;
		letter-spacing: 0.05em;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}
	.fx-board-value { font-size: 13px; gap: 6px; margin-top: 4px; white-space: nowrap; }
}

@media (max-width: 720px) {
	.fx-board-cell { padding: 9px 8px; }
	.fx-board-label { font-size: 8.5px; letter-spacing: 0.03em; }
	.fx-board-value { font-size: 12px; gap: 5px; }
	.fx-board-dot { width: 6px; height: 6px; }
}

@media (max-width: 360px) {
	/* At 320px a cell is 68px wide, which ellipsised "Fleet board" and
	   "Serviceable" at the 720px sizes. Padding and tracking come down again so
	   the longest label fits without clipping. */
	.fx-board-cell { padding: 8px 5px; }
	.fx-board-label { font-size: 7.5px; letter-spacing: 0; }
	.fx-board-value { font-size: 11px; gap: 4px; }
	.fx-board-dot { width: 5px; height: 5px; }
}
@media (prefers-reduced-motion: reduce) {
	.fx-halo { animation: none; }
}

/* ---------- 3. Buttons (primary fill + ghost secondary) ---------- */

.wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	line-height: 1.1;
	border: 1px solid transparent;
	padding: 14px 24px;
	transition: background-color var(--wp--custom--motion--fast) ease-out,
		border-color var(--wp--custom--motion--fast) ease-out,
		color var(--wp--custom--motion--fast) ease-out;
}
.wp-block-button.is-style-synops-outline .wp-block-button__link {
	background: transparent;
	border: 1px solid var(--wp--preset--color--border);
	color: var(--wp--preset--color--contrast);
}
.wp-block-button.is-style-synops-outline .wp-block-button__link:hover,
.wp-block-button.is-style-synops-outline .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--accent-dim);
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--accent);
}

/* ---------- 5. Cards (hairline, elevation, mono eyebrow, tight padding) ---------- */

.is-style-spec-card {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: 24px;
	transition: border-color var(--wp--custom--motion--fast) ease-out,
		transform var(--wp--custom--motion--fast) ease-out;
	height: auto;
}
.is-style-spec-card:hover { border-color: var(--wp--preset--color--accent); transform: translateY(-1px); }
.is-style-spec-card .fx-card-eyebrow {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
	margin: 0 0 12px;
}
.is-style-spec-card h3 { margin-block: 0 12px; }
.is-style-spec-card p { margin: 0; }
.is-style-spec-card ul { margin: 0; padding-inline-start: 20px; }
.is-style-spec-card li { margin-block-end: 8px; }

/* The fragmentation-cost cards sit on a surface band, so they take the base
   ground for contrast — the same black-panel-on-surface-band pairing as the
   Modules event file. Scoped to that section: the registered block style is
   (0,2,0) and other sections reuse spec cards on a base ground, where a base
   fill would make them vanish. This rule is (0,3,0) to win regardless of the
   order the block style's inline CSS is printed in. */
.fx-cost-band .wp-block-group.is-style-spec-card {
	background: var(--wp--preset--color--base);
}

/* ---------- 8. Platform and one-record diagrams ---------- */

.fx-diagram {
	position: relative;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	background: var(--wp--preset--color--surface);
	padding: 32px 24px;
	margin-block: 0;
	overflow: hidden;
}
.fx-diagram svg { display: block; width: 100%; height: auto; }
.fx-node { fill: var(--wp--preset--color--surface-raised); stroke: var(--wp--preset--color--border); stroke-width: 1; }
.fx-node-core { fill: var(--wp--preset--color--base); stroke: var(--wp--preset--color--accent); stroke-width: 1; }
.fx-spine { stroke: var(--wp--preset--color--border); stroke-width: 1.5; }
.fx-rail { stroke: var(--wp--preset--color--border); stroke-width: 1; }
.fx-diagram-label { font-family: var(--wp--preset--font-family--mono), ui-monospace, monospace; }
.fx-diagram-label.fx-diagram-label--strong { fill: var(--wp--preset--color--contrast); }
.fx-diagram-label.fx-diagram-label--muted { fill: var(--wp--preset--color--muted); }
.fx-pulse {
	fill: var(--wp--preset--color--accent);
}
.fx-junction {
	fill: var(--wp--preset--color--accent);
	opacity: 0.45;
}

.fx-lifecycle-track {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-block-end: 12px;
	min-height: 28px;
}

/* ---------- 11. Restraint: accent for action only ---------- */

/* Footer links deliberately do NOT get a colour override here: both themes
   define elements.link.color.text as the accent, so they inherit amber and
   match Foxtrot. An earlier `color: muted` rule made them read grey. */
.entry-content a { color: var(--wp--preset--color--contrast); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.entry-content a:hover { color: var(--wp--preset--color--accent); }

/* ---------- 13. Motion: reveal + stagger ---------- */

html.js .fx-reveal {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 450ms ease-out, transform 450ms ease-out;
	transition-delay: var(--fx-delay, 0ms);
	will-change: opacity, transform;
}
html.js .fx-reveal.is-revealed { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
	html.js .fx-reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------- 14. Responsive: one edge on small screens ---------- */

@media (max-width: 600px) {
	.fx-hero { min-height: 68vh; }
}

/* ---------- Platform diagram: node chips, spine, travelling pulse ---------- */

figure.fx-diagram { margin: 0; }
.fx-diagram { container-type: inline-size; }
.fx-spine-cap { fill: var(--wp--preset--color--border); }
.fx-node { fill: var(--wp--preset--color--surface-raised); stroke: var(--wp--preset--color--border); stroke-width: 1; }
.fx-node-core { fill: var(--wp--preset--color--base); stroke: var(--wp--preset--color--accent); stroke-width: 1; }
.fx-pulse-halo { fill: var(--wp--preset--color--accent); opacity: 0.14; }

/* Below ~720px the 1000-unit canvas squeezes the mono labels under 10px.
   Let the frame scroll horizontally instead of shrinking the type. */
@media (max-width: 720px) {
	.fx-diagram { overflow-x: auto; overscroll-behavior-x: contain; padding-inline: 16px; }
	.fx-diagram svg { width: 720px; max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
	.fx-pulse, .fx-pulse-halo { opacity: 0; }
	.fx-junction { opacity: 1 !important; }
}

/* ---------- synConnect network reach: lifecycle rail + radial Type B / AIDX diagram ---------- */

/* Square 520-unit canvas, so it scales without the platform diagram's scroll fallback. */
figure.fx-net { margin: 0; }
.fx-net svg { display: block; width: 100%; height: auto; }

/* Sample timings from sample-landing-page.html: accent radar rings expanding out of the
   hub, a highlight travelling node to node, and lifecycle chips lighting in sequence.
   Same keyframe percentages and delays as the sample; token colors in place of hardcoded
   ones, and the whole set stops under reduced motion. */
.fx-ring {
	stroke: var(--wp--preset--color--accent);
	animation: fx-ring 4.8s ease-out infinite;
	transform-box: view-box;
	transform-origin: 260px 260px;
}
.fx-ring.fx-r2 { animation-delay: 1.6s; }
.fx-ring.fx-r3 { animation-delay: 3.2s; }
@keyframes fx-ring { from { transform: scale(.34); opacity: .5; } to { transform: scale(1); opacity: 0; } }

.fx-nodepulse { animation: fx-node 8s linear infinite; }
.fx-nodepulse.fx-n2 { animation-delay: 1s; }
.fx-nodepulse.fx-n3 { animation-delay: 2s; }
.fx-nodepulse.fx-n4 { animation-delay: 3s; }
.fx-nodepulse.fx-n5 { animation-delay: 4s; }
.fx-nodepulse.fx-n6 { animation-delay: 5s; }
.fx-nodepulse.fx-n7 { animation-delay: 6s; }
.fx-nodepulse.fx-n8 { animation-delay: 7s; }
@keyframes fx-node {
	0%, 10% { stroke: var(--wp--preset--color--accent); }
	22%, 100% { stroke: var(--wp--preset--color--border); }
}

.fx-chip-step { animation: fx-step 7s linear infinite; }
.fx-chip-step--2 { animation-delay: 1.1s; }
.fx-chip-step--3 { animation-delay: 2.2s; }
.fx-chip-step--4 { animation-delay: 3.3s; }
.fx-chip-step--5 { animation-delay: 4.4s; }
@keyframes fx-step {
	0%, 16% { border-color: var(--wp--preset--color--accent); background: var(--wp--preset--color--accent-dim); color: var(--wp--preset--color--contrast); }
	24%, 100% { border-color: var(--wp--preset--color--border); background: transparent; color: var(--wp--preset--color--muted); }
}

@media (prefers-reduced-motion: reduce) {
	/* The rings carry no static opacity, so hold them as one steady boundary ring. */
	.fx-ring { animation: none; opacity: .35; }
	.fx-nodepulse, .fx-chip-step { animation: none; }
}

/* ---------- On-this-page contents rail (template "Page: with on-this-page") ---------- */

/* align-items: flex-start so the sticky rail is not stretched to the height of
   the prose column, which would defeat the sticky positioning. */
.fx-legal-columns { align-items: flex-start; }

.fx-toc { border-left: 1px solid var(--wp--preset--color--border); padding-left: 24px; position: sticky; top: 112px; }

.fx-toc-title {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--wp--preset--color--muted);
	margin-block-end: 16px;
}

.fx-toc ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.fx-toc a { text-decoration: none; color: var(--wp--preset--color--muted); font-size: var(--wp--preset--font-size--sm); }
.fx-toc a:hover { color: var(--wp--preset--color--accent); }

/* H3 entries sit one step in from their parent H2. */
.fx-toc a.fx-toc-sub { padding-left: 12px; font-size: var(--wp--preset--font-size--xs); }

/* Scroll target padding, so a jump to #section-2 is not hidden behind the fixed header. */
.fx-legal-columns :is(h2, h3, h4)[id] { scroll-margin-top: var(--fx-header-h, 96px); }

@media (max-width: 1024px) {
	.fx-toc { position: static; border-left: 0; padding-left: 0; }
	.fx-toc ul { display: flex; flex-wrap: wrap; gap: 8px 24px; }
}

