/*
 * Scoped reset: brings every element inside .thp-snapshot back to plain
 * browser defaults before any widget styling applies, so host theme /
 * Elementor CSS (button resets, global input styling, heading margins, ...)
 * cannot leak in. Everything below builds back up from that baseline using
 * classes only - no bare element selectors (button, select, h3, ...) are
 * used outside this scope, since those lose to theme/Elementor rules that
 * happen to be more specific or load later.
 */
.thp-snapshot,
.thp-snapshot *:not(.thp-snapshot__trial-form *):not(:where(svg *)){
	all: revert;
	box-sizing: border-box;
}

/*
 * The embedded thp-register wizard (inside .thp-snapshot__trial-form) is
 * deliberately EXCLUDED from the reset above. The wizard ships its own
 * defensive reset and is built to stand on a raw theme page; subjecting its
 * subtree to `all: revert` as well re-reverts rules it relies on - most visibly
 * intl-tel-input's `.iti__hide { display:none }`, which `all: revert` clobbered
 * so the whole country list rendered inline and blew out the panel's width and
 * height. Letting the wizard govern its own subtree keeps it "as designed".
 */

/*
 * The `hidden` attribute must always win. Several component rules below set an
 * explicit display (grid/flex) - e.g. .thp-snapshot__unlock-form, __consent,
 * __confirmation, __unlocked. Those are author-origin and so beat the UA
 * [hidden]{display:none} by cascade origin, regardless of specificity, which
 * left elements toggled via the `hidden` attribute (trial form, confirmation,
 * the morphed unlock form, ...) rendering visible all at once. This one guard
 * enforces hidden globally instead of retrofitting :not([hidden]) onto every
 * such rule (error-prone, easy to miss one).
 */
.thp-snapshot [hidden] {
	display: none !important;
}

/*
 * Design tokens from the approved reference mockup (SnapShot.html), scoped
 * under .thp-snapshot instead of :root so they never leak onto the rest of
 * the page, and prefixed thp- (not e.g. --white, --line) so they can't
 * collide with a theme's own generic custom properties of the same name.
 */
.thp-snapshot {
	--thp-navy: #172b52;
	--thp-teal: #0099a7;
	--thp-teal-soft: #dff5f6;
	--thp-coral: #ff6248;
	--thp-ink: #172033;
	--thp-muted: #677287;
	--thp-paper: #f6f8fb;
	--thp-white: #ffffff;
	--thp-line: #dfe5ee;
	--thp-shadow: 0 18px 50px rgba(18, 37, 69, 0.12);

	/* Stroke icons as CSS masks (data-URI SVG), painted with currentColor by the
	 * element using them. Living entirely in CSS they cannot be stripped by the
	 * scoped reset the way SVG presentation attributes are. */
	--thp-i-globe: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='9'/><path d='M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18'/></svg>");
	--thp-i-tag: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M20.6 13.4 13.4 20.6a2 2 0 0 1-2.8 0L3 13V3h10l7.6 7.6a2 2 0 0 1 0 2.8z'/><circle cx='7.5' cy='7.5' r='1.2'/></svg>");
	--thp-i-layers: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m12 3 9 5-9 5-9-5z'/><path d='m3 13 9 5 9-5'/></svg>");
	--thp-i-calendar: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='5' width='18' height='16' rx='2'/><path d='M8 3v4M16 3v4M3 10h18'/></svg>");
	--thp-i-building: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='5' y='3' width='14' height='18' rx='1'/><path d='M9 7h2M13 7h2M9 11h2M13 11h2M10 21v-4h4v4'/></svg>");
	--thp-i-contacts: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='9' cy='8' r='3.5'/><path d='M2.5 20a6.5 6.5 0 0 1 13 0M16 4.5a3.5 3.5 0 0 1 0 7M18 14.5a6.5 6.5 0 0 1 3.5 5.5'/></svg>");
	--thp-i-download: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3v12M7 10l5 5 5-5M4 20h16'/></svg>");
	--thp-i-card-off: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='2' y='5' width='20' height='14' rx='2'/><path d='M2 10h20M3 3l18 18'/></svg>");
	--thp-i-lock: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='10' width='16' height='11' rx='2'/><path d='M8 10V7a4 4 0 0 1 8 0v3'/></svg>");
	--thp-i-star: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black' stroke='black' stroke-width='1.5' stroke-linejoin='round'><path d='m12 3 2.7 5.6 6.1.9-4.4 4.3 1 6.1L12 17l-5.4 2.9 1-6.1L3.2 9.5l6.1-.9z'/></svg>");

	display: grid;
	/*
	 * Three panels, two slots. Stage A shows filters (left) + preview (right);
	 * the swap (JS adds .thp-snapshot--stage-form) switches the named areas to
	 * "preview form". Both layouts use EQUAL columns (1fr 1fr): the preview keeps
	 * the exact same width as it moves from the right slot to the left one, and
	 * the form panel inherits the width the filters had - so the FLIP move is pure
	 * translateX with no width change (no text reflow/scaling), and the embedded
	 * form is no longer the narrower 1fr against the preview's old 1.15fr.
	 */
	grid-template-columns: 1fr 1fr;
	grid-template-areas: "filters preview";
	/*
	 * Section 5a: a measured minimum row height. JS writes the stage-A row height
	 * into --thp-row-min (frozen once the swap starts, cleared on mobile), and the
	 * two panels stretch to at least that in every stage, so stage B/C never
	 * shrink below stage A. grid-template-ROWS (not grid-auto-rows) is used because
	 * the named areas make the panels' row an EXPLICIT track, which grid-auto-rows
	 * does not size; the second (note) row stays auto.
	 */
	grid-template-rows: minmax(var(--thp-row-min, 0px), auto);
	gap: 22px;
	/* stretch (grid's default) makes the two placed panels match the taller
	 * one's height, so Stage B's two panels are equal-height with no JS height
	 * syncing. The container height itself is animated once, by JS, during the
	 * swap; see runDesktopSwap(). */
	align-items: stretch;
	color: var(--thp-ink);
	font-family: inherit;
	position: relative;
}

.thp-snapshot .thp-snapshot__form {
	grid-area: filters;
}

.thp-snapshot .thp-snapshot__preview {
	grid-area: preview;
}

.thp-snapshot .thp-snapshot__form-panel {
	grid-area: form;
}

/* Stage B/C: filters gone, preview on the left, form panel on the right. Equal
 * columns (matching Stage A) keep the swap a pure translateX FLIP. */
.thp-snapshot.thp-snapshot--stage-form {
	grid-template-columns: 1fr 1fr;
	grid-template-areas: "preview form";
}

.thp-snapshot .thp-snapshot__form {
	/* Flex column, top-aligned: the banner/intro top lines up with the right
	 * panel's eyebrow (both panels use 28px top padding); leftover height is
	 * spread between the filter groups by .thp-snapshot__filters below. */
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	padding: clamp(18px, 1.8vw, 24px);
	padding-top: 28px;
	border: 1px solid var(--thp-line);
	border-radius: 20px;
	background: var(--thp-white);
	box-shadow: var(--thp-shadow);
}

/*
 * Left-panel intro copy above the filters. Uses the panel's own tokens - ink
 * for the question, muted for the subcopy - and a restrained heading size so it
 * reads as a panel heading, not the mockup's hero display.
 */
.thp-snapshot .thp-snapshot__intro {
	margin-bottom: 0;
}

/* (0,4,0): above the theme's h2 rules; the old clamp(…, 2.2vw, 2.75rem) here was
 * what inflated the heading to 44px on wide viewports. */
.thp-snapshot.thp-snapshot .thp-snapshot__form .thp-snapshot__intro-title {
	margin: 0 0 6px;
	color: var(--thp-ink);
	font-size: clamp(1.5rem, 2.1vw, 1.85rem);
	font-weight: 800;
	line-height: 1.15;
	text-wrap: balance;
}

.thp-snapshot.thp-snapshot .thp-snapshot__form .thp-snapshot__intro-copy {
	margin: 0 0 18px;
	color: var(--thp-muted);
	font-size: 14px;
	line-height: 1.45;
}

/* The four filter groups: fill the panel's leftover height and distribute it
 * between the groups, so there is no blank band at the top or bottom. */
.thp-snapshot .thp-snapshot__filters {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	justify-content: flex-start;
	gap: 16px;
}

.thp-snapshot .thp-snapshot__filters .thp-snapshot__field {
	margin-bottom: 0;
}

.thp-snapshot .thp-snapshot__field {
	display: grid;
	gap: 7px;
	margin-bottom: 13px;
}

.thp-snapshot .thp-snapshot__label {
	color: var(--thp-muted);
	font-size: clamp(0.72rem, 1vw, 0.85rem);
	font-weight: 700;
}

/*
 * Numbered prefix on each filter label ("1 · Market or region"). The mockup's
 * number+separator pattern, but in this panel's own tokens (teal number, muted
 * separator/label) and the panel's existing sentence-case label copy - not the
 * mockup's gold-on-dark uppercase. The separator is a CSS ::after so the markup
 * stays just the digit.
 */
.thp-snapshot .thp-snapshot__label-num {
	color: var(--thp-teal);
	font-weight: 800;
}

.thp-snapshot .thp-snapshot__label-num::after {
	content: " · ";
	color: var(--thp-muted);
	font-weight: 700;
}

.thp-snapshot .thp-snapshot__select {
	display: block;
	width: 100%;
	box-sizing: border-box;
	min-height: 46px;
	padding: 10px 14px;
	font-size: 15px;
	border: 1px solid #cfd7e3;
	border-radius: 10px;
	color: var(--thp-ink);
	background: var(--thp-white);
	font-family: inherit;
	font-weight: inherit;
	line-height: inherit;
}

/*
 * Grey caption under the Supplier category select, showing the full name of
 * the currently selected short-code option. Uses the same --thp-muted token
 * as the field labels so it reads as supporting copy, not a second control.
 */
.thp-snapshot .thp-snapshot__caption {
	margin: 0;
	color: var(--thp-muted);
	font-size: clamp(0.68rem, 0.9vw, 0.8rem);
	line-height: 1.4;
}

.thp-snapshot .thp-snapshot__pills {
	margin-top: 6px;
}

.thp-snapshot .thp-snapshot__pill {
	display: inline-flex;
	margin: 4px 4px 4px 0;
	padding: 7px 11px;
	/* 8px matches the site's established radius (thp-register's
	 * --input-border-radius and the Unlock button below), so the badges read
	 * as part of the same system rather than fully-rounded pills. The 7x11
	 * padding is kept: at 8px it still reads as a deliberate badge. */
	border-radius: 8px;
	color: #006b74;
	background: var(--thp-teal-soft);
	font-size: 12px;
	/* 600, folded from the site's Additional CSS (was 800). */
	font-weight: 600;
}

/*
 * Project-phase stepper: five independent toggle nodes (role=checkbox) joined by
 * one line whose segments fill between ADJACENT selected nodes, drawn in this
 * widget's own light-panel palette (teal accent, line/muted/navy tokens).
 */
.thp-snapshot .thp-snapshot__phase {
	display: grid;
	gap: 12px;
}

/* Header row: the "3 · Project phase" label on the left, the "All phases" pill
 * on the right. */
.thp-snapshot .thp-snapshot__phase-head {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 10px;
}

/* "All phases" pill: outline by default, teal-soft fill while all five phases
 * are selected (aria-pressed). Rest/hover/focus/active are restated at (0,4,0)+
 * in the interactive-state hardening section. */
.thp-snapshot .thp-snapshot__phase-all {
	flex: 0 0 auto;
	padding: 3px 10px;
	border: 1px solid var(--thp-line);
	border-radius: 8px;
	color: var(--thp-muted);
	background: var(--thp-white);
	font: inherit;
	font-size: 12px;
	font-weight: 700;
	line-height: 1.5;
	cursor: pointer;
}

.thp-snapshot .thp-snapshot__phase-all[aria-pressed="true"] {
	color: #006b74;
	border-color: var(--thp-teal);
	background: var(--thp-teal-soft);
}

.thp-snapshot .thp-snapshot__stepper {
	/* Positioning context for the single track/progress line behind the nodes. */
	position: relative;
	display: flex;
	margin: 0;
	padding: 0;
}

/*
 * ONE continuous line behind all nodes, inset to the first/last node centres:
 * each node is 1/N of the row, so its centre sits 50%/N in from the row edge. The
 * track holds one segment per gap; a segment fills (teal) only when both of its
 * neighbouring nodes are selected. Drawn as their OWN elements - not a ::before on
 * each <button>, which buttons clip.
 */
.thp-snapshot .thp-snapshot__stepper-track {
	position: absolute;
	top: 8px;
	left: calc(50% / var(--thp-step-count, 5));
	right: calc(50% / var(--thp-step-count, 5));
	display: flex;
	height: 2px;
	background: var(--thp-line);
	z-index: 0;
}

.thp-snapshot .thp-snapshot__stepper-seg {
	flex: 1 1 0;
	height: 100%;
	background: transparent;
}

.thp-snapshot .thp-snapshot__stepper-seg.is-filled {
	background: var(--thp-teal);
}

/* One flexible column per node: holds the toggle button and its tooltip. */
.thp-snapshot .thp-snapshot__step {
	position: relative;
	z-index: 1;
	display: flex;
	flex: 1 1 0;
	min-width: 0;
	justify-content: center;
}

.thp-snapshot .thp-snapshot__step.is-open {
	z-index: 5;
}

.thp-snapshot .thp-snapshot__step-btn {
	position: relative;
	display: flex;
	flex: 1 1 auto;
	min-width: 0;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--thp-muted);
	font: inherit;
	font-size: 12px;
	font-weight: 600;
	line-height: 1.25;
	text-align: center;
	cursor: pointer;
}

/* Labels wrap to at most two lines, balanced; a long word may break rather than
 * overlap its neighbour at narrow widths. */
.thp-snapshot .thp-snapshot__step-name {
	display: block;
	max-width: 100%;
	text-wrap: balance;
	overflow-wrap: anywhere;
	hyphens: auto;
}

.thp-snapshot .thp-snapshot__step-dot {
	width: 18px;
	height: 18px;
	border: 2px solid var(--thp-line);
	border-radius: 50%;
	background: var(--thp-white);
	transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

/*
 * Node preview affordance (section 1): a small scale + soft ring on the node's
 * dot on keyboard focus (always) and pointer hover (hover-capable devices only,
 * so a touch tap doesn't stick the preview). Declared at (0,4,0) like the other
 * button states so a host hover rule can't leak in. Selection is unchanged.
 */
.thp-snapshot.thp-snapshot .thp-snapshot__step-btn:focus-visible .thp-snapshot__step-dot {
	transform: scale(1.1);
	box-shadow: 0 0 0 4px rgba(0, 153, 167, 0.25);
}

@media (hover: hover) {
	.thp-snapshot.thp-snapshot .thp-snapshot__step-btn:hover .thp-snapshot__step-dot {
		transform: scale(1.1);
		box-shadow: 0 0 0 4px rgba(0, 153, 167, 0.25);
	}
}

@media (prefers-reduced-motion: reduce) {
	.thp-snapshot .thp-snapshot__step-dot {
		transition: none;
	}
}

/* Selected nodes are independent: filled dot, navy label. */
.thp-snapshot .thp-snapshot__step-btn.is-selected .thp-snapshot__step-dot {
	border-color: var(--thp-teal);
	background: var(--thp-teal);
}

.thp-snapshot .thp-snapshot__step-btn.is-selected {
	color: var(--thp-navy);
}

.thp-snapshot .thp-snapshot__phase-all:focus-visible,
.thp-snapshot .thp-snapshot__step-btn:focus-visible {
	outline: 3px solid rgba(0, 153, 167, 0.35);
	outline-offset: 2px;
}

.thp-snapshot .thp-snapshot__preview {
	position: relative;
	/* Flex column (section 5f) so the "Your selection" filler can sink to the
	 * bottom (margin-top:auto) and the slack pools between the cards and it, never
	 * as a blank band at the panel foot. */
	display: flex;
	flex-direction: column;
	/* Standard pairing for border-radius: without it, a child's
	 * background/box can render past the rounded corners. */
	overflow: hidden;
	min-height: 355px;
	padding: clamp(20px, 2vw, 26px);
	padding-top: 28px;
	border-radius: 20px;
	color: var(--thp-white);
	background: var(--thp-navy);
}

/*
 * "Your selection" filler (section 5c/5f): anchored to the bottom of the preview
 * panel with the leftover space above it. Chips show the four chosen filters.
 */
.thp-snapshot .thp-snapshot__selection {
	/* Hidden through stage A (display:none, so it never inflates the measured
	 * stage-A row height); shown, with a 200ms fade, only from the form stage. */
	display: none;
	margin-top: auto;
	padding-top: 14px;
}

.thp-snapshot.thp-snapshot--stage-form .thp-snapshot__selection,
.thp-snapshot.thp-snapshot--stage-done .thp-snapshot__selection {
	display: block;
	animation: thp-snapshot-fade-in 200ms ease-out;
}

@keyframes thp-snapshot-fade-in {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	.thp-snapshot.thp-snapshot--stage-form .thp-snapshot__selection,
	.thp-snapshot.thp-snapshot--stage-done .thp-snapshot__selection {
		animation: none;
	}
}

.thp-snapshot .thp-snapshot__selection-label {
	display: block;
	margin-bottom: 8px;
	color: rgba(255, 255, 255, 0.6);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.thp-snapshot .thp-snapshot__selection-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.thp-snapshot .thp-snapshot__chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 12px;
	border: 1px solid rgba(255, 255, 255, 0.18);
	border-radius: 8px;
	background: rgba(255, 255, 255, 0.08);
	color: rgba(255, 255, 255, 0.9);
	font-size: 14px;
	line-height: 1.3;
	white-space: nowrap;
}

/* Leading stroke icon per chip, drawn as a CSS mask in the chip's text colour. */
.thp-snapshot.thp-snapshot .thp-snapshot__chip::before {
	content: "";
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	background: currentColor;
	-webkit-mask: var(--thp-i-globe) center / contain no-repeat;
	mask: var(--thp-i-globe) center / contain no-repeat;
}

.thp-snapshot.thp-snapshot .thp-snapshot__chip--category::before {
	-webkit-mask-image: var(--thp-i-tag);
	mask-image: var(--thp-i-tag);
}

.thp-snapshot.thp-snapshot .thp-snapshot__chip--phase::before {
	-webkit-mask-image: var(--thp-i-layers);
	mask-image: var(--thp-i-layers);
}

.thp-snapshot.thp-snapshot .thp-snapshot__chip--timing::before {
	-webkit-mask-image: var(--thp-i-calendar);
	mask-image: var(--thp-i-calendar);
}

/*
 * Loading state: a plain opacity pulse on the preview panel while
 * .thp-snapshot--loading is on the widget root (toggled by snapshot-widget.js
 * around both the preview and unlock fetch() calls). Opacity is
 * compositor-only, so this never triggers layout or repaint.
 */
@keyframes thp-snapshot-pulse {
	0%,
	100% {
		opacity: 1;
	}

	50% {
		opacity: 0.6;
	}
}

.thp-snapshot--loading .thp-snapshot__preview {
	animation: thp-snapshot-pulse 1.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
	.thp-snapshot--loading .thp-snapshot__preview {
		animation: none;
		opacity: 0.8;
	}
}

/*
 * Eyebrow row at the top of the navy preview panel: the static "Your
 * personalised preview" kicker on the left, the green "Updates as you pick"
 * badge aligned to the top-right (roughly on the eyebrow's line).
 */
.thp-snapshot .thp-snapshot__preview-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
}

/* Kicker, back inside the navy panel (so light-on-navy teal), eyebrow-sized. */
.thp-snapshot .thp-snapshot__preview-kicker {
	color: #79d8dd;
	font-size: clamp(0.65rem, 0.9vw, 0.75rem);
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

/*
 * Green "success" variant of the pill badge used for the "Updates as you pick"
 * marker. Reuses the .thp-snapshot__pill shape/size; only the colours change,
 * and the badge drops the pill list's left/right margins.
 */
.thp-snapshot .thp-snapshot__pill--success {
	margin: 0;
	flex: 0 0 auto;
	color: #0b6b3f;
	background: #d6f3e1;
	/* line-height 1, folded from the site's Additional CSS: keeps the success
	 * badge vertically compact against the eyebrow row. */
	line-height: 1;
}

/*
 * Dynamic result headline + count, back inside the navy preview panel (so
 * light-on-navy colours), at the panel-sub-heading size they had before the
 * full-width experiment. JS updates them via their data attributes.
 */
.thp-snapshot .thp-snapshot__heading {
	margin: 12px 0 8px;
	font-size: clamp(1.35rem, 2.25vw, 1.8rem);
	line-height: 1.2;
	text-wrap: balance;
	color: var(--thp-white) !important;
}

.thp-snapshot .thp-snapshot__preview-meta {
	margin: 0;
	color: rgba(255, 255, 255, 0.68);
	font-size: clamp(0.78rem, 1vw, 1rem);
	line-height: 1.5;
}

.thp-snapshot .thp-snapshot__sample {
	/* Padding trimmed 15px -> 12px (~20%) and the top margin 14px -> 10px so
	 * three cards (1 sample + 2 teasers) fit the panel without feeling cramped. */
	margin-top: 10px;
	padding: 12px;
	border: 1px solid rgba(255, 255, 255, 0.15);
	border-radius: 12px;
	background: rgba(255, 255, 255, 0.09);
	font-size: clamp(0.75rem, 1vw, 1rem);
}

.thp-snapshot .thp-snapshot__sample-row {
	display: flex;
	justify-content: space-between;
	gap: 10px;
	margin-top: 6px;
	color: rgba(255, 255, 255, 0.72);
	font-size: clamp(0.68rem, 0.9vw, 0.84rem);
}

.thp-snapshot .thp-snapshot__blurred {
	opacity: 0.65;
	filter: blur(5px);
	user-select: none;
}

/*
 * Unlock reveal: each card slot (the sample + both teasers) is populated with
 * its real project data, armed in a blurred/transparent start state (this
 * class alone, no transition, so it snaps there), then flipped to .is-revealed
 * on the next frame to cross-fade blur-to-sharp. JS sets a per-card
 * transition-delay to stagger the three. See snapshot-widget.js.
 */
.thp-snapshot .thp-snapshot__sample.thp-snapshot__reveal {
	filter: blur(12px);
	opacity: 0;
}

.thp-snapshot .thp-snapshot__sample.thp-snapshot__reveal.is-revealed {
	filter: blur(0);
	opacity: 1;
	transition: filter 0.6s ease, opacity 0.6s ease;
}

@media (prefers-reduced-motion: reduce) {
	.thp-snapshot .thp-snapshot__sample.thp-snapshot__reveal,
	.thp-snapshot .thp-snapshot__sample.thp-snapshot__reveal.is-revealed {
		transition: none;
		filter: none;
		opacity: 1;
	}
}

.thp-snapshot .thp-snapshot__unlock-form {
	margin-top: 15px;
	display: grid;
	gap: 10px;
}

.thp-snapshot .thp-snapshot__email-gate {
	margin: 0;
	color: #9ce1e5;
	font-size: clamp(0.74rem, 1vw, 1rem);
	font-weight: 700;
}

.thp-snapshot .thp-snapshot__input {
	display: block;
	width: 100%;
	padding: 11px 14px;
	border: 1px solid #cfd7e3;
	border-radius: 10px;
	font: inherit;
	color: var(--thp-ink);
	background: var(--thp-white);
}

.thp-snapshot .thp-snapshot__consent {
	display: flex;
	/* Center the checkbox against its label text instead of nudging it with a
	 * manual margin offset, mirroring thp-register's consent rows. */
	align-items: center;
	gap: 8px;
	color: rgba(255, 255, 255, 0.8);
	font-size: 0.78rem;
}

.thp-snapshot .thp-snapshot__checkbox {
	/* Hold the checkbox's intrinsic size so it never shrinks if the label wraps. */
	flex: 0 0 auto;
}

/*
 * Mirrors the site header's "7-Day Free Trial" CTA (Elementor widget 82cdd66,
 * "Gradient Border Button"). Values are copied from production, not
 * approximated: the gradient/border/animation from its inline widget CSS,
 * padding/radius/typography from uploads/elementor/css/post-602.css. If that
 * header button is restyled in Elementor, update this rule to match.
 */
.thp-snapshot .thp-snapshot__button,
.thp-snapshot .thp-snapshot__form-panel .thp-wizard__cta {
	--thp-cta-border: linear-gradient(90deg, #CCE9ED, #FEBE3B, #CCE9ED, #FEBE3B, #CCE9ED, #FEBE3B);
}

.thp-snapshot .thp-snapshot__button {
	display: flex;
	justify-content: center;
	align-items: center;
	position: relative;
	overflow: hidden;
	/* Enlarged beyond the header "7-Day Free Trial" button it mirrors
	 * (0.5rem 1.5rem / 15px) so this reads as the panel's primary CTA. Only
	 * the size changes - gradient, border and animation below are untouched. */
	padding: 0.85rem 2rem;
	border: 2px solid transparent;
	border-radius: 8px;
	color: #ffffff;
	/* Gradient fills are held in custom properties so the interactive-state
	 * hardening block can re-assert the exact same background (the host kit's
	 * `button:focus{background:#fff}` is a shorthand that otherwise wipes the
	 * gradient image) and hover only has to swap the fill colour. */
	--thp-cta-fill: #0090A5;
	background:
		linear-gradient(90deg, var(--thp-cta-fill), var(--thp-cta-fill)) padding-box,
		var(--thp-cta-border) border-box;
	background-size: 450%;
	background-position: 0%;
	font-family: "Roboto", sans-serif;
	font-size: 17px;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-position 0.5s ease, box-shadow 0.2s ease;
	animation: thp-snapshot-cta-gradient 8s ease-in-out infinite;
}

/* The interactive hover/focus/active fill (distinct from the navy panel) and the
 * hover lift + glow are set in the hardening block below (section 3); the old
 * #162D53 hover equalled the #172b52 panel and the button vanished. */

/*
 * Disabled (in flight / rate-limited): dimmed, desaturated and with the
 * border sweep paused, so it reads as intentionally inactive rather than
 * a half-applied gradient.
 */
.thp-snapshot .thp-snapshot__button:disabled {
	opacity: 0.6;
	filter: grayscale(0.5);
	cursor: not-allowed;
	animation-play-state: paused;
}

/* Verbatim copy of the site's `moveBackAndForth` keyframe, renamed to avoid
 * colliding with the theme's own global animation name. */
@keyframes thp-snapshot-cta-gradient {
	0% {
		background-position: 0%;
	}

	50% {
		background-position: 100%;
	}

	100% {
		background-position: 0%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.thp-snapshot .thp-snapshot__button {
		animation: none;
		background-position: 0%;
	}
}

.thp-snapshot .thp-snapshot__error {
	margin: 0;
	color: #ffb4a8;
	font-size: 0.8rem;
}

.thp-snapshot .thp-snapshot__unlocked {
	margin-top: 14px;
	display: grid;
	gap: 10px;
}

/* =========================================================================
 * FREE-TRIAL FORM PANEL (Stage B / Stage C)
 *
 * The white panel that enters on the right during the swap. It reuses the same
 * radius + shadow tokens as the filters card it conceptually replaces, so the
 * two read as one system. A flex column: the relocated upsell copy heads it,
 * then the embedded wizard (or, after submit-success, the confirmation) fills
 * the rest. Because the wizard's own footer sinks its CTA to the bottom
 * (margin-top:auto), any slack in a shorter form pools above the button rather
 * than as a blank band at the panel's foot.
 * ========================================================================= */
.thp-snapshot .thp-snapshot__form-panel {
	display: flex;
	flex-direction: column;
	/* 20-24px white card inset (section 4). This is the only inset the wizard
	 * gets - its own panel padding is zeroed below. */
	padding: clamp(20px, 1.8vw, 24px);
	border: 1px solid var(--thp-line);
	border-radius: 20px;
	background: var(--thp-white);
	box-shadow: var(--thp-shadow);
}

/* Header = the upsell headline + value line, relocated here from the preview. */
.thp-snapshot .thp-snapshot__form-head {
	margin-bottom: 14px;
}

/*
 * The relocated nodes keep their .thp-snapshot__upsell-title/-copy classes
 * (white, for the navy preview panel), so these are nested one level deeper to
 * reach (0,3,0) - above both the upsell rules (0,2,0) and the scoped reset
 * (0,2,0) - and recolour them dark-on-white for the form panel.
 */
.thp-snapshot .thp-snapshot__form-head .thp-snapshot__form-head-title {
	margin: 0 0 4px;
	font-size: clamp(1.35rem, 2vw, 1.7rem);
	font-weight: 800;
	line-height: 1.25;
	color: var(--thp-ink);
	text-wrap: balance;
}

.thp-snapshot.thp-snapshot .thp-snapshot__upsell-copy::before {
	content: "";
	flex: 0 0 auto;
	width: 12px;
	height: 12px;
	background: currentColor;
	-webkit-mask: var(--thp-i-star) center / contain no-repeat;
	mask: var(--thp-i-star) center / contain no-repeat;
}

/* Natural height (section 5e): the slack goes between the form and the benefits
 * list (which is anchored to the panel bottom), never inside the form. */
.thp-snapshot .thp-snapshot__trial-form {
	display: flex;
	flex-direction: column;
	flex: 0 0 auto;
	min-height: 0;
}

/*
 * Wizard neutralisation. The wizard must render as plain content on snapshot's
 * white card, not as its own floating card: drop its shell shadow, radius, max
 * width, min-height (560px) and auto-centering so the form-panel padding is the
 * only chrome. This folds the site's unscoped Additional CSS
 * `.thp-wizard{border-radius:0}` - re-scoped under .thp-snapshot so the
 * standalone wizard elsewhere on the site is untouched.
 *
 * The CTA colour is no longer set here: thp-register's shortcode now honours
 * accent_color / accent_hover_color (emitted as an id-scoped
 * `#thp-wizard-N{--thp-wz-orange;--thp-wz-orange-dark}`, specificity 1,0,0), and
 * the snapshot shortcode passes accent_color="#0090A5" accent_hover_color="#162D53".
 * The former snapshot var override was redundant (the id rule outranks it) and
 * has been removed — verified #0090A5 / #162D53 (normal/hover) with it gone.
 *
 * The neutralisation below needs no !important: each descends from
 * `.thp-snapshot .thp-snapshot__trial-form ...` (>= 0,3,0), which outranks the
 * wizard's own `.thp-wizard` token block (0,1,0). Verified against computed styles.
 */
.thp-snapshot .thp-snapshot__trial-form .thp-wizard {
	min-height: 0;
	max-width: none;
	margin: 0;
	border-radius: 0;
	box-shadow: none;
	background: transparent;
}

.thp-snapshot .thp-snapshot__trial-form .thp-wizard,
.thp-snapshot .thp-snapshot__trial-form .thp-wizard__panel {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
}

/* Wizard panel padding -> 0 (folds the site's Additional CSS; the form panel
 * owns the inset). No !important: (0,3,0) beats the wizard's (0,1,0). */
.thp-snapshot .thp-snapshot__trial-form .thp-wizard__panel {
	padding: 0;
}

/* Hide the wizard's own "Create your access" step TITLE - the form header
 * carries the headline. It is an <h2>, which the wizard reverts via
 * `.thp-wizard.thp-wizard[data-thp-wizard] h2 { all: revert }` (0,3,1), so
 * !important is required to beat that revert (confirmed: without it display
 * computes to `block`).
 *
 * The step SUBTITLE ("Use your work email…") is intentionally NOT hidden any
 * more: the updated wizard reverts <p> at (0,5,1), which overrode snapshot's
 * old (0,3,0) display:none anyway, and the parity pass treats a hidden subtitle
 * as a non-allowed difference from the standalone render. It now shows in both. */
.thp-snapshot .thp-snapshot__trial-form .thp-wizard__step-title {
	display: none !important;
}

/* Section 6: re-hide the step SUBTITLE. The updated wizard reverts <p> at (0,5,1)
 * AND re-declares the subtitle at (0,6,0), so this doubles .thp-snapshot and
 * triples .thp-wizard to reach (0,7,0) and win on specificity - no !important. */
.thp-snapshot.thp-snapshot .thp-snapshot__trial-form .thp-wizard.thp-wizard.thp-wizard .thp-wizard__step-subtitle {
	display: none;
}

/* Uniform field spacing comes from the form's 12px gap (section 5e); zero the
 * per-field margin so gaps don't compound. */
.thp-snapshot .thp-snapshot__trial-form .thp-wizard__field {
	margin-bottom: 0;
}

/* Hide the helper line under the phone field (section 4). */
.thp-snapshot .thp-snapshot__trial-form .thp-wizard__hint {
	display: none;
}

/* single_form has no Back link, so the footer holds an empty <span> beside the
 * button - collapse that flex row and stretch the submit button full width. */
.thp-snapshot .thp-snapshot__trial-form .thp-wizard__footer {
	display: block;
	/* Neutralise the wizard's own margin-top:auto so it doesn't split the free
	 * space with the phone field's margin-bottom:auto; all slack pools in the one
	 * gap above the consent block (section 2d), keeping consent + submit flush. */
	/* 20px above the submit: the form's 12px gap, less the terms row's -2px, plus
	 * this 10px. */
	margin-top: 10px;
	padding-top: 0;
}

.thp-snapshot .thp-snapshot__trial-form .thp-wizard__footer > span:empty {
	display: none;
}

/* Full-width submit, keyed on the wizard's stable layout hook (data-mode) rather
 * than snapshot's wrapper class, so it holds if the embed container is renamed.
 * (0,4,0) — width:100% is uncontested by the wizard's own cta rule. */
.thp-snapshot .thp-wizard[data-mode="single_form"] .thp-wizard__cta {
	width: 100%;
}

/*
 * Trial submit: same technique as the Unlock CTA, applied directly on the button
 * (no pseudo-elements): 2px transparent border, fill on padding-box and the
 * animated --thp-cta-border gradient on border-box, so the ring follows the 8px
 * corners by construction. Specificity (0,6,0) rest / (0,7,0) states beats the
 * wizard's cta (0,4,0) and :hover/:disabled (0,5,0). No !important. Every state
 * restates both background layers + border so nothing wipes the gradient.
 * The wizard card's own `overflow:hidden` (thp-register) is switched to
 * `overflow:clip` + 10px clip margin below so the glow is not cut off.
 */
.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__cta {
	--thp-cta-fill: #0090A5;
	position: relative;
	min-height: 52px;
	padding: 13px 26px;
	border: 2px solid transparent;
	border-radius: 8px;
	color: #ffffff;
	background:
		linear-gradient(90deg, var(--thp-cta-fill), var(--thp-cta-fill)) padding-box,
		var(--thp-cta-border) border-box;
	background-size: 450%;
	background-position: 0%;
	font-size: 15px;
	font-weight: 700;
	text-transform: uppercase;
	box-shadow: 0 0 0 0 rgba(0, 144, 165, 0.35);
	transition: background-position 0.5s ease, box-shadow 0.2s ease;
	animation:
		thp-snapshot-cta-gradient 8s ease-in-out infinite,
		thp-snapshot-cta-glow 2.4s ease-out 3;
}

/* Glow off while the user is working in the panel; the border sweep keeps running. */
.thp-snapshot.thp-snapshot .thp-snapshot__form-panel:focus-within .thp-wizard[data-thp-wizard] .thp-wizard__cta {
	animation: thp-snapshot-cta-gradient 8s ease-in-out infinite;
}

/* Hover / focus / active: darker fill, static glow, same box model (no jump). */
.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__cta:is(:hover, :focus, :active, :focus-visible):not(:disabled) {
	--thp-cta-fill: #00788A;
	border: 2px solid transparent;
	border-radius: 8px;
	padding: 13px 26px;
	color: #ffffff;
	background:
		linear-gradient(90deg, var(--thp-cta-fill), var(--thp-cta-fill)) padding-box,
		var(--thp-cta-border) border-box;
	background-size: 450%;
	box-shadow: 0 0 0 4px rgba(0, 144, 165, 0.3);
	animation: thp-snapshot-cta-gradient 8s ease-in-out infinite;
	transform: none;
}

.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__cta:focus-visible:not(:disabled) {
	outline: 2px solid var(--thp-white);
	outline-offset: 2px;
}

.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__cta:disabled {
	--thp-cta-fill: #0090A5;
	border: 2px solid transparent;
	border-radius: 8px;
	padding: 13px 26px;
	color: #ffffff;
	background:
		linear-gradient(90deg, var(--thp-cta-fill), var(--thp-cta-fill)) padding-box,
		var(--thp-cta-border) border-box;
	background-size: 450%;
	box-shadow: none;
	opacity: 0.6;
	filter: grayscale(0.5);
	cursor: not-allowed;
	animation: thp-snapshot-cta-gradient 8s ease-in-out infinite paused;
}

/* Clipping: the wizard card (.thp-wizard) is overflow:hidden for its own rounded
 * shell, which snapshot neutralises (radius 0). `clip` + a 10px margin keeps the
 * layout clip but lets the 8px glow paint past the box. */
.thp-snapshot .thp-snapshot__trial-form .thp-wizard {
	overflow: clip;
	overflow-clip-margin: 10px;
}

/* 8px footer padding so the glow sits inside the footer box; negative margins
 * cancel it so the layout does not move. */
.thp-snapshot .thp-snapshot__trial-form .thp-wizard__footer {
	padding: 8px;
	margin: 2px -8px -8px;
}

@keyframes thp-snapshot-cta-glow {
	from {
		box-shadow: 0 0 0 0 rgba(0, 144, 165, 0.35);
	}

	to {
		box-shadow: 0 0 0 8px rgba(0, 144, 165, 0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__cta,
	.thp-snapshot.thp-snapshot .thp-snapshot__form-panel:focus-within .thp-wizard[data-thp-wizard] .thp-wizard__cta,
	.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__cta:is(:hover, :focus, :active, :focus-visible):not(:disabled),
	.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__cta:disabled {
		animation: none;
	}
}

/*
 * Section 5e: uniform 12px rhythm between inputs, consent rows and submit. The
 * form is a flex column with a single gap; no per-field margins and no auto
 * distribution inside it (slack lives between the form and the benefits list).
 * The consent block therefore sits a clean 12px off the phone field.
 */
.thp-snapshot .thp-wizard[data-mode="single_form"] [data-thp-details-form] {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

/*
 * Consent rows: 10px between the two rows (the hidden terms-error slot between
 * them still adds one 12px flex gap, so the terms row pulls back 2px and the
 * wizard's 8px row margin is zeroed). (0,7,0) beats the wizard's (0,6,0).
 */
.thp-snapshot.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__consent {
	margin: 0;
}

.thp-snapshot.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__consent[data-thp-terms-row] {
	margin-bottom: -2px;
}

/*
 * Legal links in the consent rows: #00788A (5.18:1 on #fff), no underline at
 * rest, underline on hover/focus-visible. (0,7,1) beats the wizard's own link
 * rule (0,5,1); hover/focus restate colour + decoration because the rest rule
 * would otherwise outrank the wizard's (0,6,1) hover rule.
 */
.thp-snapshot.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__consent a {
	color: #00788a;
	text-decoration: none;
}

.thp-snapshot.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__consent a:hover,
.thp-snapshot.thp-snapshot.thp-snapshot .thp-snapshot__form-panel .thp-wizard[data-thp-wizard] .thp-wizard__consent a:focus-visible {
	color: #00788a;
	text-decoration: underline;
}

/*
 * Benefits filler (section 5d): a check-marked list directly under the submit
 * button (14px). Not bottom-anchored: leftover panel height stays as white space
 * below the tiles.
 */
.thp-snapshot.thp-snapshot .thp-snapshot__benefits {
	/* Compact 2x2 block, never stretched. */
	flex: 0 0 auto;
	margin-top: 18px;
	display: grid;
	grid-template-columns: 1fr 1fr;
	grid-auto-rows: auto;
	align-content: start;
	gap: 8px;
	margin-right: 0;
	margin-bottom: 0;
	margin-left: 0;
	padding: 0;
	list-style: none;
}

.thp-snapshot.thp-snapshot .thp-snapshot__benefit {
	display: flex;
	align-items: center;
	gap: 10px;
	min-width: 0;
	min-height: 48px;
	padding: 8px 12px;
	border: 1px solid var(--thp-line);
	border-radius: 10px;
	background: #f6f8fb;
	color: var(--thp-ink);
}

.thp-snapshot.thp-snapshot .thp-snapshot__benefit-icon {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	background: var(--thp-teal-soft);
	color: var(--thp-teal);
}

/* Glyph drawn as a CSS mask (the scoped reset strips SVG presentation attrs). */
.thp-snapshot.thp-snapshot .thp-snapshot__benefit-icon::before {
	content: "";
	width: 14px;
	height: 14px;
	background: currentColor;
	-webkit-mask: var(--thp-i-building) center / contain no-repeat;
	mask: var(--thp-i-building) center / contain no-repeat;
}

.thp-snapshot.thp-snapshot .thp-snapshot__benefit-icon--calendar::before {
	-webkit-mask-image: var(--thp-i-calendar);
	mask-image: var(--thp-i-calendar);
}

.thp-snapshot.thp-snapshot .thp-snapshot__benefit-icon--contacts::before {
	-webkit-mask-image: var(--thp-i-contacts);
	mask-image: var(--thp-i-contacts);
}

.thp-snapshot.thp-snapshot .thp-snapshot__benefit-icon--download::before {
	-webkit-mask-image: var(--thp-i-download);
	mask-image: var(--thp-i-download);
}

.thp-snapshot.thp-snapshot .thp-snapshot__benefit-icon--card-off::before {
	-webkit-mask-image: var(--thp-i-card-off);
	mask-image: var(--thp-i-card-off);
}

.thp-snapshot.thp-snapshot .thp-snapshot__benefit-icon--layers::before {
	-webkit-mask-image: var(--thp-i-layers);
	mask-image: var(--thp-i-layers);
}

/* =========================================================================
 * VARIANT: minimal ([thp_project_snapshot variant="minimal"])
 *
 * Headline + wizard + submit only. No benefit tiles (incl. "Free for 7 days")
 * and no navy-block badge; the form block is vertically centred in its (equal-height) panel so
 * extra height reads as whitespace, not filler. "Your selection" stays but
 * quieter. Declared at (0,4,0)+ after the rich rules so it wins on order too.
 * ========================================================================= */
.thp-snapshot.thp-snapshot.thp-snapshot--minimal .thp-snapshot__benefits,
.thp-snapshot.thp-snapshot.thp-snapshot--minimal .thp-snapshot__upsell-copy {
	display: none;
}

.thp-snapshot.thp-snapshot.thp-snapshot--minimal .thp-snapshot__form-panel {
	justify-content: center;
	gap: 16px;
}

.thp-snapshot.thp-snapshot.thp-snapshot--minimal .thp-snapshot__form-head {
	margin-bottom: 0;
}

.thp-snapshot.thp-snapshot.thp-snapshot--minimal .thp-snapshot__chip {
	padding: 4px 10px;
	border: 0;
	font-size: 12px;
}

.thp-snapshot.thp-snapshot.thp-snapshot--minimal .thp-snapshot__chip::before {
	display: none;
}

.thp-snapshot .thp-snapshot__benefit-body {
	display: grid;
	gap: 2px;
	min-width: 0;
}

.thp-snapshot.thp-snapshot .thp-snapshot__benefit-title {
	font-size: 12.5px;
	font-weight: 600;
	line-height: 1.25;
}

/* Below 400px the tiles go single column (2 columns down to 400px). */
@media (max-width: 400px) {
	.thp-snapshot.thp-snapshot .thp-snapshot__benefits {
		grid-template-columns: 1fr;
	}
}

/* After submit-success the confirmation carries the panel; hide the benefits. */
.thp-snapshot.thp-snapshot--stage-done .thp-snapshot__benefits {
	display: none;
}

/* Confirmation (Stage C), restyled dark-on-white for the form panel (it used to
 * live light-on-navy inside the preview panel). */
.thp-snapshot .thp-snapshot__confirmation {
	display: grid;
	gap: 6px;
	color: var(--thp-muted);
	font-size: clamp(0.82rem, 1vw, 0.95rem);
	line-height: 1.5;
}

.thp-snapshot .thp-snapshot__confirmation strong {
	color: var(--thp-ink);
	font-size: clamp(1rem, 1.3vw, 1.2rem);
}

/* =========================================================================
 * LOCKED FILTERS STATE (section 6)
 *
 * Once projects are unlocked the filter set is fixed. Instead of dimming the
 * whole panel (opacity .6, which hurt legibility), the intro is swapped for a
 * success banner (JS) and the controls are kept fully legible but inert.
 * ========================================================================= */

/* Success banner that replaces the intro. Teal-soft card, check in a teal
 * circle, natural height (the --thp-row-min lock already holds the row height). */
.thp-snapshot .thp-snapshot__locked-banner {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-bottom: 16px;
	padding: 14px 16px;
	border-radius: 12px;
	background: var(--thp-teal-soft);
}

.thp-snapshot .thp-snapshot__locked-icon {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	color: var(--thp-white);
	background: var(--thp-teal);
}

/* The scoped reset's `all: revert` reaches this SVG and its <rect>/<path>/<g>:
 * it drops the width/height/stroke/fill attributes (the svg then collapses or
 * falls back to its default size, and the shapes fill black / lose their
 * stroke), leaving the circle empty. Size and stroke are therefore set here, at
 * (0,4,0), above the reset. */
.thp-snapshot.thp-snapshot .thp-snapshot__locked-icon svg {
	display: block;
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	overflow: visible;
}

.thp-snapshot.thp-snapshot .thp-snapshot__locked-icon svg,
.thp-snapshot.thp-snapshot .thp-snapshot__locked-icon svg * {
	stroke: currentColor;
	fill: none;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/*
 * The open padlock's shackle rests lifted (translateY(-2px) + rotate(-18deg)
 * about its right foot). (0,3,0) beats the reset's `all: revert` on the <g>,
 * which would clear the transform.
 */
.thp-snapshot.thp-snapshot .thp-snapshot__locked-icon .thp-snapshot__locked-shackle {
	transform-box: fill-box;
	transform-origin: right bottom;
	transform: translateY(-2px) rotate(-18deg);
}

/*
 * One-time unlock sequence, driven by .thp-snapshot--just-unlocked (added by JS
 * on unlock success, removed after the last animationend / 1200ms, never re-added):
 *   banner fade+rise 0-250ms, icon pop 80-480ms, shackle lift 280-730ms,
 *   ring pulse 300-1000ms, locked controls ease their colours over 300ms.
 * The card blur-reveal (100ms+) is the existing transition, driven from JS.
 */
.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__locked-banner {
	animation: thp-snapshot-banner-in 250ms ease-out both;
}

.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__locked-icon {
	animation:
		thp-snapshot-icon-pop 400ms cubic-bezier(0.34, 1.56, 0.64, 1) 80ms both,
		thp-snapshot-ring-pulse 700ms ease-out 300ms backwards;
}

.thp-snapshot.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__locked-icon .thp-snapshot__locked-shackle {
	animation: thp-snapshot-shackle-lift 450ms ease-out 280ms backwards;
}

.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__form--locked .thp-snapshot__select,
.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__form--locked .thp-snapshot__input {
	transition: background-color 300ms ease, color 300ms ease, -webkit-text-fill-color 300ms ease, border-color 300ms ease;
}

.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__form--locked .thp-snapshot__step-btn,
.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__form--locked .thp-snapshot__step-dot,
.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__form--locked .thp-snapshot__label {
	transition: background-color 300ms ease, color 300ms ease, border-color 300ms ease, opacity 300ms ease;
}

@keyframes thp-snapshot-banner-in {
	from {
		opacity: 0;
		transform: translateY(-8px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes thp-snapshot-icon-pop {
	0% {
		transform: scale(0.6);
	}
	60% {
		transform: scale(1.08);
	}
	100% {
		transform: scale(1);
	}
}

@keyframes thp-snapshot-ring-pulse {
	from {
		box-shadow: 0 0 0 0 rgba(0, 153, 167, 0.45);
	}
	to {
		box-shadow: 0 0 0 14px transparent;
	}
}

@keyframes thp-snapshot-shackle-lift {
	from {
		transform: translateY(0) rotate(0deg);
	}
	to {
		transform: translateY(-2px) rotate(-18deg);
	}
}

@media (prefers-reduced-motion: reduce) {
	.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__locked-banner,
	.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__locked-icon,
	.thp-snapshot.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__locked-icon .thp-snapshot__locked-shackle {
		animation: none;
	}

	.thp-snapshot.thp-snapshot--just-unlocked .thp-snapshot__form--locked * {
		transition: none;
	}
}

.thp-snapshot .thp-snapshot__locked-text {
	display: grid;
	gap: 2px;
	min-width: 0;
}

.thp-snapshot .thp-snapshot__locked-title {
	color: #075f68;
	font-size: 18px;
	font-weight: 800;
	line-height: 1.2;
}

.thp-snapshot .thp-snapshot__locked-sub {
	color: #0a6b74;
	font-size: 13px;
	line-height: 1.4;
}

/* Controls stay fully legible (no panel dim): paper fill, real text colour even
 * when disabled, not-allowed cursor. */
.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__select:disabled,
.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__input:disabled {
	opacity: 1;
	color: var(--thp-ink);
	-webkit-text-fill-color: var(--thp-ink);
	background: var(--thp-paper);
	border: 1px solid #cfd7e3;
	cursor: not-allowed;
}

.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__label {
	color: var(--thp-muted);
}

/* Lock affordance (no overlay): selects swap the chevron for a lock icon on the
 * right, the phase label gets a small lock after it, and the whole group shows
 * not-allowed. Values stay fully legible. */
.thp-snapshot.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__select:disabled {
	-webkit-appearance: none;
	appearance: none;
	padding-right: 40px;
	background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23677287' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='10' width='16' height='11' rx='2'/><path d='M8 10V7a4 4 0 0 1 8 0v3'/></svg>");
	background-repeat: no-repeat;
	background-position: right 14px center;
	background-size: 16px 16px;
}

.thp-snapshot.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__phase-head .thp-snapshot__label::after {
	content: "";
	display: inline-block;
	width: 12px;
	height: 12px;
	margin-left: 6px;
	vertical-align: -1px;
	background: currentColor;
	-webkit-mask: var(--thp-i-lock) center / contain no-repeat;
	mask: var(--thp-i-lock) center / contain no-repeat;
}

.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__field {
	cursor: not-allowed;
}

/* The stepper keeps the selected nodes and the filled segments at full strength;
 * the track and the unselected dots drop to .7. Labels are never faded (muted ink
 * on white is >= 4.5:1; opacity would break that), and the track is dimmed via its
 * colour rather than opacity so the filled segments stay at 100%. */
.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__step-btn {
	cursor: not-allowed;
}

.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__stepper-track {
	background: rgba(223, 229, 238, 0.7);
}

.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__step-btn:not(.is-selected) .thp-snapshot__step-dot {
	opacity: 0.7;
}

.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__phase-all,
.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__step-btn {
	cursor: not-allowed;
}

/* Section 6c: the "No registration / Just your email" pills are stale once
 * unlocked, so hide them in the locked state. */
.thp-snapshot .thp-snapshot__form--locked .thp-snapshot__pills {
	display: none;
}

/* =========================================================================
 * TOAST NOTIFICATIONS (section 5)
 *
 * One at a time, fixed bottom-centre. The layer is a widget child so the scoped
 * reset shields it from theme button/link rules; position:fixed still anchors to
 * the viewport because the root is not a transformed containing block.
 * ========================================================================= */
.thp-snapshot .thp-snapshot__toast-layer {
	position: fixed;
	left: 50%;
	bottom: 24px;
	transform: translateX(-50%);
	z-index: 100000;
	width: min(92vw, 420px);
	pointer-events: none;
}

.thp-snapshot .thp-snapshot__toast {
	position: relative;
	display: flex;
	align-items: flex-start;
	gap: 10px;
	padding: 12px 14px 12px 18px;
	border-radius: 12px;
	color: var(--thp-white);
	background: var(--thp-navy);
	box-shadow: 0 12px 34px rgba(18, 37, 69, 0.3);
	font-size: 0.9rem;
	line-height: 1.4;
	pointer-events: auto;
	overflow: hidden;
	transition: opacity 0.2s ease, transform 0.2s ease;
}

/* Coral accent bar down the leading edge. */
.thp-snapshot .thp-snapshot__toast::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 4px;
	background: var(--thp-coral);
}

.thp-snapshot .thp-snapshot__toast-msg {
	flex: 1 1 auto;
}

.thp-snapshot .thp-snapshot__toast-close {
	flex: 0 0 auto;
	margin: -2px -2px 0 0;
	padding: 0 4px;
	border: 0;
	border-radius: 4px;
	background: transparent;
	color: rgba(255, 255, 255, 0.8);
	font-size: 18px;
	line-height: 1.2;
	cursor: pointer;
}

/* Keep the close affordance clean under the host theme's button rules. */
.thp-snapshot.thp-snapshot .thp-snapshot__toast-close:is(:hover, :focus, :active, :focus-visible) {
	background: transparent;
	box-shadow: none;
	border-radius: 4px;
	padding: 0 4px;
	color: var(--thp-white);
	outline: none;
	transform: none;
}

.thp-snapshot.thp-snapshot .thp-snapshot__toast-close:focus-visible {
	outline: 2px solid var(--thp-white);
	outline-offset: 2px;
}

/* Enter/leave: slide up + fade. */
.thp-snapshot .thp-snapshot__toast.is-entering,
.thp-snapshot .thp-snapshot__toast.is-leaving {
	opacity: 0;
	transform: translateY(12px);
}

@media (prefers-reduced-motion: reduce) {
	.thp-snapshot .thp-snapshot__toast {
		transition: none;
	}
}

/* Visually-hidden polite live region (unlock + swap announcements). */
.thp-snapshot .thp-snapshot__live {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
}

/*
 * Upsell block shown when the unlock form morphs into the free-trial CTA. Its
 * own subtle card (border + faint fill, separated from the 3 project cards
 * above) plus a larger CTA so it reads as a distinct, important next step
 * rather than a trailing footnote. PLACEHOLDER copy - see snapshot-widget.js.
 */
.thp-snapshot .thp-snapshot__unlock-form--upsell {
	margin-top: 18px;
	padding: 16px;
	border: 1px solid rgba(255, 255, 255, 0.15);
	border-radius: 12px;
	background: rgba(255, 255, 255, 0.06);
}

/* Title left, "Free for 7 days" badge right, one centred row. */
.thp-snapshot .thp-snapshot__upsell {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}

.thp-snapshot .thp-snapshot__upsell-title {
	flex: 1 1 auto;
	min-width: 0;
	margin: 0;
	color: var(--thp-white);
	font-size: 22px;
	font-weight: 800;
	line-height: 1.25;
}

/* Dark-panel marketing badge (the light variant is .thp-snapshot__form-head-copy). */
.thp-snapshot .thp-snapshot__upsell-copy {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 6px;
	width: fit-content;
	margin: 0;
	padding: 4px 10px;
	border-radius: 8px;
	background: rgba(0, 144, 165, 0.25);
	color: #79d8dd;
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.06em;
	line-height: 1.3;
	text-transform: uppercase;
}

/*
 * Trial CTA: a step up in size/prominence from the reused unlock button
 * (0.85rem 2rem / 17px -> 1rem 2rem / 18px), full-width in the upsell card.
 * Inherits the gradient + animation from .thp-snapshot__button unchanged.
 */
.thp-snapshot .thp-snapshot__button--trial {
	width: 100%;
	padding: 1rem 2rem;
	font-size: 18px;
}

/*
 * Full-width note strip below both panels (matches the reference's
 * .delivery-note). Spans both grid columns since, unlike the reference's
 * static slide layout, this widget's note is itself a grid child.
 */
.thp-snapshot .thp-snapshot__note {
	grid-column: 1 / -1;
	margin: 0;
	padding: 12px 16px;
	border-radius: 12px;
	color: #075f68;
	background: var(--thp-teal-soft);
	font-size: clamp(0.7rem, 0.92vw, 0.9rem);
	line-height: 1.45;
}

/* =========================================================================
 * INTERACTIVE-STATE HARDENING (hover / focus / active / focus-visible)
 *
 * Host Elementor kits ship button :hover/:focus/:active rules from (0,1,1) up to
 * (0,2,2) (e.g. `body .elementor-kit-7 button:hover`) that beat the widget's
 * origin-reverted base reset, so a clicked phase node turned into a white,
 * shadowed, rounded box with a black label and an orange outline. A reset cannot
 * defend interactive states, so every button restates its full intended look for
 * every interactive state at (0,4,0) (doubled root class + element class + an
 * :is() pseudo), which outranks the kit rules with no !important. focus-visible
 * then adds the ring. Measured against computed style in every state.
 * ========================================================================= */

/* Phase stepper nodes: never a box — transparent, no shadow/radius/padding. */
.thp-snapshot.thp-snapshot .thp-snapshot__step-btn:is(:hover, :focus, :active, :focus-visible) {
	background: transparent;
	box-shadow: none;
	border-radius: 0;
	padding: 0;
	color: var(--thp-muted);
	outline: none;
	transform: none;
}

/* Selected nodes keep their navy label through every interactive state. */
.thp-snapshot.thp-snapshot .thp-snapshot__step-btn.is-selected:is(:hover, :focus, :active, :focus-visible) {
	color: var(--thp-navy);
}

.thp-snapshot.thp-snapshot .thp-snapshot__step-btn:focus-visible {
	outline: 2px solid var(--thp-teal);
	outline-offset: 2px;
}

/* "All phases" pill, state-complete at (0,4,0)+. Rest, pressed, hover/focus/active
 * each restate the full look INCLUDING the border (so it never drops), and
 * hover/focus/active give a teal border + teal-soft fill + teal text whether or
 * not the pill is pressed. */
.thp-snapshot.thp-snapshot .thp-snapshot__phase-all:not(:is(:hover, :focus, :active, :focus-visible)) {
	border: 1px solid var(--thp-line);
	background: var(--thp-white);
	color: var(--thp-muted);
	box-shadow: none;
	border-radius: 8px;
	padding: 3px 10px;
	outline: none;
	transform: none;
}

.thp-snapshot.thp-snapshot .thp-snapshot__phase-all[aria-pressed="true"]:not(:is(:hover, :focus, :active, :focus-visible)) {
	border: 1px solid var(--thp-teal);
	background: var(--thp-teal-soft);
	color: #006b74;
}

.thp-snapshot.thp-snapshot .thp-snapshot__phase-all:is(:hover, :focus, :active, :focus-visible) {
	border: 1px solid var(--thp-teal);
	background: var(--thp-teal-soft);
	color: #006b74;
	box-shadow: none;
	border-radius: 8px;
	padding: 3px 10px;
	outline: none;
	transform: none;
}

.thp-snapshot.thp-snapshot .thp-snapshot__phase-all:focus-visible {
	outline: 2px solid var(--thp-teal);
	outline-offset: 2px;
}

/* Gradient CTAs (Unlock + "Start my free trial"): block the kit's shadow /
 * padding / colour / outline leak; the gradient background and its hover darken
 * stay with the base .thp-snapshot__button rules above. */
.thp-snapshot.thp-snapshot .thp-snapshot__button:is(:hover, :focus, :active, :focus-visible) {
	/* Section 3: a distinct darker-teal fill on every interactive state (hover,
	 * focus, active, focus-visible) so the CTA never equals the #172b52 panel.
	 * #00788A: 2.70:1 vs the panel, white text 5.18:1 - both pass. Re-asserted via
	 * the fill var so the kit's `button:focus{background:#fff}` can't wipe it. */
	--thp-cta-fill: #00788A;
	background:
		linear-gradient(90deg, var(--thp-cta-fill), var(--thp-cta-fill)) padding-box,
		var(--thp-cta-border) border-box;
	background-size: 450%;
	box-shadow: none;
	/* Identical box model in every state: the 2px transparent border (through
	 * which the gradient border layer shows) and the padding are restated so no
	 * kit hover rule can drop the border or shift the layout. */
	border: 2px solid transparent;
	border-radius: 8px;
	padding: 0.85rem 2rem;
	color: #ffffff;
	outline: none;
	transform: none;
}

.thp-snapshot.thp-snapshot .thp-snapshot__button--trial:is(:hover, :focus, :active, :focus-visible) {
	padding: 1rem 2rem;
}

/* Hover-only soft teal glow (after the hardening so it wins over box-shadow:none;
 * focus/active stay flat). Fill colour + glow are the only hover changes. */
.thp-snapshot.thp-snapshot .thp-snapshot__button:hover:not(:disabled) {
	box-shadow: 0 0 0 3px rgba(0, 144, 165, 0.35);
}

/* Visible focus ring on the teal CTA (sits on the navy panel). */
.thp-snapshot.thp-snapshot .thp-snapshot__button:focus-visible {
	outline: 2px solid var(--thp-white);
	outline-offset: 2px;
}

@media (max-width: 760px) {
	/*
	 * Single column: panels stack in source order (filters, preview, form
	 * panel). grid-template-areas:none lets the named-area items auto-place, so
	 * no horizontal reorder happens - the mobile swap is vertical only. The
	 * stage-form rule repeats at (0,2,0) so it overrides the top-of-file
	 * stage-form columns (which are also 0,2,0) here inside the query.
	 */
	.thp-snapshot,
	.thp-snapshot.thp-snapshot--stage-form {
		grid-template-columns: 1fr;
		grid-template-areas: none;
	}

	/*
	 * Clear the named-area placement so the panels auto-flow and STACK in source
	 * order (filters, preview, form). Without this they keep their grid-area
	 * line names ("preview"/"form"), which, with no such lines in a single-column
	 * grid, collapse to the same cell and overlap.
	 */
	.thp-snapshot .thp-snapshot__form,
	.thp-snapshot .thp-snapshot__preview,
	.thp-snapshot .thp-snapshot__form-panel {
		grid-area: auto;
	}
}

/*
 * If, after visual QA on a real page with Elementor active, a theme/Elementor
 * rule still wins over the nested .thp-snapshot .thp-snapshot__x selectors
 * above (typically on .thp-snapshot__button or .thp-snapshot__select -
 * background, color, border, font-family are the usual culprits), add
 * !important to only those specific declarations here rather than sprinkling
 * it throughout the rules above.
 */

/*
 * Unknown opening date: "TBA" + asterisk button + tooltip (see buildDateNode in
 * the JS). The tooltip is a child of the card (absolute, so no layout shift) and
 * stays within the preview panel, which clips overflow; JS flips it above the
 * button (.is-above) and shifts it (--thp-tba-shift) to keep it inside. A card
 * with an open tooltip is lifted above its siblings (the blurred teasers).
 * The scoped reset strips button borders/states, so every state is restated at
 * (0,4,0). No transitions: nothing animates, reduced motion included.
 */
.thp-snapshot .thp-snapshot__sample {
	position: relative;
}

.thp-snapshot .thp-snapshot__sample:has(.thp-snapshot__tba.is-open) {
	z-index: 5;
}

.thp-snapshot .thp-snapshot__tba {
	display: inline-flex;
	align-items: center;
	white-space: nowrap;
}

.thp-snapshot .thp-snapshot__tba-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* 14px glyph, padded to a 24px hit area; negative margins keep the row height. */
	width: 24px;
	height: 24px;
	margin: -5px -5px -5px 0;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	box-shadow: none;
	color: rgba(255, 255, 255, 0.85);
	font-size: 14px;
	font-weight: 700;
	line-height: 1;
	text-transform: none;
	cursor: pointer;
}

.thp-snapshot.thp-snapshot .thp-snapshot__tba-btn:is(:hover, :focus, :active, :focus-visible) {
	border: 0;
	background: rgba(255, 255, 255, 0.16);
	box-shadow: none;
	color: var(--thp-white);
	outline: none;
	transform: none;
}

.thp-snapshot.thp-snapshot .thp-snapshot__tba-btn:focus-visible {
	outline: 2px solid var(--thp-white);
	outline-offset: 1px;
}

.thp-snapshot .thp-snapshot__tba-tip {
	display: none;
	position: absolute;
	top: calc(100% + 4px);
	right: 8px;
	z-index: 6;
	width: max-content;
	max-width: 240px;
	padding: 8px 10px;
	border-radius: 8px;
	background: var(--thp-white);
	box-shadow: var(--thp-shadow);
	color: var(--thp-ink);
	font-size: 0.75rem;
	font-weight: 400;
	line-height: 1.45;
	text-align: left;
	white-space: normal;
	transform: translateX(var(--thp-tba-shift, 0px));
}

.thp-snapshot .thp-snapshot__tba.is-open .thp-snapshot__tba-tip {
	display: block;
}

.thp-snapshot .thp-snapshot__tba-tip.is-above {
	top: auto;
	bottom: calc(100% + 4px);
}

/* Stepper node tooltip ("Not typical for %s suppliers"): the TBA tooltip look,
 * centred under the node (JS shifts it off the form's side edges / flips it above
 * when it would run past the bottom). Only non-typical nodes ever open one. */
.thp-snapshot .thp-snapshot__step-tip {
	display: none;
	position: absolute;
	top: calc(100% + 4px);
	left: 50%;
	z-index: 6;
	width: max-content;
	max-width: 200px;
	padding: 8px 10px;
	border-radius: 8px;
	background: var(--thp-white);
	box-shadow: var(--thp-shadow);
	color: var(--thp-ink);
	font-size: 0.75rem;
	font-weight: 400;
	line-height: 1.45;
	text-align: left;
	white-space: normal;
	transform: translateX(calc(-50% + var(--thp-tba-shift, 0px)));
}

.thp-snapshot .thp-snapshot__step.is-open .thp-snapshot__step-tip {
	display: block;
}

.thp-snapshot .thp-snapshot__step-tip.is-above {
	top: auto;
	bottom: calc(100% + 4px);
}

/* =========================================================================
 * HERO LAYOUT ([thp_project_snapshot layout="hero"])
 *
 * Stages are container classes set by JS (bindHeroLayout), next to the existing
 * --stage-form:
 *   --stage-intro   text | filters      (preview hidden + inert)
 *   --stage-active  filters | preview   (text hidden + inert)
 *   --stage-active.--stage-form  preview | form   (the unchanged registration swap)
 * Without JS, and on mobile (<=760px), no stage class is set: the panels stack in
 * source order (text, filters, preview, form panel) and nothing is hidden.
 * Specificity stays at (0,3,0)+ so these win over the base grid rules at the top
 * of the file and over theme/Elementor rules, without !important. No stage rule
 * sets a transform: the slide is animated by JS only while it runs.
 * ========================================================================= */
.thp-snapshot.thp-snapshot--hero {
	grid-template-columns: 1fr;
	grid-template-areas: none;
	grid-template-rows: none;
}

.thp-snapshot.thp-snapshot--hero .thp-snapshot__hero-text,
.thp-snapshot.thp-snapshot--hero .thp-snapshot__form,
.thp-snapshot.thp-snapshot--hero .thp-snapshot__preview,
.thp-snapshot.thp-snapshot--hero .thp-snapshot__form-panel {
	grid-area: auto;
}

.thp-snapshot.thp-snapshot--hero:is(.thp-snapshot--stage-intro, .thp-snapshot--stage-active) {
	grid-template-columns: 1fr 1fr;
	/* One row for the panels (with the measured minimum height). */
	grid-template-rows: minmax(var(--thp-row-min, 0px), auto);
}

.thp-snapshot.thp-snapshot--hero.thp-snapshot--stage-intro {
	grid-template-areas:
		"text filters";
}

.thp-snapshot.thp-snapshot--hero.thp-snapshot--stage-active {
	grid-template-areas:
		"filters preview";
}

.thp-snapshot.thp-snapshot--hero.thp-snapshot--stage-active.thp-snapshot--stage-form {
	grid-template-areas:
		"preview form";
}

.thp-snapshot.thp-snapshot--hero:is(.thp-snapshot--stage-intro, .thp-snapshot--stage-active) .thp-snapshot__hero-text {
	grid-area: text;
}

.thp-snapshot.thp-snapshot--hero:is(.thp-snapshot--stage-intro, .thp-snapshot--stage-active) .thp-snapshot__form {
	grid-area: filters;
}

.thp-snapshot.thp-snapshot--hero:is(.thp-snapshot--stage-intro, .thp-snapshot--stage-active) .thp-snapshot__preview {
	grid-area: preview;
}

.thp-snapshot.thp-snapshot--hero:is(.thp-snapshot--stage-intro, .thp-snapshot--stage-active) .thp-snapshot__form-panel {
	grid-area: form;
}

/* Intro panel: dark navy card (same tokens as the preview panel), white text. The
 * sibling cards use overflow:hidden for their rounded corners; this one needs none,
 * so focus rings on the demo link are never clipped. */
.thp-snapshot.thp-snapshot--hero .thp-snapshot__hero-text {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 14px;
	padding: clamp(20px, 2vw, 28px);
	border-radius: 20px;
	background: var(--thp-navy);
	box-shadow: var(--thp-shadow);
	color: var(--thp-white);
}

.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-eyebrow {
	margin: 0;
	color: var(--thp-teal-soft);
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-title {
	margin: 0;
	color: var(--thp-white);
	font-size: clamp(1.6rem, 2.4vw, 2.2rem);
	font-weight: 800;
	line-height: 1.15;
	text-wrap: balance;
}

/* Programmatic focus after "Back": no ring on mouse/script focus, keyboard focus keeps it. */
.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-title:focus:not(:focus-visible) {
	outline: none;
}

.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-copy {
	margin: 0;
	color: var(--thp-white);
	font-size: 1rem;
	line-height: 1.5;
}

.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-steps {
	display: grid;
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: thp-hero-step;
}

.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-step {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	margin: 0;
	padding: 0;
	color: var(--thp-white);
	font-size: 0.95rem;
	line-height: 1.4;
	counter-increment: thp-hero-step;
}

.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-step::before {
	content: counter(thp-hero-step);
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	background: var(--thp-coral);
	color: var(--thp-white);
	font-size: 0.8rem;
	font-weight: 800;
	line-height: 1;
}

.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-demo {
	align-self: flex-start;
	color: var(--thp-teal-soft);
	font-size: 0.9rem;
	font-weight: 700;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-demo:is(:hover, :focus, :active) {
	background: transparent;
	color: var(--thp-white);
	text-decoration: underline;
}

.thp-snapshot.thp-snapshot .thp-snapshot__hero-text .thp-snapshot__hero-demo:focus-visible {
	outline: 2px solid var(--thp-white);
	outline-offset: 3px;
}

/* "← Back" in the top right corner of the filters card (JS shows it only in the
 * settled active stage, until unlock or the registration swap). Out of flow, so
 * nothing shifts when it appears or hides. The card needs a positioning context in
 * hero only; the FLIP swap pins the card with an inline position:absolute, which
 * overrides this while it runs. Hover/focus/active states are re-asserted against
 * theme/Elementor button rules (same pattern as the toast close button). */
.thp-snapshot.thp-snapshot--hero .thp-snapshot__form {
	position: relative;
}

.thp-snapshot.thp-snapshot .thp-snapshot__form .thp-snapshot__hero-back {
	position: absolute;
	top: 16px;
	right: 18px;
	z-index: 2;
	margin: 0;
	padding: 4px 8px;
	border: 0;
	border-radius: 4px;
	background: transparent;
	box-shadow: none;
	color: var(--thp-muted);
	font-size: 12px;
	font-weight: 500;
	line-height: 16px;
	text-transform: none;
	cursor: pointer;
}

/* Keep a two-line heading clear of the button while it is visible. */
.thp-snapshot.thp-snapshot .thp-snapshot__form:has(.thp-snapshot__hero-back:not([hidden])) .thp-snapshot__intro-title {
	padding-right: 72px;
}

.thp-snapshot.thp-snapshot .thp-snapshot__form .thp-snapshot__hero-back:is(:hover, :focus, :active) {
	background: transparent;
	box-shadow: none;
	color: var(--thp-ink);
	text-decoration: underline;
	transform: none;
}

.thp-snapshot.thp-snapshot .thp-snapshot__form .thp-snapshot__hero-back:focus-visible {
	outline: 2px solid var(--thp-teal);
	outline-offset: 2px;
}

/* Preview placeholder (hero only): until the first real preview renders, the preview
 * panel shows just this block and hides everything else in it. */
.thp-snapshot .thp-snapshot__preview-placeholder {
	display: none;
}

.thp-snapshot.thp-snapshot--preview-pending .thp-snapshot__preview > :not(.thp-snapshot__preview-placeholder) {
	display: none;
}

.thp-snapshot.thp-snapshot--preview-pending .thp-snapshot__preview .thp-snapshot__preview-placeholder {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 8px;
	flex: 1 1 auto;
	color: var(--thp-white);
}

.thp-snapshot.thp-snapshot .thp-snapshot__preview-placeholder .thp-snapshot__preview-placeholder-title {
	color: var(--thp-white);
	font-size: 1.15rem;
	font-weight: 800;
	line-height: 1.2;
}

.thp-snapshot.thp-snapshot .thp-snapshot__preview-placeholder .thp-snapshot__preview-placeholder-copy {
	margin: 0;
	color: var(--thp-white);
	font-size: 0.95rem;
	line-height: 1.45;
	opacity: 0.85;
}

/* Preview skeleton (hero only, inside the placeholder): a "— matching projects" line,
 * one ghost project card with blurred bars and a muted hint. Static bars under
 * prefers-reduced-motion. */
.thp-snapshot.thp-snapshot .thp-snapshot__preview-placeholder .thp-snapshot__skeleton-count {
	margin: 0;
	color: var(--thp-white);
	font-size: 0.95rem;
	font-weight: 700;
	line-height: 1.3;
	animation: thp-snapshot-pulse 1.4s ease-in-out infinite;
}

.thp-snapshot.thp-snapshot .thp-snapshot__preview-placeholder .thp-snapshot__skeleton-card {
	display: grid;
	gap: 10px;
	padding: 16px;
	border: 1px solid rgba(255, 255, 255, 0.18);
	border-radius: 14px;
	background: rgba(255, 255, 255, 0.06);
}

.thp-snapshot.thp-snapshot .thp-snapshot__skeleton-card .thp-snapshot__skeleton-bar {
	display: block;
	height: 12px;
	border-radius: 6px;
	background: linear-gradient(90deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.12));
	background-size: 200% 100%;
	filter: blur(1.5px);
	animation: thp-snapshot-shimmer 1.6s linear infinite;
}

.thp-snapshot.thp-snapshot .thp-snapshot__skeleton-card .thp-snapshot__skeleton-bar--wide {
	width: 85%;
}

.thp-snapshot.thp-snapshot .thp-snapshot__skeleton-card .thp-snapshot__skeleton-bar--mid {
	width: 60%;
}

.thp-snapshot.thp-snapshot .thp-snapshot__skeleton-card .thp-snapshot__skeleton-bar--short {
	width: 35%;
}

@keyframes thp-snapshot-shimmer {
	from {
		background-position: 200% 0;
	}
	to {
		background-position: -200% 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.thp-snapshot.thp-snapshot .thp-snapshot__preview-placeholder .thp-snapshot__skeleton-count,
	.thp-snapshot.thp-snapshot .thp-snapshot__skeleton-card .thp-snapshot__skeleton-bar {
		animation: none;
	}
}
