/* Home and shared marketing sections. */

/* Fits inside one viewport: everything critical stays above the fold. */
.hero {
	position: relative;
	display: flex;
	align-items: center;
	min-height: min(100vh, 50rem); /* fallback for engines without svh */
	min-height: min(100svh, 50rem);
	padding-block: calc(var(--nav-h) + 2rem) 2.5rem;
	background: var(--gradient-hero);
	overflow: hidden;
}

.site-main--flush { padding-top: 0; }

.hero__grid {
	position: relative;
	z-index: 2;
	display: grid;
	gap: 3rem;
	align-items: center;
}

.hero__content { text-align: center; }

/* Sized so "Actually Works Together" holds one line in its column at
   every desktop width (text needs ~8.8px of width per px of font). */
.hero h1 { max-width: 50rem; font-size: clamp(2.5rem, 0.5rem + 4vw, 4.25rem); color: var(--color-white); }

/* Desktop line structure: "Finally, an MSP Platform" / "That" / red line.
   Below 64rem the break disappears and the headline wraps naturally. */
.hero__br { display: none; }

@media (min-width: 64rem) {
	.hero__br { display: block; }
	.hero h1 span { display: block; }
}
.hero h1 span,
.solution h2 span,
.demo-section h2 span { color: var(--color-accent-on-dark); }

/* V2: the accent segment starts its own line (matches Figma breaks). */
.solution h2 span,
.demo-section h2 span { display: block; }
.hero__lede { max-width: 42rem; margin: 1.25rem auto 1.5rem; color: var(--color-on-dark-muted); font-size: var(--text-xl); }
.hero .button-row { justify-content: center; }

/* ===== Trust strip — its own slim band right under the hero ===== */
/* No border-bottom: the torn seam on the following section is what marks this
   boundary now, and a hairline would have run straight through the tear. */
.trust-strip {
	background: var(--surface-grain-dark) repeat, var(--color-dark);
	padding-block: 1.75rem;
}

.trust-strip__grid {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 1rem 1.25rem;
	margin: 0;
}

/* Stat cards on the flat-dark strip. Same family as .benefits-impact__item, so
   the same card-tier treatment — this strip sits on flat --color-dark, the one
   dark surface where the ink is uniform across the whole row. */
.trust-strip__grid div {
	flex: 0 1 13rem;
	min-width: 9.375rem;
	padding: 0.85rem 1rem;
	text-align: center;
	border: 2px solid var(--color-border-dark);
	border-radius: var(--radius-lg);
	background: rgba(255, 255, 255, 0.07);
	box-shadow: var(--shadow-stamp-dark);
}

.trust-strip__grid dt { color: var(--color-white); font-family: var(--font-heading); font-size: var(--text-2xl); font-weight: 700; }
.trust-strip__grid dd { color: var(--color-on-dark-muted); font-size: var(--text-sm); }

/* ===== V2 textures (decorative, out of the a11y tree) ===== */
.hero,
.solution,
.benefits-section { position: relative; overflow: hidden; }

.hero::before,
.solution::before,
.benefits-section::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background-repeat: no-repeat;
	background-position: center;
	background-size: cover;
}

/* Rebel edge scuff — screen blend over the dark hero gradient */
.hero::before {
	background-image: url("../img/textures/hero-edge-scuff.webp");
	background-image: image-set(
		url("../img/textures/hero-edge-scuff.avif") 1x type("image/avif"),
		url("../img/textures/hero-edge-scuff@2x.avif") 2x type("image/avif"),
		url("../img/textures/hero-edge-scuff.webp") 1x type("image/webp"),
		url("../img/textures/hero-edge-scuff@2x.webp") 2x type("image/webp")
	);
	opacity: 0.25;
	mix-blend-mode: screen;
}

/* Technical grid (vector) — replaces the v1 dot pattern on the solution band */
.solution::before {
	background-image: url("../img/textures/technical-grid.svg");
	opacity: 0.46;
	mix-blend-mode: screen;
}

/* Halftone signal (vector) — multiply over the light benefits band */
.benefits-section::before {
	background-image: url("../img/textures/halftone-signal.svg");
	opacity: 0.6;
	mix-blend-mode: multiply;
}

.solution > *,
.benefits-section > * { position: relative; }

/* Dark-to-dark chain into the trust strip. The hero's screen-blended scuff sits
   above the section background, so the flat-dark settle has to be its own layer
   on top of it rather than a background layer underneath; the hero gives its
   content column a z-index so it stays above this, and the fade only reaches
   into bottom padding anyway. See --chain-dark-up in tokens.css.

   The demo band used to share this rule to chain into the footer. The footer now
   opens on a light band, so that boundary is the footer's torn seam instead —
   which also frees this ::after slot on the demo band, though the seam stays
   hosted on the footer because .demo-section is not last-before-footer on
   /demo/. */
.hero::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	height: 4.5rem;
	background: var(--chain-dark-up);
	pointer-events: none;
}

.hero__glow,
.demo-section__glow {
	position: absolute;
	width: 24rem;
	height: 24rem;
	border-radius: 50%;
	background: rgba(224, 85, 85, 0.2);
	filter: blur(72px);
	pointer-events: none;
}

.hero__glow--one { top: 10%; left: 10%; }
.hero__glow--two { right: 8%; bottom: 8%; background: rgba(196, 28, 28, 0.3); }

/* The demo glow's breathing pulse. A keyframe animation rather than a scripted
   one: the compositor owns it and the main thread never wakes for it, where a
   JS-driven loop would hold requestAnimationFrame open for the life of the page.
   4.4s round trip, sine in/out on each half.
   The motion layer adds .is-idle while the section is off-screen, so an
   off-screen glow costs nothing; the class is additive, so nothing breaks if
   it never arrives. */
@keyframes demo-glow-pulse {
	0%, 100% { transform: scale(1); opacity: 1; }
	50% { transform: scale(1.18); opacity: 0.55; }
}

@media (prefers-reduced-motion: no-preference) {
	.demo-section__glow { animation: demo-glow-pulse 4.4s cubic-bezier(0.37, 0, 0.63, 1) infinite; }
	.demo-section__glow.is-idle { animation-play-state: paused; }
}

.hero-product {
	position: relative;
	max-width: 34rem;
	width: 100%;
	margin-inline: auto;
	padding: 2rem;
	/* Hero tier: the most-looked-at box on the site. Its own ::before bloom sits
	   at z-index -1 and a box-shadow paints with the element's background layer,
	   so this offset lands ON the bloom rather than on the raw hero gradient —
	   white is the only ink that stays legible over a red-shifted backdrop of
	   that hue, which the accent red would not. */
	border: 2px solid var(--color-accent-on-dark);
	border-radius: var(--radius-xl);
	background: var(--color-white);
	box-shadow: var(--shadow-stamp-lg-dark);
}

.hero-product::before {
	content: "";
	position: absolute;
	inset: -1rem;
	z-index: -1;
	border-radius: 2rem;
	background: linear-gradient(90deg, rgba(196, 28, 28, 0.28), rgba(224, 85, 85, 0.22));
	filter: blur(22px);
}

/* V2: crisp red-outlined ticket rows, third row inverted dark */
.hero-product__rows { display: grid; gap: 1rem; }
.hero-product__rows div { display: flex; align-items: center; gap: 0.8rem; padding: 1rem; border: 2px solid var(--color-primary); border-radius: var(--radius-sm); background: var(--color-white); }
.hero-product__rows i { width: 0.6rem; height: 0.6rem; border-radius: 2px; background: var(--color-primary); }
.hero-product__rows span { width: 80%; height: 0.4rem; border-radius: 2px; background: var(--color-primary); }
.hero-product__rows div:nth-child(2) span { width: 65%; opacity: 0.75; }
.hero-product__rows div:nth-child(3) { border-color: var(--color-dark); background: var(--color-dark); }
.hero-product__rows div:nth-child(3) i { background: var(--color-white); }
.hero-product__rows div:nth-child(3) span { width: 50%; background: var(--color-white); }

.hero-product__stats { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1.5rem; }
.hero-product__stats div { display: flex; flex-direction: column; padding: 1rem; border: 2px solid rgba(0, 0, 0, 0.35); border-radius: var(--radius-sm); background: var(--gradient-dark); color: var(--color-white); box-shadow: 3px 3px 0 rgba(26, 13, 13, 0.9); }
.hero-product__stats div:last-child { background: var(--gradient-primary); }
.hero-product__stats strong { font-size: var(--text-2xl); }
/* Solid white, not --color-on-dark-muted. Three of these four tiles are
   --gradient-dark and the muted token is fine on them, but the last is
   --gradient-primary, which ends at #D63A3A — and rgba(255,255,255,.85)
   composites to #F9E1E1 there, measuring 3.73:1 against a 4.5:1 bar for 12px
   text. Solid white is 4.64:1 at that same point. One rule for all four rather
   than a :last-child exception, so the four labels stay identical. */
.hero-product__stats span { font-size: 0.75rem; color: var(--color-on-dark); }

.split-layout { display: grid; gap: 3rem; align-items: center; }
.solution h2 { max-width: 42rem; font-size: var(--text-4xl); }
.solution__lede { margin: 1.25rem 0 2rem; color: var(--color-on-dark-muted); font-size: var(--text-xl); }
.feature-list { display: grid; gap: 1.25rem; }
.feature-list__item { display: grid; grid-template-columns: auto 1fr; gap: 1rem; align-items: start; }
.feature-list__item h3 { margin-bottom: 0.25rem; font-size: var(--text-xl); }
.feature-list__item p { color: var(--color-on-dark-muted); }

.consolidation { display: grid; justify-items: center; gap: 1.2rem; }
.consolidation__tools { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; width: 100%; }
.consolidation__tools span { padding: 0.85rem 0.5rem; border: 1px solid var(--color-border-dark); border-radius: var(--radius); background: rgba(255, 255, 255, 0.08); text-align: center; font-size: var(--text-sm); }
/* Points DOWN. .consolidation is a single-column grid at every width — six tools,
   then this, then the platform card — so the 90deg turn is unconditional and
   there is no breakpoint where it should point right.

   `color` is gone from here: it was set to --color-on-dark-muted on an <img>,
   which does nothing. Sketch icons carry their ink baked into the file and are
   not tintable (see base.css), and the only thing `color` could have reached is
   alt text this icon deliberately does not have. It was reading as if the arrow
   were muted on purpose, which is now handled where it actually can be — the
   icon serves from cta/, whose artwork has no accent to mute. */
.consolidation__arrow { transform: rotate(90deg); }
/* Border and radius were already right; only the legacy soft blur was off-language. */
.platform-card { width: min(100%, 25rem); padding: 2rem; border: 2px solid var(--color-accent-on-dark); border-radius: var(--radius-lg); background: rgba(255, 255, 255, 0.11); text-align: center; box-shadow: var(--shadow-stamp-dark); }
.platform-card__mark { display: block; width: 3.25rem; height: auto; margin: 0 auto 0.8rem; }
.platform-card > p { color: var(--color-on-dark-muted); font-size: var(--text-sm); }
.platform-card ul { display: grid; gap: 0.55rem; margin-top: 1.25rem; padding: 0; list-style: none; text-align: left; }
.platform-card li { display: flex; align-items: center; gap: 0.65rem; padding: 0.65rem 0.8rem; border-radius: var(--radius-sm); background: rgba(255, 255, 255, 0.08); }
.platform-card li .icon { width: 1.1em; height: 1.1em; color: var(--color-on-dark-muted); }

/* Declared rather than left to the body: the torn seam overhanging its top edge
   is painted in --color-white and has to meet this surface exactly. */
.features-section { background: var(--color-white); }

.benefits-section { background: linear-gradient(180deg, var(--color-tint), var(--color-white)); }
.comparison-section { background: var(--color-white); }
.integrations-section { background: linear-gradient(180deg, var(--color-white), var(--color-tint)); }

/* Integrations → testimonials handoff: the dark CTA panel straddles the
   section boundary and testimonials continues the tint the integrations
   gradient ends on, so the two read as one flow. */
.cta-panel--bridge {
	position: relative;
	z-index: 2;
	margin-bottom: calc(-1 * (var(--section-pad) + 2.5rem));
}

.testimonials-section {
	background: linear-gradient(180deg, var(--color-tint), var(--color-white));
	padding-top: calc(var(--section-pad) + 4rem);
}

.demo-section { position: relative; background: var(--gradient-dark-sym); overflow: hidden; }
.demo-section__glow { right: 8%; bottom: -8rem; }
/* z-index so the content clears the ::after overlays below (the dark-to-dark
   chain fade on the home page, the torn seam on /demo/). At 375 the section's
   4rem of bottom padding is shorter than the 4.5rem fade, and DOM order alone
   would have put a decorative layer over the last row's button. */
.demo-section__inner { position: relative; z-index: 1; max-width: 68rem; text-align: center; }
.demo-section h2 { max-width: 58rem; margin-inline: auto; font-size: clamp(2.2rem, 6vw, 3.75rem); }
.demo-section__lede { max-width: 48rem; margin: 1.25rem auto 2.5rem; color: var(--color-on-dark-muted); font-size: var(--text-xl); }
.demo-card { max-width: 44rem; margin-inline: auto; padding: clamp(1.25rem, 5vw, 2rem); border: 2px solid var(--color-border-dark); border-radius: var(--radius-lg); background: rgba(255, 255, 255, 0.1); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); box-shadow: var(--shadow-stamp-dark); }
/* An embedded form is its own document, so its media queries measure the IFRAME,
   not the viewport. The provider stacks its field columns below 649px, and at the
   card's normal 44rem the slot is 704 - 64 = 640px — nine pixels short, which
   serves the stacked layout on a 1280px desktop. 46rem leaves a 672px slot.
   Scoped with :has() so a native form keeps the original measure, and
   deliberately the smallest bump that clears the breakpoint. */
.demo-card:has(.ghl-form) { max-width: 46rem; }

.demo-card h3 { margin-bottom: 1.25rem; font-size: var(--text-2xl); }
.form-fineprint { margin-top: 1rem; color: var(--color-on-dark-muted); font-size: var(--text-sm); }
.demo-section__call { margin-top: 2.5rem; padding-top: 2rem; border-top: 1px solid var(--color-border-dark); }
.demo-section__call p { margin-bottom: 1rem; font-size: var(--text-lg); }

@media (min-width: 64rem) {
	.split-layout { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4rem; }
	/* Content column gets the wider share so the headline holds its line. */
	.hero__grid { grid-template-columns: 1.1fr 0.9fr; gap: 4rem; }
	.hero__content { text-align: left; }
	.hero__lede { margin-inline: 0; }
	.hero .button-row { justify-content: flex-start; }
}

@media (max-width: 39.99rem) {
	.hero { min-height: auto; }
	.hero .button-row .btn { width: 100%; }
	.hero-product { padding: 1.25rem; }
	.consolidation__tools { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
