/*
  Forte homepage v3, "stupidly direct" landing page.

  This is a separate stylesheet from assets/css/homepage.css on purpose:
  that file now belongs entirely to /homepage-v2/ (the fuller narrative
  homepage, preserved as a secondary page). This page has different goals
  - watch the founder, read proof, run the numbers, book a call - so it
  gets its own lean stylesheet rather than inheriting a system built for a
  much longer page. Shared tokens (palette/type) are duplicated rather
  than imported so the two pages can evolve independently without one
  edit silently changing the other.
*/

:root {
  --ink: #0e1610;
  --ink-soft: #161f18;
  --ink-softer: #1e2a21;
  /* Tuned to sit visibly lighter than --ink (#0e1610) - but this
     page's actual rendered body background is #243523 (a same-
     specificity `body{background-color:...}` rule in the Webflow
     shared stylesheet, loaded after this file, wins the cascade over
     our own body{background:var(--ink)} - see the .hero fix earlier
     for the same pattern), which is already lighter than the old
     #1c2721 card color. Every "card" using this variable (stat
     cards, feature cards, the reviews badge, the booking modal
     panel) was rendering *darker* than the page instead of standing
     out from it. Lightened relative to the actual #243523 backdrop. */
  --ink-card: #32492e;
  --gold: #d6af0b;
  --gold-bright: #f0c93d;
  --sand: #e6d7ab;
  --ember: #c9622a;
  --cream: #f9f5e4;
  --cream-dim: #efe8d2;
  --white: #ffffff;

  --text-hi: var(--cream);
  --text-muted: #9aa599;
  --text-dim: #6d766c;

  --font-display: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace;

  --container: min(1180px, 100% - 3rem);
  --radius-sm: 8px;
  --radius-md: 16px;
  --radius-lg: 28px;

  --space-section: clamp(3.5rem, 8vw, 6.5rem);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; background: var(--ink); scroll-padding-top: 6rem; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--text-hi);
  background: var(--ink);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, video { max-width: 100%; display: block; }
a { color: inherit; }
h1, h2, h3, h4 { font-weight: 400; margin: 0; line-height: 1.05; letter-spacing: -0.01em; text-wrap: balance; }
h1 { font-family: var(--font-display); }
h2, h3, h4 { font-family: var(--font-body); font-weight: 300; }
p { margin: 0; color: var(--text-muted); text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; cursor: pointer; }

.u-container { width: var(--container); margin-inline: auto; position: relative; z-index: 1; }
.u-visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 1rem; top: -3rem;
  background: var(--gold); color: var(--ink);
  padding: 0.75rem 1.25rem; border-radius: var(--radius-sm);
  z-index: 200; transition: top 0.2s ease; font-weight: 700;
}
.skip-link:focus { top: 1rem; }

:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Nav "Book a Demo" button: Webflow's cover-link pattern (an
   invisible <a class="u-link-cover"> stretched over the whole
   button, with the visible text/background as separate sibling
   divs) receives keyboard focus on the invisible link itself.
   Safari draws its own native focus ring on that link regardless of
   this site's :focus-visible rule above, rendering as a pale rounded
   box floating inside the dark button - not reproducible in Chromium
   (where this was originally checked), only reported from Safari.
   Suppress it there and show the intended gold ring on the visible
   button instead. */
.nav-button .u-link-cover { outline: none; }
.nav-button .button:has(.u-link-cover:focus-visible) {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* ---------- Buttons ---------- */
/* !important on padding/border-radius: the Webflow shared stylesheet
   happens to define its own, unrelated `.btn{...}` for a real
   component on the actual Forte site (padding:14px 28px, a 6px
   rounded rect) that coincidentally shares this class name with this
   page's custom button. Equal specificity, loaded after this file,
   so it silently won - buttons were losing their pill shape for a
   subtly-wrong rounded rectangle. Same story for .btn-primary
   (background-color:var(--dark-green) there vs our gold here) -
   "Get a Personalized Quote" was rendering with a background that
   matched the page behind it almost exactly, effectively invisible. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 1rem 2.1rem !important; border-radius: 999px !important; font-weight: 600; font-size: 1.05rem;
  text-decoration: none; border: 1px solid transparent; transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.btn:hover { transform: translateY(-2px); }
.btn-primary { background: var(--gold) !important; color: var(--ink) !important; }
.btn-primary:hover { background: var(--gold-bright) !important; }
.btn-ghost-dark { border-color: rgba(249,245,228,0.22); color: var(--text-hi); }
.btn-ghost-dark:hover { border-color: var(--gold); color: var(--gold-bright); }
.btn-sm { padding: 0.6rem 1.3rem; font-size: 0.9rem; }

.site-footer__logo-svg { height: 15px; width: auto; }
.site-footer__logo-icon { height: 15px; width: auto; color: var(--cream); margin-left: 0.5rem; }

/* ---------- Decorative glow ---------- */
.glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
}
.glow::before {
  content: ""; position: absolute; width: 140%; max-width: 1400px; aspect-ratio: 1;
  left: 50%; top: -40%; transform: translateX(-50%);
  background: conic-gradient(from 200deg at 50% 50%, transparent 0deg, var(--ember) 40deg, var(--gold) 110deg, transparent 200deg, transparent 360deg);
  filter: blur(90px); opacity: 0.35;
}

/* ---------- Section scaffolding ---------- */
/* !important is required: the Webflow shared stylesheet (loaded after
   this file on the From Our CEO page) has its own same-specificity
   `.section { padding-top: 0; padding-bottom: 0 }` rule for native
   Webflow sections, which otherwise wins the cascade by load order
   and collapses every custom section on this page - hero, reviews,
   ROI calculator, everything - to zero vertical padding. */
.section { padding-block: var(--space-section) !important; position: relative; }
.section--edge-top { border-top: 1px solid rgba(249,245,228,0.08); }
/* !important on both: this section carries a "how" class (just a
   plain content-identifying name when this was written) that
   coincidentally collides with a real component on the actual Forte
   Webflow site, PLUS the generic .section collision already seen
   elsewhere - three same-specificity rules end up competing for
   this element's own background/color (ours, vendor's .section, and
   vendor's .how), and vendor's rules, loading later, were winning.
   Background was resolving to vendor's own --cream (a slightly
   different, lighter shade than our intended --sand tan), and color
   was resolving to white - the latter is what left .how-card h3 (no
   color of its own, relying on inheriting this section's dark ink)
   unreadable, the same root cause as the earlier heading fix below. */
.section--band { background: var(--sand) !important; color: var(--ink) !important; }
.section--band p { color: rgba(14,22,16,0.72); }
.section--band .eyebrow { color: rgba(14,22,16,0.65); }
.section--band .eyebrow::before, .section--band .eyebrow::after { background: rgba(14,22,16,0.25); }
/* .section-head h2 defaults to --text-hi (white/cream) for the
   normal dark sections it's mostly used in; .section--light got a
   matching override when it was added, but .section--band never did,
   so its heading kept the white default meant for a dark background
   sitting on this section's tan one instead - unreadable. */
.section--band .section-head h2 { color: var(--ink); }

/* A plain light (cream) section, used sparingly to break up the dark
   theme with real rhythm rather than leaving everything on --ink. */
/* !important: same vendor-CSS collision as .hero/.cc-hero elsewhere -
   the Webflow shared stylesheet's own `.section{background-color:...}`
   rule (loaded after this file) has equal specificity and wins the
   cascade, so this section was silently staying the page's normal
   dark green instead of turning cream. That left every child text
   color here (headings/eyebrow/button all switched to dark ink,
   assuming a light backdrop) sitting on a dark background instead -
   dark-on-dark, reading as "text blending into the background." */
.section--light { background: var(--cream) !important; color: var(--ink); }
.section--light .section-head h2, .section--light .reviews-head__title { color: var(--ink); }
.section--light .section-head p { color: rgba(14,22,16,0.68); }
.section--light .eyebrow { color: rgba(14,22,16,0.6); }
.section--light .eyebrow::before, .section--light .eyebrow::after { background: rgba(14,22,16,0.22); }
.section--light .btn-ghost-dark { border-color: rgba(14,22,16,0.25); color: var(--ink); }
.section--light .btn-ghost-dark:hover { border-color: var(--ember); color: var(--ember); }

/* !important on letter-spacing: same vendor-CSS class-name collision
   pattern as .btn/.stat-grid/.section--band above - a real Webflow
   component also named .eyebrow sets its own 0.1em, which otherwise
   wins over this file's 0.16em. Cosmetic (both read fine), fixed for
   consistency while auditing every other instance of this pattern. */
.eyebrow {
  display: flex; align-items: center; gap: 0.85rem; justify-content: center;
  text-transform: uppercase; letter-spacing: 0.16em !important;
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 500;
  color: var(--gold-bright); margin-bottom: 1.25rem;
}
.eyebrow::before, .eyebrow::after { content: ""; width: 1.5rem; height: 1px; background: rgba(249,245,228,0.35); flex-shrink: 0; }

.section-head { max-width: 40rem; margin-inline: auto; margin-bottom: 3rem; text-align: center; }
.section-head h2 { font-size: clamp(2rem, 4.2vw, 3rem); margin-bottom: 1rem; color: var(--text-hi); }
.section-head p { font-size: 1.1rem; }

[data-reveal] { opacity: 1; transform: none; }
.js-reveal-ready [data-reveal] {
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.js-reveal-ready [data-reveal].is-visible { opacity: 1; transform: none; }

/* ================================================================
   HERO: text above a centered, horizontal video
   ================================================================ */
.hero {
  padding-top: clamp(3rem, 8vw, 5.5rem); padding-bottom: clamp(3rem, 8vw, 5.5rem);
  text-align: center; overflow: hidden;
}
/* The sticky nav takes up real space in the flow (unlike the old fixed
   header this hero was originally built for), so the hero was starting
   right below it - leaving the nav's own gap above it showing flat
   page background instead of this hero's photo. Pull the hero up by
   most of the nav's rendered height and add that same amount back as
   padding, so the photo extends up underneath/behind the nav (nav's
   z-index:999 keeps it stacked on top). Only pulling up 44px of the
   nav's ~67-74px height (rather than the full amount) leaves a bit of
   the page's own dark background showing as breathing room between the
   nav and the photo, instead of the photo tucking up with zero gap.

   The -44/+44 pair on their own would net to zero for the visible text
   (it'd land at exactly clamp(...) from the viewport top either way,
   same as before any of this) - the extra +28px on top of that +44 is
   what actually pushes the eyebrow/heading text down for real breathing
   room from the nav, since it isn't cancelled out by the margin. */
.hero.hero--photo {
  margin-top: -44px;
  /* !important: needed to beat .section's own !important padding-block
     (added above to escape the same vendor-cascade problem) - without
     it, that rule's higher-priority !important would win by itself and
     erase this compensation, leaving the hero's visible content shifted
     up by the 44px this rule is meant to add back. */
  padding-top: calc(clamp(3rem, 8vw, 5.5rem) + 44px + 28px) !important;
}
/* The Webflow shared stylesheet (loaded after this file on the From Our
   CEO page) carries its own same-specificity `.hero { background-color:
   var(--cream) }` rule, which - being later in source order - wins the
   cascade and washes the whole section out in light cream instead of
   the dark photo backdrop below. The extra .hero--photo class here
   out-specifies that single-class vendor rule and restores the intended
   dark background. */
.hero.hero--photo { background-color: var(--dark-green, #243523); }
/* A real photo behind the hero, blended low and dark so it reads as
   ambient atmosphere (not a competing image) and keeps text contrast high. */
.hero__bg {
  display: none;
  position: absolute; inset: 0; z-index: 0;
  background-size: cover; background-position: center 22%;
  opacity: 0.34; filter: saturate(0.7) blur(4px);
}
/* The gradient used to fade to --ink (#0e1610), but this page's actual
   ambient background (body, every section below) renders as the Webflow
   shared stylesheet's --dark-green (#243523) - a same-specificity `body`
   rule there beats ours the same way its `.hero` rule did above. Fading
   to a color darker than what's actually behind the hero left a visible
   seam where the hero ends and the next section's real background
   begins. Match --dark-green so the hero blends into it seamlessly.
   Keep the top blend short (8%, not the original 28%) - matching the
   nav gap's color at full strength for a long stretch reads as a flat
   green bar rather than a hero photo; the photo should take over
   almost immediately below the nav. */
.hero__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, var(--dark-green, #243523) 0%, rgba(36,53,35,0.35) 8%, rgba(36,53,35,0.35) 75%, var(--dark-green, #243523) 100%);
}
@media (min-width: 700px) {
  .hero__bg { display: block; }
}
.hero__pre-eyebrow {
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--cream);
  margin-bottom: 0.6rem;
}
.hero__eyebrow-line {
  font-family: var(--font-mono); font-size: clamp(0.95rem, 2.6vw, 1.55rem);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--gold-bright);
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem); max-width: 46rem; margin-inline: auto;
}
@media (min-width: 900px) {
  .hero__eyebrow-line { white-space: nowrap; max-width: none; }
}
.hero__subhead {
  font-size: clamp(1rem, 1.6vw, 1.15rem); color: rgba(249, 245, 228, 0.82);
  max-width: 42rem; margin: clamp(1.5rem, 4vw, 2.25rem) auto 0; line-height: 1.6;
  /* --text-muted reads fine over the solid --ink sections it's normally
     used on, but this hero has a real photo showing through the middle
     of its background gradient - gray-on-photo loses far more contrast
     than gray-on-flat-color. Lighten it and add a shadow so it stays
     legible regardless of what's behind it at any given scroll position. */
  text-shadow: 0 2px 16px rgba(0,0,0,0.55);
}
.hero__video-wrap { max-width: 900px; margin-inline: auto; }
.video-placeholder {
  position: relative; aspect-ratio: 16 / 9; border-radius: var(--radius-lg);
  overflow: hidden; background: linear-gradient(155deg, #0a0f0b, var(--ink-soft));
  border: 1px solid rgba(249,245,228,0.12);
  display: flex; align-items: center; justify-content: center; text-align: center;
  box-shadow: 0 40px 100px -40px rgba(214,175,11,0.25);
}
.hero__cta { margin-top: clamp(1.75rem, 4vw, 2.5rem); }

/* Custom sound toggle for the autoplaying (muted) CEO video - same
   pattern as the reference site (autoplay muted, click to unmute),
   but positioned top-left per request instead of bottom-right. Sized
   up and given a gold border + soft pulse so it reads as an
   invitation to interact, not a small incidental control. */
.video-sound-toggle {
  position: absolute; top: 1.1rem; left: 1.1rem; z-index: 2;
  display: inline-flex; align-items: center; gap: 0.6rem;
  padding: 0.85rem 1.3rem; border: 2px solid rgba(214,175,11,0.55); border-radius: 999px;
  background: rgba(14,22,16,0.7); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 20px rgba(0,0,0,0.35);
  color: var(--cream); cursor: pointer; transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
  animation: soundTogglePulse 2.6s ease-in-out infinite;
}
.video-sound-toggle:hover { background: rgba(14,22,16,0.85); border-color: var(--gold); transform: scale(1.04); }
.video-sound-toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.video-sound-toggle.is-unmuted { animation: none; }
@keyframes soundTogglePulse {
  0%, 100% { box-shadow: 0 6px 20px rgba(0,0,0,0.35), 0 0 0 0 rgba(214,175,11,0.35); }
  50% { box-shadow: 0 6px 20px rgba(0,0,0,0.35), 0 0 0 8px rgba(214,175,11,0); }
}
@media (prefers-reduced-motion: reduce) {
  .video-sound-toggle { animation: none; }
}
.video-sound-toggle__icon { display: block; flex-shrink: 0; width: 24px; height: 24px; }
.video-sound-toggle__icon--unmuted { display: none; }
.video-sound-toggle.is-unmuted .video-sound-toggle__icon--muted { display: none; }
.video-sound-toggle.is-unmuted .video-sound-toggle__icon--unmuted { display: block; }
.video-sound-toggle__label { font-size: 0.95rem; font-weight: 600; white-space: nowrap; }
.video-sound-toggle.is-unmuted .video-sound-toggle__label { display: none; }

/* "Book a Conversation" hero CTA - lifted to cream/white so it reads
   as the clear next step against the dark video, rather than the
   site-wide gold .btn-primary (still used elsewhere on this page). */
.hero__cta .btn-primary { background: var(--cream); color: var(--ink); }
.hero__cta .btn-primary:hover { background: #fff; }

/* ================================================================
   TESTIMONIALS: dense, review-card styled wall of real quotes
   ================================================================ */
.reviews-head { text-align: center; margin-bottom: clamp(2rem, 5vw, 3rem); }
.reviews-head__title {
  font-size: clamp(2.1rem, 4.6vw, 3.4rem); color: var(--text-hi);
  max-width: 34rem; margin: 0 auto 1.5rem;
}
@media (min-width: 900px) {
  .reviews-head__title { white-space: nowrap; max-width: none; }
}
.reviews-agg {
  display: inline-flex; align-items: center; gap: 0.9rem; background: var(--ink-card);
  border: 1px solid rgba(249,245,228,0.1); border-radius: 999px; padding: 0.75rem 1.5rem;
  margin-bottom: 1.5rem;
}
.reviews-agg__stars { color: var(--gold); font-size: 1.1rem; letter-spacing: 0.05em; }
.reviews-agg__score { font-family: var(--font-display); font-size: 1.3rem; color: var(--text-hi); }
.reviews-agg__count { font-size: 0.85rem; color: var(--text-dim); }

/* A plain grid rather than CSS column-count masonry: column-count's
   "balance" height estimate runs before web fonts swap in, and doesn't
   re-run afterwards, so card heights (and therefore each column's start
   position) could drift out of alignment depending on font-load timing.
   Grid gives every card in a row the same top edge deterministically. */
/* minmax(0, 1fr), not bare 1fr: a bare 1fr track still has an implicit
   min width of its content's min-content size, so a single long
   nowrap name/role in one card was forcing that whole column wider
   and squeezing the other three - the uneven column widths a reviewer
   flagged as looking sloppy. minmax(0, 1fr) removes that content floor
   so every column is genuinely equal. */
.review-wall { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.1rem; align-items: start; }
@media (min-width: 640px) { .review-wall { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 980px) { .review-wall { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1300px) { .review-wall { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.review-card {
  background: var(--white); color: #202124;
  border-radius: 10px; padding: 1.15rem 1.25rem; box-shadow: 0 1px 2px rgba(0,0,0,0.15);
  display: flex; flex-direction: column;
}
.review-card__top { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.6rem; }
.review-card__avatar {
  width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: #1a73a8; color: var(--white); font-weight: 600; font-size: 0.95rem; flex-shrink: 0;
  font-family: var(--font-body);
}
/* Cycle through a varied palette so avatars don't all read as the same
   generated placeholder - matches how real review sites color-code
   initials per person rather than using one flat brand color. */
.review-wall .review-card:nth-of-type(9n+1) .review-card__avatar { background: #1a73a8; }
.review-wall .review-card:nth-of-type(9n+2) .review-card__avatar { background: #4a8b5c; }
.review-wall .review-card:nth-of-type(9n+3) .review-card__avatar { background: #8b5e3c; }
.review-wall .review-card:nth-of-type(9n+4) .review-card__avatar { background: #3b4b66; }
.review-wall .review-card:nth-of-type(9n+5) .review-card__avatar { background: #a34a4a; }
.review-wall .review-card:nth-of-type(9n+6) .review-card__avatar { background: #6b5b95; }
.review-wall .review-card:nth-of-type(9n+7) .review-card__avatar { background: #c98a3e; }
.review-wall .review-card:nth-of-type(9n+8) .review-card__avatar { background: #4a8b8b; }
.review-wall .review-card:nth-of-type(9n) .review-card__avatar { background: #7a6a5a; }
.review-card__id { flex-grow: 1; min-width: 0; }
.review-card__name { font-size: 0.92rem; font-weight: 500; color: #202124; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.review-card__role { font-size: 0.76rem; color: #5f6368; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.review-card__stars { color: #fbbc04; font-size: 0.85rem; margin-bottom: 0.5rem; letter-spacing: 0.1em; }
/* Real Google review cards clamp to a handful of lines rather than
   growing to fit - quote length here ranges from one line to a full
   paragraph, and letting every card grow to its own natural height
   is what made the wall read as uneven/sloppy rather than as a grid. */
.review-card__text {
  font-size: 0.9rem; line-height: 1.5; color: #3c4043;
  display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Base [data-css-marquee-list] mechanism - on root this ships for
   free with Webflow's own client-logos marquee component; pages
   built from this file (like /from-the-ceo, which has no Webflow
   marquee component of its own) need it defined here instead, plus
   the initCSSMarquee() clone/pause logic in homepage.js. Without
   this, a list just has one un-cloned copy of itself sliding fully
   off-screen and snapping back every cycle - "stops moving, then a
   big empty gap before it restarts" - rather than looping seamlessly. */
@keyframes translateX { to { transform: translateX(-100%); } }
[data-css-marquee-list] {
  animation: translateX 30s linear;
  animation-iteration-count: infinite;
  animation-play-state: paused;
}

/* ================================================================
   HOMEPAGE REVIEWS MARQUEE: several rows of the same review cards,
   auto-scrolling continuously (alternating direction per row) so
   all 2,000+ reviews stay implied without ever dumping them on the
   page at once or needing a "load more" control. Reuses the site's
   existing [data-css-marquee]/[data-css-marquee-list] mechanism
   (already shipped for the client-logos row below the hero, on
   pages that have one) rather than a bespoke animation system - that
   JS clones each list enough times to cover the viewport and pauses
   the animation whenever the marquee scrolls out of view, so this
   gets that for free. */
.review-marquee { display: flex; flex-direction: column; gap: 2rem; margin-top: clamp(2rem, 4vw, 3rem); }
/* display:flex was missing here: the marquee JS clones each row's
   [data-css-marquee-list] several times (to cover the viewport width
   for a seamless loop) and appends the clones as siblings inside this
   wrapper. Without flex, those clones - each already an internally-
   flex row of cards - stacked vertically as plain block elements
   instead of sitting side by side, which is what rendered as the
   same reviewers repeated underneath themselves. */
.review-marquee-row {
  display: flex;
  /* Matches the gap inside each [data-css-marquee-list] below - the
     marquee JS places multiple clones of that list as siblings of
     each other inside this row, so without a matching gap here the
     last card of one clone sits flush against the first card of the
     next, reading as two cards stuck together. */
  gap: 1.1rem;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, black 6%, black 94%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0%, black 6%, black 94%, transparent 100%);
}
.review-marquee-row [data-css-marquee-list] { display: flex; gap: 1.1rem; flex-shrink: 0; }
.review-marquee-section { padding-block: clamp(3.5rem, 8vw, 6.5rem) !important; position: relative; background: #243523 !important; }
/* Scoped to the marquee (not the base .review-card/.review-wall,
   which the /from-the-ceo grid used before it was replaced by this
   same marquee) so a second, brand-refreshed card style - gold top
   accent, serif name, clickable lift - can live alongside the plain
   Google-style base without touching it. */
.review-marquee-row .review-card {
  min-width: 300px; max-width: 300px; flex-shrink: 0;
  border-top: 3px solid #d6af0b; box-shadow: 0 2px 12px rgba(36,53,35,0.18);
  height: 158px; cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.review-marquee-row .review-card:hover, .review-marquee-row .review-card:focus-visible {
  transform: translateY(-3px); box-shadow: 0 10px 24px rgba(36,53,35,0.3);
}
.review-marquee-row .review-card__avatar { width: 34px; height: 34px; font-size: 0.9rem; }
.review-marquee-row .review-card__name {
  font-family: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  font-size: 1.05rem; font-weight: 400; color: #243523;
}
.review-marquee-row .review-card__stars { color: #d6af0b; }
.review-marquee-row .review-card__text { -webkit-line-clamp: 3; }
/* The shared marquee CSS only defines the leftward direction; add a
   reverse variant so alternating rows can travel opposite ways. */
[data-css-marquee-list][data-marquee-reverse="true"] { animation-name: reviewMarqueeRight; }
@keyframes reviewMarqueeRight { from { transform: translateX(-100%); } to { transform: translateX(0); } }
/* The marquee JS sets its own animation-duration inline (scaled to
   each row's content width so speed reads consistently); override
   per row with !important. All four rows now match the bottom row's
   (speed4's) slower pace instead of drifting at different speeds. */
.review-marquee-row--speed1 [data-css-marquee-list] { animation-duration: 83s !important; }
.review-marquee-row--speed2 [data-css-marquee-list] { animation-duration: 83s !important; }
.review-marquee-row--speed3 [data-css-marquee-list] { animation-duration: 83s !important; }
.review-marquee-row--speed4 [data-css-marquee-list] { animation-duration: 83s !important; }
@media (prefers-reduced-motion: reduce) {
  .review-marquee-row [data-css-marquee-list] { animation: none !important; transform: none !important; }
  .review-marquee-row { overflow-x: auto; }
}
/* Mobile: a 300px card is ~80% of a 375px screen, leaving barely a
   sliver of the next card as a scroll cue. Narrower cards read more
   clearly as "one of several" on a small screen. */
@media (max-width: 480px) {
  .review-marquee-row .review-card { min-width: 250px; max-width: 250px; }
}

/* Review lightbox: reuses the site's own dialog.modal mechanism
   (Mast Modal, already loaded globally for the booking modal) for
   the fade-in/backdrop/close behavior, styled to match the review
   cards' own branding. A single shared dialog is populated from
   whichever card was clicked rather than one dialog per card, since
   the marquee JS clones every card several times over. */
.review-lightbox {
  width: min(90vw, 560px); max-width: 560px; padding: 2.5rem 2.75rem 2.75rem;
  border: none; border-radius: 20px; border-top: 4px solid #d6af0b;
  background: #fffcfa; color: #202124;
  box-shadow: 0 30px 80px -20px rgba(0,0,0,0.5);
}
/* !important: the site's global dialog.modal::backdrop rule uses
   color-mix() with a Webflow component-scoped variable
   (--_color---neutral--black) that isn't actually defined at the
   :root/html level, making that whole background declaration
   invalid everywhere it's used (so this global rule, at higher
   specificity than a plain .review-lightbox::backdrop, was quietly
   leaving every modal on the site with a fully transparent
   backdrop) - force this one with a literal, valid color instead. */
.review-lightbox::backdrop { background: rgba(36,53,35,0.85) !important; }
.review-lightbox__close {
  position: absolute; top: 1rem; right: 1.1rem; width: 34px; height: 34px;
  border: none; border-radius: 50%; background: rgba(36,53,35,0.06); color: #243523;
  font-size: 1.5rem; line-height: 1; cursor: pointer; transition: background 0.15s ease;
}
.review-lightbox__close:hover { background: rgba(36,53,35,0.14); }
.review-lightbox__quote-mark {
  font-family: 'Instrument Serif', Georgia, serif; font-size: 4.5rem; line-height: 1;
  color: #d6af0b; opacity: 0.5; margin-bottom: -1.25rem;
}
.review-lightbox__top { display: flex; align-items: center; gap: 0.85rem; margin-bottom: 0.75rem; }
.review-lightbox__avatar {
  width: 52px; height: 52px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  color: #fffcfa; font-weight: 600; font-size: 1.2rem; flex-shrink: 0;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.review-lightbox__name { font-family: 'Instrument Serif', Georgia, serif; font-size: 1.4rem; color: #243523; }
.review-lightbox__role { font-size: 0.85rem; color: #5f6368; }
.review-lightbox__stars { color: #d6af0b; font-size: 1.05rem; letter-spacing: 0.12em; margin-bottom: 1rem; }
.review-lightbox__text { font-size: 1.1rem; line-height: 1.65; color: #3c4043; }
@media (max-width: 600px) {
  .review-lightbox { padding: 2.25rem 1.5rem 2rem; }
}

/* ================================================================
   ROI CALCULATOR: ported from /general-v1, re-themed to this palette
   ================================================================ */
.roi-band { background: var(--ink-softer); }
.roi-head { text-align: center; margin-bottom: clamp(2rem, 4vw, 3rem); }
.roi-title { font-size: clamp(1.8rem, 3.4vw, 2.6rem); color: var(--text-hi); margin: 0.6rem 0; }
.roi-desc { font-size: 0.95rem; color: var(--text-muted); max-width: 32rem; margin: 0 auto; }

.roi-layout {
  display: grid; grid-template-columns: 1fr; gap: 0;
  max-width: 900px; margin: 0 auto 2rem; border: 1px solid rgba(249,245,228,0.12);
  border-radius: var(--radius-md); overflow: hidden;
}
@media (min-width: 800px) { .roi-layout { grid-template-columns: 1fr auto 1fr; } }

.roi-inputs { padding: 1.75rem; display: flex; flex-direction: column; gap: 0.9rem; }
.roi-field label {
  display: block; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-dim); margin-bottom: 0.4rem;
}
.roi-field input {
  width: 100%; background: rgba(249,245,228,0.06); border: 1px solid rgba(249,245,228,0.14);
  border-radius: 6px; color: var(--text-hi); padding: 0.6rem 0.8rem; font-size: 0.95rem; font-family: var(--font-body);
}
.roi-field input:focus { outline: none; border-color: var(--gold); }

.roi-center {
  border-block: 1px solid rgba(249,245,228,0.12); padding: 1.75rem 2rem; text-align: center;
}
@media (min-width: 800px) { .roi-center { border-block: none; border-inline: 1px solid rgba(249,245,228,0.12); } }
.roi-total-lbl { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim); margin-bottom: 0.5rem; }
.roi-total { font-family: var(--font-display); font-size: clamp(2.6rem, 5vw, 3.6rem); color: var(--gold-bright); line-height: 1; white-space: nowrap; }
.roi-1pct { font-size: 0.78rem; color: var(--text-dim); margin-top: 0.6rem; line-height: 1.4; }
.roi-1pct span { color: var(--text-hi); font-weight: 600; }

.roi-levers { padding: 1.75rem; display: flex; flex-direction: column; gap: 0.5rem; }
.roi-lever { display: flex; align-items: center; gap: 0.65rem; background: rgba(249,245,228,0.04); border-radius: 6px; padding: 0.55rem 0.75rem; }
.roi-lever-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.roi-dot-blue { background: #3d7fb8; }
.roi-dot-green { background: #2e7d5b; }
.roi-dot-gold { background: var(--gold); }
.roi-dot-dim { background: rgba(249,245,228,0.2); }
.roi-lever-name { font-size: 0.8rem; color: var(--text-muted); flex: 1; }
.roi-lever-val { font-size: 0.9rem; font-weight: 700; color: var(--text-hi); white-space: nowrap; }
.roi-lever-cost .roi-lever-val { color: var(--text-dim); font-weight: 400; font-size: 0.8rem; }

.roi-cta-row { text-align: center; }

/* ================================================================
   Ported from /general-v2: What Is Mental Fitness, Coaching,
   Sample Exercises, How It Works, Why Forte Works
   ================================================================ */
.eyebrow--left { justify-content: flex-start; }

.mf-tracks { display: grid; gap: 1.5rem; margin-top: 1rem; }
@media (min-width: 800px) { .mf-tracks { grid-template-columns: repeat(2, 1fr); } }
.mf-track {
  background: var(--ink-card); border: 1px solid rgba(249,245,228,0.08);
  border-radius: var(--radius-md); overflow: hidden;
}
.mf-track__photo { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
.mf-track__text { padding: 1.5rem; }
.mf-track__text h3 { font-size: 1.25rem; color: var(--text-hi); margin-bottom: 0.6rem; }
.mf-track__text p { font-size: 0.95rem; margin-bottom: 0.85rem; }
.mf-track__detail { font-size: 0.78rem; color: var(--text-dim); }
.mf-track__link { color: var(--gold-bright); text-decoration: none; font-weight: 600; font-size: 0.92rem; }
.mf-track__link:hover { color: var(--gold); }

.coaching-inner { display: grid; gap: 2rem; align-items: center; }
@media (min-width: 900px) { .coaching-inner { grid-template-columns: 0.85fr 1fr; gap: 3rem; } }
.coaching-visual img { border-radius: var(--radius-lg); aspect-ratio: 4 / 5; object-fit: cover; width: 100%; }
.coaching-text h2 { font-size: clamp(1.9rem, 3.6vw, 2.6rem); margin-bottom: 1rem; color: var(--text-hi); }
.coaching-text p { font-size: 1.02rem; margin-bottom: 1rem; }
.coaching-list { display: flex; flex-direction: column; gap: 0.6rem; margin: 1.25rem 0 1.75rem; }
.coaching-list li {
  position: relative; padding-left: 1.4rem; font-size: 0.95rem; color: var(--text-muted);
}
.coaching-list li::before { content: "✓"; position: absolute; left: 0; color: var(--gold-bright); font-weight: 700; }

.exercise-cards { display: grid; gap: 1.25rem; margin-top: 1rem; }
@media (min-width: 800px) { .exercise-cards { grid-template-columns: repeat(3, 1fr); } }
.exercise-card {
  background: var(--ink-card); border: 1px solid rgba(249,245,228,0.08);
  border-radius: var(--radius-md); padding: 1.75rem;
}
.exercise-card__num { font-family: var(--font-mono); font-size: 0.8rem; color: var(--text-dim); margin-bottom: 0.75rem; }
.exercise-card h4 { font-size: 1.15rem; color: var(--text-hi); margin-bottom: 0.6rem; }
.exercise-card p { font-size: 0.9rem; margin-bottom: 0.85rem; }
.exercise-card__time {
  display: inline-block; font-family: var(--font-mono); font-size: 0.72rem;
  color: var(--gold-bright); border: 1px solid rgba(249,245,228,0.18); border-radius: 999px; padding: 0.25rem 0.7rem;
}
.exercises-preview__cta { text-align: center; margin-top: 2.25rem; }

/* "How It Works" is styled as a bright gold band, breaking up the dark
   theme rather than sitting flush with every other section. */
.how-steps { display: grid; gap: 1.5rem; margin-top: 1rem; }
@media (min-width: 800px) { .how-steps { grid-template-columns: repeat(3, 1fr); } }
.how-card {
  background: rgba(14,22,16,0.08); border: 1px solid rgba(14,22,16,0.14);
  border-radius: var(--radius-md); padding: 1.75rem;
}
.how-card__num {
  width: 2.25rem; height: 2.25rem; border-radius: 50%; background: var(--ink); color: var(--gold-bright);
  display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-size: 1.1rem;
  margin-bottom: 1rem;
}
/* Explicit color as a backstop: .how-card is a barely-tinted light
   card (rgba(14,22,16,0.08) over the tan .section--band background),
   so it needs dark-ink text. Now that .section--band's own color is
   forced correct with !important above, h3 would inherit the right
   value anyway - kept explicit here too, matching the p right below
   it which already had its own color set, in case another collision
   on one of this element's other classes shows up later. */
.how-card h3 { font-size: 1.2rem; margin-bottom: 0.6rem; color: var(--ink); }
.how-card p { font-size: 0.92rem; color: rgba(14,22,16,0.72); }

.features .section-head { max-width: 46rem; }
/* !important: the Webflow shared stylesheet happens to define its
   own, unrelated `.stat-grid{grid-template-columns:1fr;...}` for a
   real component on the actual Forte site, coincidentally sharing
   this class name. Equal specificity, loaded after this file, wins
   regardless of this rule being inside a matching @media block -
   media-scoping a rule doesn't grant it extra precedence over a
   later plain rule of the same specificity. Stat cards were stacking
   in one column at every width instead of 4 side by side. */
.stat-grid { display: grid; gap: 1.1rem; margin: 2rem 0; }
@media (min-width: 700px) { .stat-grid { grid-template-columns: repeat(4, 1fr) !important; } }
/* !important on padding: same vendor collision pattern - its
   .stat-card sets padding via a --card-pad variable this page never
   defines, which makes those 4 (invalid at compute time) padding
   longhands resolve to 0 instead of falling back to ours, so cards
   had their content flush against the edges. */
.stat-card {
  background: var(--ink-card); border: 1px solid rgba(249,245,228,0.08);
  border-radius: var(--radius-md); padding: 1.5rem !important; text-align: center;
}
.stat-card__num { font-family: var(--font-display); font-size: clamp(1.8rem, 3vw, 2.3rem); color: var(--gold-bright); }
.stat-card__label { font-size: 0.85rem; color: var(--text-muted); margin-top: 0.4rem; }
.stat-card__label strong { color: var(--text-hi); }

.paths-grid { display: grid; gap: 1.1rem; grid-template-columns: 1fr; margin: 2rem 0; }
@media (min-width: 700px) { .paths-grid { grid-template-columns: repeat(4, 1fr); } }
.path-card {
  position: relative; display: block; border-radius: var(--radius-md); overflow: hidden;
  aspect-ratio: 3 / 4; text-decoration: none;
}
.path-card img { width: 100%; height: 100%; object-fit: cover; }
.path-card::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(14,22,16,0.92), rgba(14,22,16,0.15) 55%, transparent 80%);
}
.path-card__label {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 1.1rem 1rem;
  font-family: var(--font-body); font-weight: 600; font-size: 0.95rem; color: var(--text-hi); z-index: 1;
  display: flex; align-items: center; gap: 0.4rem;
}
.path-card__label svg { flex-shrink: 0; transition: transform 200ms; }
.path-card:hover .path-card__label svg { transform: translateX(3px); }

.photo-grid-4 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.85rem; margin: 2rem 0; }
@media (min-width: 700px) { .photo-grid-4 { grid-template-columns: repeat(4, 1fr); } }
.photo-grid-4__frame { border-radius: var(--radius-md); overflow: hidden; aspect-ratio: 1; }
.photo-grid-4__frame img { width: 100%; height: 100%; object-fit: cover; }

.features-grid { display: grid; gap: 1.25rem; margin-top: 1rem; }
@media (min-width: 800px) { .features-grid { grid-template-columns: repeat(3, 1fr); } }
.feature-card {
  background: var(--ink-card); border: 1px solid rgba(249,245,228,0.08);
  border-radius: var(--radius-md); padding: 1.75rem;
}
.feature-card h3 { font-size: 1.15rem; color: var(--text-hi); margin-bottom: 0.6rem; }
.feature-card p { font-size: 0.9rem; margin-bottom: 1rem; }
.feature-card__metric { display: flex; flex-direction: column; gap: 0.15rem; padding-top: 0.9rem; border-top: 1px solid rgba(249,245,228,0.1); }
.feature-card__metric-num { font-family: var(--font-display); font-size: 1.4rem; color: var(--gold-bright); }
.feature-card__metric span:last-child { font-size: 0.78rem; color: var(--text-dim); }

/* ---------- Footer (slim) ---------- */
.site-footer { background: var(--ink); color: var(--text-dim); padding-block: 2.5rem; font-size: 0.88rem; border-top: 1px solid rgba(249,245,228,0.08); }
.site-footer a { color: var(--text-muted); text-decoration: none; }
.site-footer a:hover { color: var(--cream); }
.site-footer__top {
  display: flex; flex-wrap: wrap; gap: 1.5rem; justify-content: space-between; align-items: center;
  padding-bottom: 1.5rem; border-bottom: 1px solid rgba(249,245,228,0.1);
}
.site-footer__logo { color: var(--cream); font-family: var(--font-display); font-size: 1.3rem; }
.site-footer__links { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.site-footer__bottom {
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between; align-items: center; padding-top: 1.25rem;
}
.site-footer__social { display: flex; flex-wrap: wrap; gap: 1rem; }

/* ---------- Booking modal ---------- */
.booking-modal { position: fixed; inset: 0; z-index: 300; display: none; }
.booking-modal[data-open="true"] { display: block; }
.booking-modal__backdrop { position: absolute; inset: 0; background: rgba(6,10,7,0.78); backdrop-filter: blur(4px); }
.booking-modal__panel {
  position: relative; margin: 4vh auto; width: min(640px, 92vw); max-height: 92vh;
  overflow-y: auto; background: var(--ink-card); border: 1px solid rgba(249,245,228,0.12);
  border-radius: var(--radius-lg); box-shadow: 0 40px 100px -30px rgba(0,0,0,0.6);
  padding: 2.5rem;
}
.booking-modal__close {
  position: absolute; top: 1.25rem; right: 1.25rem; width: 40px; height: 40px; border-radius: 50%;
  background: var(--ink-soft); border: 1px solid rgba(249,245,228,0.15); color: var(--text-hi);
  font-size: 1.4rem; line-height: 1; display: flex; align-items: center; justify-content: center;
}
.booking-modal__close:hover { border-color: var(--gold); color: var(--gold-bright); }
.booking-modal__header { max-width: 26rem; margin-bottom: 1.5rem; }
.booking-modal__header h2 { font-size: clamp(1.6rem, 3vw, 2.1rem); color: var(--text-hi); margin-bottom: 0.5rem; }
.booking-modal__sub { font-size: 1rem; }
.booking-modal__body .meetings-iframe-container { min-height: 480px; }
@media (max-width: 600px) {
  .booking-modal__panel { padding: 1.75rem 1.25rem; margin-top: 2vh; }
}
