/* ==========================================================================
   Sphinx Labs — design tokens + shared classes
   Values taken from the Figma file (B2B SaaS Founders, node 46:137).
   Loaded alongside the Tailwind CDN build.
   ========================================================================== */

:root {
  /* --- Brand blues ------------------------------------------------------
     Demoted. On the dark canvas the blue survives only as ambient depth —
     corner blooms, section wash, gradient blobs. It never lands on a control
     again; lime does that job now. Keeping it at all is deliberate: it holds
     colour continuity with the wider Sphinx brand and stops the page reading
     as flat monochrome black. */
  --brand: #074e87;
  --brand-dark: #06487f;
  --accent: #008cff;

  /* Hero is near-black now. The blue arrives as a bloom, not a fill. */
  --hero-from: #0c0c0c;
  --hero-to: #050505;

  /* --- The one action colour --------------------------------------------
     Every CTA, active state, focus ring, underline and numeral. Restricting
     accent to a single hue is what makes it read as premium rather than
     decorated — the eye learns "lime means you can act on this". */
  --lime: #c6ff00;
  --lime-dim: #a9db00;
  --lime-glow: rgba(198, 255, 0, 0.28);
  --lime-ink: #0a0a0a;      /* text placed on top of lime */

  /* --- Text -------------------------------------------------------------
     --ink/--body keep their names so no component needs re-plumbing; they
     simply invert. Contrast on #0a0a0a: ink 18.4:1, body 7.7:1 — both AAA. */
  --ink: #f4f4f5;
  --body: #a1a1a6;
  --on-dark: #ffffff;
  --on-dark-muted: #d8d8d8;
  --on-dark-faint: #c5c5c5;

  /* --- Problem cards ----------------------------------------------------
     Pastel fills would glow like lightboxes on black. They become low-alpha
     tints, with the foreground lifted to a value that actually reads. */
  --card-amber-bg: rgba(255, 193, 7, 0.07);
  --card-amber-fg: #ffc24d;
  --card-purple-bg: rgba(143, 87, 255, 0.08);
  --card-purple-fg: #b98cff;
  --card-teal-bg: rgba(48, 180, 163, 0.08);
  --card-teal-fg: #4fd8c4;

  /* --- Surfaces --------------------------------------------------------- */
  --page: #0a0a0a;
  --surface-1: #101010;
  --glass: rgba(255, 255, 255, 0.035);
  --glass-hi: rgba(255, 255, 255, 0.07);
  --hairline: rgba(255, 255, 255, 0.08);
  --hairline-hi: rgba(255, 255, 255, 0.16);

  /* Depth on black comes from a large soft shadow plus a 1px top highlight,
     not from a darker fill — there is nothing darker than the page. */
  --shadow-card: 0 18px 40px rgba(0, 0, 0, 0.5);
  --shadow-lift: 0 28px 70px rgba(0, 0, 0, 0.65);

  --radius: 20px;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  /* --- Type ------------------------------------------------------------- */
  --font-display: "Bricolage Grotesque", system-ui, sans-serif;
  --font-ui: "Plus Jakarta Sans", system-ui, sans-serif;

  /* --- Layout ----------------------------------------------------------- */
  /* Figma: 1440 page, 1210 content, so 115px gutters. */
  --content: 1210px;
  --gutter: 115px;
}

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

body {
  background: var(--page);
  color: var(--ink);
  font-family: var(--font-display);
  font-variation-settings: "opsz" 14, "wdth" 100;
  -webkit-font-smoothing: antialiased;
  /* The hero dot pattern is intentionally wider than its card. */
  overflow-x: clip;
}

html {
  overflow-x: clip;
  scroll-behavior: smooth;
  scroll-padding-top: 120px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   Shared classes — used across several sections
   -------------------------------------------------------------------------- */

/* Page gutter + max width. Figma content column is 1210px inside 1440px. */
.shell {
  width: 100%;
  max-width: calc(var(--content) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Pill badge above each section heading ("Problems", "Why Us", …).
   Now a lime-outlined glass pill with a faint inner tint — it reads as the
   first, smallest instance of the accent before the eye reaches the heading. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid rgba(198, 255, 0, 0.35);
  border-radius: 999px;
  padding: 7px 14px;
  background: rgba(198, 255, 0, 0.06);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 14px;
  line-height: 13px;
  letter-spacing: 0.3px;
  color: var(--lime);
  white-space: nowrap;
}

/* 16px matches what the Solution badge was already forcing with !important
   utilities, so raising the base leaves that instance pixel-identical.
   line-height has to be reset too: .badge pins it at 13px, which clips a
   16px face. */
.badge--on-dark {
  border-color: rgba(255, 255, 255, 0.22);
  background: var(--glass);
  color: #ffffff;
  font-size: 16px;
  line-height: 1;
  padding: 8px 18px;
  height: auto;
}

/* Rotating ring ------------------------------------------------------------
   A conic gradient can only be swept by animating its angle, and an angle can
   only be animated if it is registered as a typed custom property — a plain
   --var is a string to the animation engine, so it would jump 0->360 at the
   halfway mark instead of turning.

   This is the one place that animates something other than transform/opacity
   (see the note atop css/effects.css). Justified here: the repainting box is a
   ~210x37px pill that never moves, so the per-frame cost is trivial, and the
   transform-based alternative needs a second wrapper element plus a rotating
   square sized to the pill's diagonal, which sweeps visibly off-axis on a
   shape this wide. The global prefers-reduced-motion rule already freezes it.
   -------------------------------------------------------------------------- */

@property --badge-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.badge--spin {
  position: relative;
  /* The pseudo-element below draws the edge now. Kept as transparent rather
     than removed so the badge's box size is unchanged. */
  border-color: transparent;
}

.badge--spin::before {
  content: "";
  position: absolute;
  /* -1px reaches the border box, where the original 1px border sat. */
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(
    from var(--badge-angle),
    rgba(255, 255, 255, 0.16) 0deg,
    var(--lime) 45deg,
    rgba(255, 255, 255, 0.16) 130deg,
    rgba(255, 255, 255, 0.16) 360deg
  );
  /* Two masks, one clipped to the content box, composited to cancel out —
     leaves only the 1px padding band visible, i.e. a ring. */
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
  animation: badge-ring 4s linear infinite;
}

@keyframes badge-ring {
  to {
    --badge-angle: 360deg;
  }
}

.badge--cream {
  border-color: rgba(198, 255, 0, 0.35);
  color: var(--lime);
}

/* Section heading -----------------------------------------------------------
   Oversized, tight and heavy: the brief's "headlines dominate each section".
   clamp() means one declaration covers every breakpoint, so the per-breakpoint
   font-size overrides at the bottom of this file are no longer needed.

   line-height below 1 is safe here only because Bricolage Grotesque has short
   descenders; it is what makes multi-line headings read as a single block
   rather than as separate lines. */
.h-section {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.25rem, 5vw, 3.75rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: balance;
}

/* The hero h1. Larger and tighter still — it is the only element on the page
   at this size, which is what gives the page a clear single entry point. */
.h-hero {
  font-family: var(--font-display);
  font-weight: 600;
  /* Capped at 4.5rem rather than the display-type maximum: this headline runs
     to two full sentences, and any larger pushes the CTAs below the fold on a
     laptop — which costs more than the extra scale gains. */
  font-size: clamp(2.25rem, 5.4vw, 4.5rem);
  line-height: 0.98;
  letter-spacing: -0.03em;
  color: #ffffff;
  text-wrap: balance;
}

/* Supporting paragraph under a section heading. Gains size and leading rather
   than shrinking — body copy has to hold its own against headings this large,
   and long measures on a dark background need more air to stay readable. */
.p-section {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 18px;
  line-height: 1.65;
  color: var(--body);
}

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

/* Pill buttons. The radius change from 10px to fully round is what most
   separates the new look from the old at a glance. */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: 999px;
  padding: 16px 26px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  line-height: 19px;
  cursor: pointer;
  /* transform is listed so magnetic buttons (js/motion.js) inherit the easing.
     No layout property is animated. */
  transition: background-color 0.25s ease, color 0.25s ease,
    box-shadow 0.35s var(--ease-out), transform 0.25s var(--ease-out);
}

/* Lime fill, black label — the primary CTA. The glow is a resting state, not
   a hover reward: this is the one thing on the page that should look lit
   before you touch it. */
.btn--light {
  background: var(--lime);
  color: var(--lime-ink);
  box-shadow: 0 0 0 rgba(198, 255, 0, 0), 0 10px 34px rgba(198, 255, 0, 0.22);
}

.btn--light:hover {
  background: #d4ff33;
  box-shadow: 0 0 0 6px rgba(198, 255, 0, 0.1), 0 14px 44px rgba(198, 255, 0, 0.36);
}

/* The arrow ships as dark ink (see images/icons/arrow-up-right.svg), which is
   already correct on lime — so unlike the old blue button, no filter needed. */
.btn--light:active {
  transform: translateY(1px);
}

/* Outlined glass — the secondary CTA. Hover fills from the bottom rather than
   switching colour, so the two buttons never compete for attention. */
.btn--ghost-light {
  border: 1px solid var(--hairline-hi);
  background: var(--glass);
  color: #ffffff;
  overflow: hidden;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.btn--ghost-light::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(255, 255, 255, 0.14);
  transform: translateY(101%);
  transition: transform 0.4s var(--ease-out);
}

.btn--ghost-light:hover {
  border-color: rgba(255, 255, 255, 0.3);
}

.btn--ghost-light:hover::before {
  transform: translateY(0);
}

/* Nav "Contact Us". Plus Jakarta Sans per Figma. */
.btn--accent {
  background: var(--lime);
  color: var(--lime-ink);
  font-family: var(--font-ui);
  font-size: 14px;
  padding: 13px 20px;
  box-shadow: 0 8px 26px rgba(198, 255, 0, 0.24);
}

.btn--accent:hover {
  background: #d4ff33;
  box-shadow: 0 0 0 5px rgba(198, 255, 0, 0.1), 0 12px 34px rgba(198, 255, 0, 0.34);
}

/* The nav arrow is the same dark-ink asset, so it reads correctly on lime. */
.btn--accent img {
  filter: none;
}

/* Sticky header ---------------------------------------------------------- */

/* `sticky` rather than `fixed`: the header keeps its place in the flow, so
   pinning it costs no layout shift and needs no spacer element. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  transition: background-color 0.35s ease, box-shadow 0.35s ease;
}

.site-header__bar {
  transition: padding-block 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.site-header__logo {
  transition: height 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

/* JS adds .is-stuck once the page has scrolled past the header's own height.
   Transparent until then, so the page opens with the hero running clean to the
   top edge and the header appearing to float over it. */
.site-header.is-stuck {
  background: rgba(10, 10, 10, 0.72);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid var(--hairline);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
  /* Drops in from above the viewport the moment it pins. */
  animation: header-drop 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Compress on pin so the bar takes less of the screen while reading. */
.site-header.is-stuck .site-header__bar {
  padding-block: 12px;
}

.site-header.is-stuck .site-header__logo {
  height: 40px;
}

@keyframes header-drop {
  from {
    transform: translateY(-100%);
  }
  to {
    transform: translateY(0);
  }
}

/* The drop is decorative; the pin itself is what matters. */
@media (prefers-reduced-motion: reduce) {
  .site-header,
  .site-header__bar,
  .site-header__logo {
    transition: none;
  }

  .site-header.is-stuck {
    animation: none;
  }
}

/* Navigation ------------------------------------------------------------- */

.nav-link {
  position: relative;
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
  transition: color 0.2s ease;
}

/* Underline scales in from the left rather than fading — direction gives the
   hover a sense of intent that a fade doesn't have. */
.nav-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 1.5px;
  border-radius: 2px;
  background: var(--lime);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.35s var(--ease-out);
}

.nav-link:hover,
.nav-link:focus-visible {
  color: var(--lime);
}

.nav-link:hover::after,
.nav-link:focus-visible::after {
  transform: scaleX(1);
}

/* Hamburger: a middle bar plus two pseudo bars that cross into an X. */
.nav-burger,
.nav-burger::before,
.nav-burger::after {
  display: block;
  width: 18px;
  height: 2px;
  background: var(--ink);
  transition: transform 0.25s ease, top 0.25s ease, background-color 0.2s ease;
}

.nav-burger {
  position: relative;
}

.nav-burger::before,
.nav-burger::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav-burger::before {
  top: -6px;
}

.nav-burger::after {
  top: 6px;
}

[aria-expanded="true"] .nav-burger {
  background: transparent;
}

[aria-expanded="true"] .nav-burger::before,
[aria-expanded="true"] .nav-burger::after {
  top: 0;
}

[aria-expanded="true"] .nav-burger::before {
  transform: rotate(45deg);
}

[aria-expanded="true"] .nav-burger::after {
  transform: rotate(-45deg);
}

/* Mobile menu panel. Desktop layout comes from Tailwind's lg:flex. */
@media (max-width: 1023px) {
  .nav-links.is-open {
    display: flex;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 50;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: rgba(10, 10, 10, 0.94);
    -webkit-backdrop-filter: blur(18px);
    backdrop-filter: blur(18px);
    border-top: 1px solid var(--hairline);
    box-shadow: 0 24px 50px rgba(0, 0, 0, 0.6);
    padding: 8px var(--gutter) 24px;
  }

  .nav-links.is-open li {
    border-bottom: 1px solid var(--hairline);
  }

  .nav-links.is-open li:last-child {
    border-bottom: 0;
    padding-top: 20px;
  }

  .nav-links.is-open .nav-link {
    display: block;
    padding: 18px 0;
    font-size: 14px;
  }
}

/* Hero ------------------------------------------------------------------- */

/* The hero (card, gradient and rotating dot field) lives in css/hero.css.
   The --hero-from / --hero-to tokens above are still defined here. */

/* "Trusted by" logo strip ------------------------------------------------ */

/* Figma: six logos across 1053px, each in its own ~152px slot, one row.
   The explicit width/height attributes carry the per-logo Figma sizes; this
   only handles distribution and the small-screen wrap. */
.logo-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  width: 100%;
  max-width: 1053px;
  margin-inline: auto;
}

.logo-strip img {
  height: auto;
  max-width: 100%;
  object-fit: contain;
}

@media (max-width: 1023px) {
  .logo-strip {
    flex-wrap: wrap;
    justify-content: center;
    gap: 24px 36px;
  }

  /* Keep the row readable rather than shrinking logos to illegibility. */
  .logo-strip img {
    max-height: 32px;
    width: auto;
  }
}

/* Problem cards ---------------------------------------------------------- */

/* The tinted fill now arrives from the Tailwind bg-*-bg classes as a 7-8%
   wash rather than a pastel block, so each card keeps its identity while
   staying part of the dark page. The hairline and shadow do the work the
   solid fill used to do. */
.problem-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-card);
  padding: 40px;
  overflow: hidden;
  transition: transform 0.45s var(--ease-out), border-color 0.45s ease,
    box-shadow 0.45s var(--ease-out);
}

/* Border glow, tinted to each card's own hue so the row reads as three
   distinct ideas rather than one component repeated three times. */
.problem-card::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s var(--ease-out);
  background: radial-gradient(70% 60% at 50% 0%, var(--card-glow), transparent 70%);
}

#problems .problem-card:nth-child(1) {
  --card-glow: rgba(255, 194, 77, 0.16);
}
#problems .problem-card:nth-child(2) {
  --card-glow: rgba(185, 140, 255, 0.16);
}
#problems .problem-card:nth-child(3) {
  --card-glow: rgba(79, 216, 196, 0.16);
}

.problem-card:hover {
  transform: translateY(-6px);
  border-color: var(--hairline-hi);
  box-shadow: var(--shadow-lift);
}

.problem-card:hover::before {
  opacity: 1;
}

/* Oversized and set back behind the copy — the numeral is a landmark, not a
   label, so it can afford to be large and quiet at the same time. */
.problem-card__num {
  position: relative;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 64px;
  line-height: 0.9;
  letter-spacing: -0.03em;
}

.problem-card__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  color: var(--ink);
}

.problem-card__body {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 18px;
  color: var(--body);
}

@media (max-width: 767px) {
  .problem-card {
    padding: 28px;
  }

  .problem-card__num {
    font-size: 40px;
  }

  .problem-card__body {
    font-size: 16px;
  }
}

/* Solution --------------------------------------------------------------- */

/* Figma 71:25086: 1210x657 grey card, photo bleeding behind a green panel
   pinned to the right. */
/* The panel sits in flow (not absolutely positioned) so the card grows if the
   copy needs more room than Figma's fixed 657px — clipped text is worse than a
   slightly taller card. Photo is absolute behind it. */
.solution {
  display: flex;
  justify-content: flex-end;
  min-height: 657px;
  padding: 40px;
  border: 1px solid var(--hairline);
  background: var(--surface-1);
}

.solution__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Figma applies rotate(180deg) + scaleY(-1), which nets to a horizontal flip. */
  transform: scaleX(-1);
}

/* A scrim over the photo. Without it the white panel copy would sit on
   whatever happens to be behind it and lose contrast unpredictably; with it,
   the text has a guaranteed floor no matter how the image crops. */
.solution::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    rgba(10, 10, 10, 0.62) 0%,
    rgba(10, 10, 10, 0.88) 45%,
    rgba(10, 10, 10, 0.97) 100%
  );
}

/* The solid green panel becomes glass, so the photo now reads *through* the
   copy block instead of being hidden behind it. */
.solution__panel {
  position: relative;
  z-index: 1;
  display: flex;
  width: 509px;
  max-width: 100%;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline-hi);
  background: rgba(255, 255, 255, 0.05);
  -webkit-backdrop-filter: blur(18px) saturate(120%);
  backdrop-filter: blur(18px) saturate(120%);
  box-shadow: var(--shadow-lift);
  padding: 60px;
  overflow: hidden;
}

/* Lime edge-light along the top of the panel — the accent appearing as a
   physical highlight rather than as another block of colour. */
.solution__panel::before {
  content: "";
  position: absolute;
  top: 0;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--lime), transparent);
  opacity: 0.7;
}

.solution__panel p {
  color: var(--on-dark-muted);
  line-height: 1.65;
}

@media (max-width: 1023px) {
  /* Stack: photo on top, panel below, rather than covering the photo. */
  .solution {
    display: block;
    min-height: 0;
    padding: 0;
  }

  .solution__photo {
    position: relative;
    height: 280px;
  }

  .solution__panel {
    width: 100%;
    max-width: none;
    padding: 32px;
    border-radius: 0;
  }

  .solution__panel h2 {
    font-size: 32px;
  }

  .solution__panel p {
    font-size: 16px;
  }
}

/* Our Process ------------------------------------------------------------ */

/* Was a full-bleed blue gradient. Now near-black with the blue surviving as a
   single off-centre bloom, so the section still separates from the page above
   it without reintroducing a colour block. */
.process {
  position: relative;
  overflow: hidden;
  background: var(--page);
  border-block: 1px solid var(--hairline);
  isolation: isolate;
}

.process::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(48% 44% at 20% 0%, rgba(7, 78, 135, 0.55), transparent 66%),
    radial-gradient(40% 40% at 88% 100%, rgba(198, 255, 0, 0.06), transparent 66%);
}

.process-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 20px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background: var(--glass);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: var(--shadow-card);
  padding: 29px;
  overflow: hidden;
  transition: transform 0.45s var(--ease-out), border-color 0.45s ease,
    background-color 0.45s ease, box-shadow 0.45s var(--ease-out);
}

.process-card::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s var(--ease-out);
  background: radial-gradient(60% 55% at 22% 0%, var(--lime-glow), transparent 70%);
}

.process-card:hover {
  transform: translateY(-6px);
  border-color: rgba(198, 255, 0, 0.28);
  background: var(--glass-hi);
  box-shadow: var(--shadow-lift);
}

.process-card:hover::before {
  opacity: 1;
}

/* The six process icons keep their vivid multicolour — they read well on black
   and supply the variety that stops the page going monotone lime. The tile
   around them is what changes: a glass chip instead of a white square. */
.process-card__icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  flex: 0 0 auto;
  border-radius: 12px;
  border: 1px solid var(--hairline);
  background: var(--glass-hi);
  transition: transform 0.45s var(--ease-out), box-shadow 0.45s var(--ease-out);
}

.process-card:hover .process-card__icon {
  transform: scale(1.08);
  box-shadow: 0 0 24px rgba(198, 255, 0, 0.18);
}

.process-card__icon img {
  width: 30px;
  height: 30px;
}

.process-card__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  color: var(--ink);
}

/* Figma nests title+body in their own 16px-gap stack inside the 20px stack. */
.process-card__title + .process-card__body {
  margin-top: -4px;
}

.process-card__body {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 18px;
  color: var(--body);
}

@media (max-width: 767px) {
  .process-card__body {
    font-size: 16px;
  }
}

/* Why Us ----------------------------------------------------------------- */

/* Figma 87:142: 525px image + 40px gap + 645px card column = 1210. */
.why {
  display: grid;
  grid-template-columns: 525px 645px;
  gap: 40px;
  align-items: start;
  justify-content: center;
}

.why__media {
  position: relative;
  height: 632px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  overflow: hidden;
}

.why__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A dark vignette so the photo sits *in* the page rather than punching a
   bright rectangle through it. */
.why__media::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(10, 10, 10, 0.1) 0%,
    rgba(10, 10, 10, 0.55) 100%
  );
}

/* Image reveal: the photo wipes up behind a clip-path mask when it enters
   view. clip-path is composited, so this costs nothing to animate. */
.js .why__media[data-animate="reveal"] {
  clip-path: inset(0 0 100% 0);
  opacity: 1;
  transform: none;
}

.js .why__media[data-animate="reveal"].is-inview {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1s var(--ease-out);
}

.why__list {
  display: flex;
  flex-direction: column;
  gap: 27px;
}

.why-card {
  position: relative;
  display: flex;
  gap: 20px;
  align-items: flex-start;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background: var(--glass);
  box-shadow: var(--shadow-card);
  padding: 25px;
  overflow: hidden;
  transition: transform 0.45s var(--ease-out), border-color 0.45s ease,
    background-color 0.45s ease;
}

/* Each card's glow starts from a different corner, so a vertical stack of
   three doesn't read as the same unit repeated down the column. */
.why-card::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s var(--ease-out);
  background: radial-gradient(
    55% 70% at var(--glow-x, 50%) var(--glow-y, 0%),
    var(--lime-glow),
    transparent 70%
  );
}

.why__list .why-card:nth-child(1) {
  --glow-x: 8%;
  --glow-y: 0%;
}
.why__list .why-card:nth-child(2) {
  --glow-x: 92%;
  --glow-y: 50%;
}
.why__list .why-card:nth-child(3) {
  --glow-x: 50%;
  --glow-y: 100%;
}

.why-card:hover {
  transform: translateX(6px);
  border-color: rgba(198, 255, 0, 0.24);
  background: var(--glass-hi);
}

.why-card:hover::before {
  opacity: 1;
}

.why-card__icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 70px;
  height: 70px;
  flex: 0 0 auto;
  border-radius: 18px;
  border: 1px solid var(--hairline);
  background: var(--glass-hi);
  transition: transform 0.45s var(--ease-out);
}

.why-card:hover .why-card__icon {
  transform: scale(1.06);
}

.why-card__icon img {
  width: 44px;
  height: 44px;
}

.why-card__text {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.why-card__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  color: var(--ink);
}

.why-card__body {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 18px;
  color: var(--body);
}

@media (max-width: 1279px) {
  /* Let the two columns share the row fluidly before stacking. */
  .why {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  }
}

@media (max-width: 1023px) {
  .why {
    grid-template-columns: 1fr;
  }

  .why__media {
    height: 320px;
  }
}

@media (max-width: 767px) {
  .why-card {
    padding: 20px;
    gap: 14px;
  }

  .why-card__icon {
    width: 54px;
    height: 54px;
    border-radius: 14px;
  }

  .why-card__icon img {
    width: 32px;
    height: 32px;
  }

  .why-card__body {
    font-size: 16px;
  }
}

/* Clutch review strip ---------------------------------------------------- */

/* Figma 71:25236 — logo, five stars, caption; 20px vertical rhythm. */
.clutch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.clutch__logo {
  width: 168px;
  height: 48px;
  object-fit: contain;
}

.clutch__stars {
  display: flex;
  align-items: center;
  gap: 10px;
}

.clutch__stars img {
  width: 24px;
  height: 24px;
  /* drop-shadow rather than box-shadow: the glow follows the star's actual
     outline instead of its bounding box. Static, so it never repaints. */
  filter: drop-shadow(0 0 8px rgba(198, 255, 0, 0.45));
}

/* The Clutch mark ships dark-on-transparent for the old light page. Inverting
   is the honest fix here — it is a third-party logo and recolouring the file
   would misrepresent their brand asset. */
.clutch__logo {
  filter: brightness(0) invert(1);
  opacity: 0.9;
}

.clutch__caption {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 18px;
  color: var(--body);
  text-align: center;
}

@media (max-width: 767px) {
  .clutch__logo {
    width: 132px;
    height: 38px;
  }

  .clutch__stars {
    gap: 8px;
  }

  .clutch__stars img {
    width: 20px;
    height: 20px;
  }

  .clutch__caption {
    font-size: 16px;
  }
}

/* Testimonials carousel -------------------------------------------------- */

/* Figma 71:25206: 773x379 slides, 20px gap, centred with neighbours peeking.
   The track is full-bleed; JS translates it so the active slide is centred. */
.tst {
  --slide-w: 773px;
  --slide-gap: 20px;
}

.tst__viewport {
  overflow: hidden;
  /* Grabbable, and stops the browser hijacking horizontal drags as scroll. */
  cursor: grab;
  touch-action: pan-y;
}

.tst__viewport.is-dragging {
  cursor: grabbing;
}

.tst__viewport:focus-visible {
  outline: 2px solid var(--lime);
  outline-offset: 4px;
}

.tst__track {
  display: flex;
  gap: var(--slide-gap);
  align-items: stretch;
  will-change: transform;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.tst__track.is-dragging {
  transition: none;
}

.tst__slide {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  flex: 0 0 var(--slide-w);
  width: var(--slide-w);
  min-height: 379px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  padding: 39px;
  overflow: hidden;
  /* JS sets --bg per slide from a shuffled palette of low-alpha dark tints. */
  background: var(--bg, rgba(255, 255, 255, 0.04));
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: var(--shadow-card);
  /* Neighbours recede so the centred slide reads as active. */
  opacity: 0.4;
  transform: scale(0.94);
  transition: opacity 0.5s ease, transform 0.5s ease, border-color 0.5s ease;
}

.tst__slide.is-active {
  opacity: 1;
  transform: scale(1);
  border-color: var(--hairline-hi);
}

/* Oversized quotation mark set behind the copy. Purely typographic decoration
   — it is a CSS glyph, so it adds no markup and no image request. */
.tst__slide::before {
  content: "\201C";
  position: absolute;
  top: -38px;
  left: 24px;
  font-family: var(--font-display);
  font-size: 180px;
  font-weight: 700;
  line-height: 1;
  color: var(--lime);
  opacity: 0.14;
  pointer-events: none;
  user-select: none;
}

.tst__quote {
  position: relative;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 24px;
  line-height: 1.5;
  text-align: center;
  color: var(--ink);
}

.tst__person {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-top: auto;
}

.tst__avatar {
  width: 70px;
  height: 70px;
  border-radius: 9999px;
  object-fit: cover;
}

.tst__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  color: var(--ink);
}

.tst__role {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 18px;
  color: var(--body);
}

/* Bullet pagination ------------------------------------------------------ */

.tst__dots {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  margin-top: 32px;
}

.tst__dot {
  width: 10px;
  height: 10px;
  padding: 0;
  border: 0;
  border-radius: 9999px;
  background: rgba(255, 255, 255, 0.2);
  cursor: pointer;
  transition: width 0.3s ease, background-color 0.3s ease, box-shadow 0.3s ease;
}

.tst__dot:hover {
  background: rgba(255, 255, 255, 0.45);
}

.tst__dot.is-active {
  width: 28px;
  background: var(--lime);
  box-shadow: 0 0 14px rgba(198, 255, 0, 0.5);
}

@media (max-width: 1023px) {
  .tst {
    --slide-w: 620px;
  }

  .tst__quote {
    font-size: 20px;
  }
}

@media (max-width: 767px) {
  /* Below this the peek is too tight to be useful — go near-full-width. */
  .tst {
    --slide-w: 86vw;
    --slide-gap: 12px;
  }

  .tst__slide {
    padding: 24px;
    min-height: 0;
  }

  .tst__quote {
    font-size: 16px;
  }

  .tst__role {
    font-size: 16px;
  }
}

/* How It Works ----------------------------------------------------------- */

/* The #fff4ff panel becomes glass over the page. */
.how-panel {
  position: relative;
  border: 1px solid var(--hairline);
  background: var(--glass);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.how-panel hr {
  border-top-color: var(--hairline);
}

.step {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: flex-start;
}

/* A hairline running from each step's numeral toward the next, so the three
   read as a sequence rather than three unrelated columns. Suppressed on the
   last step and below the breakpoint where the grid stops being a row. */
@media (min-width: 1024px) {
  .step::before {
    content: "";
    position: absolute;
    top: 26px;
    left: 62px;
    right: -20px;
    height: 1px;
    background: linear-gradient(90deg, rgba(198, 255, 0, 0.4), transparent);
  }

  .step:last-child::before {
    display: none;
  }
}

.step__num {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 56px;
  line-height: 0.9;
  letter-spacing: -0.03em;
  color: var(--lime);
}

.step__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  color: var(--ink);
}

.step__body {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 18px;
  color: var(--body);
}

@media (max-width: 767px) {
  .step__num {
    font-size: 40px;
  }

  .step__body {
    font-size: 16px;
  }
}

/* Growth Audit ----------------------------------------------------------- */

/* Figma 77:189: 598px visual + 40px gap + 572px copy = 1210. */
.audit {
  display: grid;
  grid-template-columns: 598px 572px;
  gap: 40px;
  align-items: start;
  justify-content: center;
}

.audit__media {
  position: relative;
  height: 444px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  overflow: hidden;
  /* Figma layers the photo over a purple gradient; the gradient shows through
     wherever the cut-out photo is transparent. Deepened for the dark page —
     the original pastel purple glowed against #0A0A0A. */
  background: linear-gradient(127.75deg, #3b2f7a 0%, #1b1440 97.82%);
}

/* Image reveal, matching the Why Us treatment. */
.js .audit__media[data-animate="reveal"] {
  clip-path: inset(0 0 100% 0);
  opacity: 1;
  transform: none;
}

.js .audit__media[data-animate="reveal"].is-inview {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1s var(--ease-out);
}

.audit__media img {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  /* Figma: 988x556 image inside a 598x444 frame — it overflows and is clipped. */
  width: 988px;
  max-width: none;
  height: 556px;
  object-fit: cover;
}

.audit__copy {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.audit__how {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  color: var(--ink);
}

.audit__item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

/* Figma centres the 20px icon inside a 24px box. */
.audit__check {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  margin: 2px;
}

.audit__item p {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 18px;
  color: var(--body);
}

@media (max-width: 1279px) {
  .audit {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  /* The photo is fixed-width, so keep it covering as the frame narrows. */
  .audit__media img {
    left: 0;
    transform: none;
    width: 100%;
    height: 100%;
  }
}

@media (max-width: 1023px) {
  .audit {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  .audit__copy {
    gap: 32px;
  }
}

@media (max-width: 767px) {
  .audit__media {
    height: 300px;
  }

  .audit__item p {
    font-size: 16px;
  }
}

/* Contact ---------------------------------------------------------------- */

/* Figma 71:25272 — full-bleed gradient at ~-63deg. Inner grid is
   641px (photo) + 39px gap + 600px (form) = 1280, with 80px page padding. */
.contact {
  position: relative;
  overflow: hidden;
  background: var(--page);
  border-top: 1px solid var(--hairline);
  isolation: isolate;
}

/* Ambient bloom behind the form. The blue is warmest directly behind the card,
   which is what draws the eye to the one place on the page we want a click. */
.contact::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(44% 52% at 78% 42%, rgba(7, 78, 135, 0.62), transparent 66%),
    radial-gradient(38% 40% at 14% 88%, rgba(198, 255, 0, 0.07), transparent 66%);
}

.contact__lede {
  font-size: 18px;
  font-weight: 300;
  line-height: 1.65;
  color: var(--on-dark-muted);
}

.contact__inner {
  display: grid;
  grid-template-columns: 641px 600px;
  gap: 39px;
  /* stretch, not start: the card holds a short CTA rather than five fields, so
     it takes its height from the header + photo column and centres inside. */
  align-items: stretch;
  justify-content: center;
  max-width: 1440px;
  margin-inline: auto;
  padding: 80px;
}

.contact__left {
  display: flex;
  flex-direction: column;
  /* Figma: header sits at y=80, photo at y=263 — ~35px below the header. */
  gap: 35px;
}

.contact__media {
  height: 452px;
  border-radius: 20px;
  overflow: hidden;
}

.contact__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Glassy form card ------------------------------------------------------- */

.contact__card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--hairline-hi);
  background: rgba(255, 255, 255, 0.045);
  -webkit-backdrop-filter: blur(20px) saturate(130%);
  backdrop-filter: blur(20px) saturate(130%);
  box-shadow: var(--shadow-lift);
  padding: 39px;
}

/* Lime edge-light along the card's top, matching the Solution panel. */
.contact__card::after {
  content: "";
  position: absolute;
  top: 0;
  left: 15%;
  right: 15%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--lime), transparent);
  opacity: 0.6;
  pointer-events: none;
}

/* Decorative glow bleeding off the card's top-right (Figma 71:25301). */
.contact__glow {
  position: absolute;
  top: -88px;
  left: 379px;
  width: 339px;
  height: 339px;
  max-width: none;
  pointer-events: none;
}

/* The card is far shorter than the header + photo beside it now that it holds
   three elements rather than five fields, so it stretches to the left column's
   height (see .contact__inner) and centres its content in the space. */
.contact__cta {
  position: relative;
  z-index: 1;
  display: flex;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  text-align: center;
}

.contact__cta-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(28px, 2.6vw, 38px);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: #ffffff;
}

.contact__cta-text {
  max-width: 42ch;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 16px;
  line-height: 1.7;
  color: var(--on-dark-muted);
}

/* The decorative glow asset was drawn for the blue card; on black it reads as
   a grey smear at full strength. */
.contact__glow {
  opacity: 0.35;
  mix-blend-mode: screen;
}

@media (max-width: 1279px) {
  .contact__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    padding: 64px 48px;
  }
}

@media (max-width: 1023px) {
  .contact__inner {
    grid-template-columns: 1fr;
    gap: 32px;
    padding: 56px 32px;
  }

  .contact__media {
    height: 320px;
  }

  .contact__left h2 {
    font-size: 38px;
  }
}

@media (max-width: 767px) {
  .contact__inner {
    padding: 40px 20px;
  }

  .contact__card {
    padding: 24px;
  }

  .contact__left h2 {
    font-size: 30px;
  }

  .contact__left p {
    font-size: 16px;
  }

  .contact__media {
    height: 240px;
  }
}

/* FAQ accordion ---------------------------------------------------------- */

.faq-item {
  position: relative;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--glass);
  padding: 30px 24px;
  overflow: hidden;
  transition: border-color 0.35s ease, background-color 0.35s ease;
}

.faq-item:hover {
  border-color: var(--hairline-hi);
  background: var(--glass-hi);
}

/* The open item is marked with a lime rail down its left edge — a state cue
   that survives even when the panel content is scrolled past. */
.faq-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--lime);
  transform: scaleY(0);
  transform-origin: top center;
  transition: transform 0.4s var(--ease-out);
}

.faq-item:has(.faq-item__q[aria-expanded="true"]) {
  border-color: rgba(198, 255, 0, 0.22);
  background: var(--glass-hi);
}

.faq-item:has(.faq-item__q[aria-expanded="true"])::before {
  transform: scaleY(1);
}

.faq-item__q {
  display: flex;
  width: 100%;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  color: var(--ink);
}

.faq-item__icon {
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  transition: transform 0.25s ease;
}

/* Figma shows the open item's chevron rotated -90deg. */
.faq-item__q[aria-expanded="true"] .faq-item__icon {
  transform: rotate(-90deg);
}

/* Collapsed by max-height so the toggle can animate. */
.faq-item__a {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

.faq-item__a p {
  padding-top: 12px;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 18px;
  color: var(--body);
}

@media (max-width: 767px) {
  .faq-item__q {
    font-size: 17px;
  }

  .faq-item__a p {
    font-size: 16px;
  }
}

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

/* The footer was a solid blue slab. It becomes the page colour with a single
   lime hairline across the top — the last appearance of the accent, closing
   the page the same way the header opens it. */
.site-footer {
  position: relative;
  background: var(--page);
}

.site-footer::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(198, 255, 0, 0.55) 30%,
    rgba(198, 255, 0, 0.55) 70%,
    transparent
  );
}

.site-footer p {
  color: var(--body);
}

/* Scoped past `.site-footer li > a` below — that rule's `display: block` outranks
   a bare `.social-round`, which strands the glyph at the top of the circle. */
.site-footer li > a.social-round {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 9999px;
  border: 1px solid var(--hairline);
  background: var(--glass);
  transition: transform 0.3s var(--ease-out), background-color 0.3s ease,
    border-color 0.3s ease, box-shadow 0.3s ease;
}

.site-footer li > a {
  display: block;
  transition: transform 0.3s var(--ease-out);
}

.site-footer li > a:hover {
  transform: translateY(-3px);
}

.social-round:hover {
  background: var(--glass-hi);
  border-color: rgba(198, 255, 0, 0.35);
  box-shadow: 0 0 20px rgba(198, 255, 0, 0.2);
}

/* Focus ------------------------------------------------------------------ */

/* Lime at 16.7:1 on the page colour — the most visible focus ring available
   on this palette, and the same colour as every other interactive affordance
   so the keyboard path reads as the same system as the pointer path. */
:focus-visible {
  outline: 2px solid var(--lime);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: 16px;
  z-index: 200;
  background: var(--lime);
  color: var(--lime-ink);
  padding: 12px 20px;
  border-radius: 999px;
  font-weight: 700;
  transition: top 0.2s ease;
}

.skip-link:focus {
  top: 16px;
}

/* --------------------------------------------------------------------------
   Responsive: scale the Figma desktop values down
   -------------------------------------------------------------------------- */

/* Responsive 16:9 video embed */
.video-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 16px;
  overflow: hidden;
}

.video-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

@media (max-width: 1279px) {
  :root {
    --gutter: 48px;
  }
}

@media (max-width: 1023px) {
  :root {
    --gutter: 32px;
  }
}

/* .h-section and .h-hero size themselves with clamp(), so the per-breakpoint
   font-size overrides that used to live here are gone — they would have
   fought the fluid scale rather than refined it. */

@media (max-width: 767px) {
  :root {
    --gutter: 20px;
  }

  .p-section {
    font-size: 16px;
  }

  .badge {
    font-size: 14px;
  }

  .problem-card__num,
  .step__num {
    font-size: 44px;
  }

  .tst__slide::before {
    font-size: 120px;
    top: -24px;
  }
}
