/* ==========================================================================
   Perfect Solutions — stylesheet
   Single, hand-organised CSS file. Sections below, in order:
   1. Fonts          5. Layout & sections   9.  Ledger Rule (signature device)
   2. Tokens         6. Header & nav        10. Logo grid
   3. Reset          7. Footer              11. Forms
   4. Typography     8. Buttons & links     12. Page-specific components
                                             13. Scroll reveal & motion
   ========================================================================== */

/* ---------- 1. Fonts ---------- */
/* Montserrat — loaded via Google Fonts <link> in each page <head>.
   Gotham (used by nerdwallet.com) is a commercial font we don't have a licence
   for; Montserrat is the standard free substitute — same geometric, boxy
   proportions. */

/* ---------- 2. Tokens ---------- */
:root {
  /* Brand — fixed system, do not add colours outside this set */
  --primary: #1E40AF;
  --secondary: #2563EB;
  --accent: #DBEAFE;
  --white: #FFFFFF;
  --body-text: #1F2937;
  --muted: #64748B;      /* derived neutral: captions, secondary text */
  --hairline: #E2E8F0;   /* derived neutral: fine rules only */

  /* Type families */
  --font-display: 'Montserrat', 'Arial Black', 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'Montserrat', -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;

  /* Type scale */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-md: 1.125rem;
  --text-lg: 1.375rem;
  --text-xl: 1.75rem;
  --text-2xl: 2.25rem;
  --text-3xl: 2.75rem;
  --text-4xl: 3.5rem;
  --text-5xl: 4.25rem;

  /* Spacing scale (8px base grid) */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;

  /* Structure */
  --container-max: 72rem;
  --measure: 68ch;
  --radius-sm: 10px;
  --radius-md: 18px;
  --radius-pill: 999px;

  /* Deep navy — hero bands and other high-contrast moments, derived from the two brand blues */
  --navy-deep: #0A1330;
  --navy-mid: #142868;
  --hero-photo-navy: #102440; /* sampled directly from the hero photo's wall colour, so the overlay blends seamlessly into the image */

  /* WhatsApp brand green — used only for WhatsApp entry points, not part of the general palette */
  --whatsapp-green: #25D366;
  --whatsapp-green-dark: #1DA851;

  /* Warm gold — used only for the hero headline emphasis word, not part of the general palette.
     --accent (#DBEAFE) is too close to --white against the dark hero photo to read as emphasis. */
  --hero-gold: #F5B942;

  /* Shadows — cool-toned (never plain black) so depth still reads as part of the blue system */
  --shadow-sm: 0 1px 2px rgba(10, 19, 48, 0.06), 0 1px 1px rgba(10, 19, 48, 0.05);
  --shadow-md: 0 10px 26px rgba(10, 19, 48, 0.14), 0 2px 8px rgba(10, 19, 48, 0.08);
  --shadow-lg: 0 24px 60px rgba(10, 19, 48, 0.28), 0 8px 20px rgba(10, 19, 48, 0.14);

  /* Motion */
  --ease-entrance: cubic-bezier(0.22, 1, 0.36, 1);
  --duration-entrance: 550ms;
  --duration-fast: 180ms;
}

/* ---------- 3. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
/* Kill the default mobile tap-highlight rectangle — it ignores border-radius,
   so it shows up as a flat grey square over pill/circular buttons like nav-toggle. */
a, button { -webkit-tap-highlight-color: transparent; }
body {
  margin: 0;
  background: var(--white);
  color: var(--body-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
body.nav-open { overflow: hidden; }
img, picture, svg { display: block; max-width: 100%; height: auto; }
input, button, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p, figure { margin: 0; }
a { color: inherit; text-decoration: none; }
table { border-collapse: collapse; width: 100%; }

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

/* ---------- 4. Typography ---------- */
h1, h2, h3, h4, .font-display {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  color: var(--primary);
  letter-spacing: -0.01em;
}
h1 { font-size: var(--text-4xl); letter-spacing: -0.02em; }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-lg); }
h4 { font-size: var(--text-md); font-family: var(--font-body); font-weight: 600; letter-spacing: 0; color: var(--body-text); }

@media (min-width: 60rem) {
  h1 { font-size: var(--text-5xl); letter-spacing: -0.03em; }
  h2 { font-size: var(--text-3xl); }
  h3 { font-size: var(--text-xl); }
}

p { max-width: var(--measure); }
p + p { margin-top: var(--space-4); }
.lead { font-size: var(--text-md); color: var(--body-text); }

.eyebrow {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--space-3);
}

.tabular-nums { font-variant-numeric: tabular-nums lining-nums; }

.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }

.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: var(--space-3);
  top: var(--space-3);
  background: var(--primary);
  color: var(--white);
  padding: var(--space-3) var(--space-4);
  z-index: 100;
  transform: translateY(-150%);
  transition: transform var(--duration-fast) ease;
}
.skip-link:focus { transform: translateY(0); }

/* Focus states — designed, not browser default */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--secondary);
  outline-offset: 2px;
}

/* ---------- 5. Layout & sections ---------- */
.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}
@media (min-width: 60rem) {
  .container { padding-inline: var(--space-6); }
}
.container--narrow { max-width: 46rem; }

/* Section rhythm. Every section pads both edges, so the visible gap between
   two of them is double this — keep that in mind before nudging it up. */
.section {
  padding-block: var(--space-7);
}
@media (min-width: 60rem) {
  .section { padding-block: var(--space-8); }
}
.section--accent { background: var(--accent); }
.section--bordered { border-top: 1px solid var(--hairline); }

.section-header {
  max-width: 42rem;
  margin-bottom: var(--space-7);
}
.section-header--center { margin-inline: auto; text-align: center; }

.grid {
  display: grid;
  gap: var(--space-6);
}
@media (min-width: 60rem) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
}

.split {
  display: grid;
  gap: var(--space-7);
  align-items: start;
}
@media (min-width: 64rem) {
  .split { grid-template-columns: 1.2fr 1fr; gap: var(--space-9); }
  .split--wide-right { grid-template-columns: 1fr 1.2fr; }
}

/* ---------- 6. Header & nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--white);
  border-bottom: 1px solid var(--hairline);
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-3);
}
.header-left {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  color: var(--primary);
}
.brand img { height: 2rem; width: auto; }
/* Below the nav breakpoint the full horizontal wordmark is too wide to fit next
   to the hamburger — swap it for the compact stacked lockup instead (mark stays
   visible at every size). Matches nerdwallet's own compact header. */
.brand__wordmark { display: none; }
.brand__stacked { display: block; height: 2.25rem; }
@media (min-width: 64rem) {
  .brand img { height: 1.5rem; }
  .brand__wordmark { display: block; }
  .brand__stacked { display: none; }
}

.primary-nav {
  display: none;
}
@media (min-width: 64rem) {
  .primary-nav {
    display: flex;
    align-items: center;
    gap: var(--space-4);
  }
  .primary-nav a {
    font-size: var(--text-sm);
    font-weight: 500;
    padding-block: var(--space-2);
    border-bottom: 2px solid transparent;
    transition: border-color var(--duration-fast) ease, color var(--duration-fast) ease;
  }
  .primary-nav a:hover,
  .primary-nav a[aria-current="page"] {
    color: var(--primary);
    border-bottom-color: var(--secondary);
  }
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  transition: border-color var(--duration-fast) ease, background-color var(--duration-fast) ease;
}
.nav-toggle:hover { border-color: var(--secondary); background: var(--accent); }
@media (min-width: 64rem) {
  .nav-toggle { display: none; }
}

/* Hamburger — MDB's "animated-icon1": three bars that morph in place into an X.
   Kept framework-free (no MDB/Bootstrap JS) — keyed off aria-expanded, already
   toggled by main.js, standing in for MDB's own "open" class. */
.animated-icon1 {
  width: 22px;
  height: 16px;
  position: relative;
  margin: 0;
  transform: rotate(0deg);
  transition: .5s ease-in-out;
}
.animated-icon1 span {
  display: block;
  position: absolute;
  height: 2px;
  width: 100%;
  border-radius: 2px;
  background: currentColor;
  opacity: 1;
  left: 0;
  transform: rotate(0deg);
  transition: .25s ease-in-out;
}
.animated-icon1 span:nth-child(1) { top: 0px; }
.animated-icon1 span:nth-child(2) { top: 7px; }
.animated-icon1 span:nth-child(3) { top: 14px; }
.nav-toggle[aria-expanded="true"] .animated-icon1 span:nth-child(1) { top: 7px; transform: rotate(135deg); }
.nav-toggle[aria-expanded="true"] .animated-icon1 span:nth-child(2) { opacity: 0; left: -22px; }
.nav-toggle[aria-expanded="true"] .animated-icon1 span:nth-child(3) { top: 7px; transform: rotate(-135deg); }

/* Backdrop behind the sliding drawer */
.mobile-nav-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 19, 48, 0.45);
  z-index: 30;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-entrance) ease;
}
.mobile-nav-backdrop.is-open { opacity: 1; pointer-events: auto; }
@media (min-width: 64rem) {
  .mobile-nav-backdrop { display: none !important; }
}

/* Drawer — slides in from the left, under the sticky header (z-index 40) so
   the hamburger/X stays reachable to close it, nerdwallet-style. */
.mobile-nav {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 35;
  width: min(20rem, 84vw);
  background: var(--white);
  box-shadow: var(--shadow-lg);
  overflow-y: auto;
  padding-top: var(--space-8);
  transform: translateX(-100%);
  transition: transform var(--duration-entrance) var(--ease-entrance);
}
.mobile-nav.is-open { transform: translateX(0); }
@media (min-width: 64rem) {
  .mobile-nav { display: none !important; }
}
.mobile-nav ul { padding: var(--space-4) var(--space-5); display: flex; flex-direction: column; gap: var(--space-1); }
.mobile-nav a {
  display: block;
  padding: var(--space-3) 0;
  font-size: var(--text-md);
  border-bottom: 1px solid var(--hairline);
}
/* ---------- 7. Footer ---------- */
.site-footer {
  background: var(--white);
  border-top: 1px solid var(--hairline);
  padding-block: var(--space-8);
}
.footer-grid {
  display: grid;
  gap: var(--space-7);
}
@media (min-width: 48rem) {
  .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; }
}
.footer-brand__logo { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-4); }
.footer-brand__logo img { height: 3.5rem; width: auto; }
.footer-brand__name {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  color: var(--primary);
  margin-bottom: var(--space-4);
}
.footer-brand p { color: var(--muted); font-size: var(--text-sm); max-width: 28ch; }
.footer-heading {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--space-4);
}
.footer-links li { margin-bottom: var(--space-2); }
.footer-links a { font-size: var(--text-sm); color: var(--body-text); }
.footer-links a:hover { color: var(--secondary); }
.footer-bottom {
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--muted);
}
.footer-disclaimer {
  max-width: none;
  font-size: var(--text-xs);
  color: var(--muted);
  line-height: 1.6;
  margin-top: var(--space-5);
}

/* ---------- 8. Buttons & links ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-6);
  font-size: var(--text-sm);
  font-weight: 600;
  white-space: nowrap;
  flex-shrink: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  transition: background-color var(--duration-fast) ease, color var(--duration-fast) ease,
              border-color var(--duration-fast) ease, transform var(--duration-fast) ease,
              box-shadow var(--duration-fast) ease;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-primary { background: var(--primary); color: var(--white); box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: #16307f; box-shadow: var(--shadow-md); }
.btn-secondary { background: transparent; color: var(--primary); border-color: var(--primary); }
.btn-secondary:hover { background: var(--primary); color: var(--white); }
.btn-ghost { background: transparent; color: var(--body-text); border-color: var(--hairline); }
.btn-ghost:hover { border-color: var(--secondary); color: var(--secondary); }
.btn-whatsapp { background: var(--whatsapp-green); color: var(--white); border-color: var(--whatsapp-green); }
.btn-whatsapp:hover { background: var(--whatsapp-green-dark); border-color: var(--whatsapp-green-dark); }

.text-link {
  color: var(--secondary);
  border-bottom: 1px solid transparent;
  background-image: linear-gradient(var(--secondary), var(--secondary));
  background-size: 0% 1px;
  background-repeat: no-repeat;
  background-position: left bottom;
  transition: background-size var(--duration-fast) ease;
  padding-bottom: 1px;
}
.text-link:hover { background-size: 100% 1px; }

/* On accent (pale) surfaces, emphasis must use primary — enforced here, not left to chance */
.section--accent .text-link,
.section--accent a:not(.btn) { color: var(--primary); background-image: linear-gradient(var(--primary), var(--primary)); }

/* ---------- 9. Ledger Rule — signature device ---------- */
.ledger { display: flex; flex-direction: column; gap: var(--space-4); }
.ledger__row {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: var(--space-5);
  padding: var(--space-6);
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--duration-fast) ease, transform var(--duration-fast) ease;
}
.ledger__row:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
@media (min-width: 48rem) {
  .ledger__row { grid-template-columns: 4rem 1fr; padding: var(--space-7); }
}
.ledger__index {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-pill);
  background: var(--primary);
  color: var(--white);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  font-variant-numeric: tabular-nums;
}
.ledger__label { font-size: var(--text-md); font-weight: 600; margin-bottom: var(--space-2); color: var(--body-text); }
.ledger__body { color: var(--body-text); }
.ledger__body p { color: var(--muted); }

/* "Why homebuyers trust us" — a direct port of NerdWallet's own
   "hp_why_trust_element" section: same DOM shape, same breakpoint
   behavior, same spacing values (translated 1:1 from their Tailwind
   classes into rem/px). Only colors, copy, and asset paths are ours. */
.trust-section { padding-inline: 1rem; overflow-x: hidden; }
.trust-heading-mobile { margin-bottom: 2rem; }
@media (min-width: 60rem) { .trust-heading-mobile { display: none; } }
.trust-heading-mobile h2 {
  margin: 0;
  font-size: 28px;
  line-height: 34px;
  font-weight: 500;
  letter-spacing: -0.3px;
  color: var(--primary);
}
.trust__row {
  max-width: var(--container-max);
  margin-inline: auto;
  display: flex;
  flex-direction: row-reverse;
  align-items: stretch;
  justify-content: space-between;
  gap: 2rem;
}
@media (min-width: 60rem) {
  .trust__row { flex-direction: row; align-items: center; gap: 4rem; }
}
.trust__photo {
  position: relative;
  z-index: 10;
  display: flex;
  width: 50%;
  align-items: stretch;
  justify-content: center;
}
@media (min-width: 60rem) {
  .trust__photo { z-index: auto; width: 33.333%; }
}
.trust__photo-blob {
  display: none;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  /* Sized relative to the photo column rather than NerdWallet's fixed
     310x340px (tuned to their own photo's proportions) — a fixed size
     only reliably peeks out past our differently-proportioned photo at
     one specific viewport width. */
  height: 90%;
  width: calc(100% + 2.5rem);
  border-radius: 16px;
  background: linear-gradient(31deg, var(--accent) -3.72%, transparent 145.93%);
}
@media (min-width: 60rem) {
  .trust__photo-blob { display: block; }
}
.trust__photo-frame {
  position: relative;
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
  /* No rightward bleed on phones: it opened a 66px gutter between the stat
     cards and the photo, and pushed a third of the photo off the screen. */
  margin-right: 0;
  border-radius: 16px;
  overflow: hidden;
}
@media (max-width: 20rem) {
  .trust__photo-frame { display: none; }
}
/* From tablet widths up, the frame's height: 100% never resolves — the column
   height is itself content-driven — so the image falls back to its natural
   aspect and renders at column-width x 1.48. On a phone the stacked stat cards
   are taller than that, so it goes unnoticed; once the column is
   wide enough (around 615px, where the column aspect passes the image aspect)
   the image overtakes the stats, drives the whole row, and
   spills past both the cards and the right edge of the screen.

   Taking the frame out of flow breaks that feedback loop: the stats alone set
   the row height and the photo fills exactly what they leave, tucked right.
   Self-correcting at every width, so no magic heights. Phones keep the
   original in-flow treatment; the 60rem rules below reset this for desktop. */
@media (min-width: 38rem) {
  .trust__photo { position: relative; }
  .trust__photo-frame { position: absolute; inset: 0; margin-right: 0; }
}
@media (min-width: 60rem) {
  .trust__photo-frame { position: relative; inset: auto; width: auto; height: auto; max-height: 500px; margin-right: 0; overflow: visible; border-radius: 0; }
}
.trust__photo-frame img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 16px;
  object-fit: cover;
  object-position: left;
}
/* Once the frame is as wide as it is tall, cover starts cropping vertically
   and cuts the top off her head. Scale the whole photo down to fit instead,
   kept to the right edge, so nothing is cropped at any tablet width. */
@media (min-width: 38rem) {
  .trust__photo-frame img { object-fit: contain; object-position: right center; }
}
@media (min-width: 60rem) {
  .trust__photo-frame img { width: auto; height: auto; max-height: 500px; object-fit: contain; object-position: center; }
}
.trust__content {
  display: flex;
  flex-direction: column;
  width: 50%;
  align-items: flex-start;
  justify-content: space-between;
  text-align: left;
}
@media (min-width: 60rem) {
  .trust__content { width: 66.666%; }
}
.trust__heading-desktop {
  display: none;
  margin: 0 0 2rem;
  font-size: 40px;
  line-height: 48px;
  font-weight: 500;
  letter-spacing: -0.8px;
  color: var(--primary);
}
@media (min-width: 60rem) {
  .trust__heading-desktop { display: block; }
}
.trust__stats {
  display: flex;
  flex-direction: column;
  width: 100%;
  align-items: flex-start;
  gap: 1rem;
}
@media (min-width: 60rem) {
  .trust__stats { display: grid; grid-template-columns: repeat(3, 1fr); column-gap: 88px; row-gap: 1rem; }
}
.trust__stat {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 1.25rem;
}
@media (min-width: 60rem) {
  .trust__stat { padding: 1.25rem 1.25rem 1.25rem 0; }
}
.trust__stat-highlight {
  display: block;
  pointer-events: none;
  position: absolute;
  inset-block: 0;
  right: -52%;
  left: 0;
  border-radius: 12px;
  background: linear-gradient(to right, var(--accent), transparent);
}
@media (min-width: 60rem) {
  .trust__stat-highlight { display: none; }
}
.trust__figure {
  position: relative;
  margin: 0;
  font-size: 28px;
  line-height: 34px;
  font-weight: 500;
  letter-spacing: -0.3px;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}
@media (min-width: 60rem) {
  .trust__figure { font-size: 40px; line-height: 48px; letter-spacing: -0.8px; }
}
.trust__plus { color: var(--hero-gold); }
.trust__label {
  position: relative;
  margin: 0;
  font-size: 1rem;
  line-height: 1.5;
  font-weight: 400;
  color: var(--primary);
}
@media (min-width: 60rem) {
  .trust__label { color: var(--muted); }
}
/* Desktop partner strip — lives inside .trust__content, left-aligned
   label with a single trailing rule. Hidden below the breakpoint in
   favor of the separate, centered .trust__partners-mobile block. */
.trust__partners-desktop { display: none; margin-top: 2.5rem; width: 100%; padding-top: 0.5rem; }
@media (min-width: 60rem) {
  .trust__partners-desktop { display: block; }
}
.trust__partners-desktop .trust__partners-label-row {
  margin-bottom: 1rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
}
.trust__partners-desktop .trust__partners-label {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--muted);
  text-transform: uppercase;
  white-space: nowrap;
}
.trust__partners-desktop .trust__partners-hr,
.trust__partners-mobile .trust__partners-hr {
  height: 1px;
  flex: 1;
  background: var(--hairline);
  border: 0;
  margin: 0;
}
/* Mobile/tablet partner strip — full section width, centered label
   flanked by rule lines on both sides, sits after the row entirely. */
.trust__partners-mobile { display: block; margin-top: 2.5rem; }
@media (min-width: 60rem) {
  .trust__partners-mobile { display: none; }
}
.trust__partners-mobile .trust__partners-label-row {
  margin-bottom: 1rem;
  display: flex;
  width: 100%;
  align-items: center;
  gap: 0.25rem;
}
.trust__partners-mobile .trust__partners-label {
  margin: 0;
  max-width: 14.375rem;
  text-align: center;
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--muted);
  text-transform: uppercase;
}
@media (min-width: 30rem) {
  .trust__partners-mobile .trust__partners-label { max-width: 20rem; }
}
/* Logo marquee — dedicated to this section (opacity-only fade, wide
   gap, edge fade masks as real overlay divs) rather than reusing the
   bolder two-row marquee further down the page. */
.tw-marquee { position: relative; width: 100%; overflow: hidden; }
.tw-marquee__track {
  display: flex;
  align-items: center;
  gap: 4rem;
  width: max-content;
  animation: tw-marquee-scroll 34s linear infinite;
}
@keyframes tw-marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .tw-marquee__track { animation: none; }
  .tw-marquee { overflow-x: auto; }
}
.tw-marquee__item { display: flex; height: 2rem; flex-shrink: 0; align-items: center; justify-content: center; }
@media (min-width: 48rem) {
  .tw-marquee__item { height: 2.5rem; }
}
.tw-marquee__item img { display: block; height: auto; max-height: 100%; width: auto; max-width: none; object-fit: contain; opacity: 0.7; }
.tw-marquee__fade { pointer-events: none; position: absolute; inset-block: 0; z-index: 10; width: 3rem; }
.tw-marquee__fade--left { left: 0; background: linear-gradient(to right, rgba(255, 255, 255, 0.8), transparent); }
.tw-marquee__fade--right { right: 0; background: linear-gradient(to left, rgba(255, 255, 255, 0.8), transparent); }

/* ---------- 10. Logo grid (banking partners) ---------- */
.logo-group { margin-bottom: var(--space-7); }
.logo-group__title {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--space-4);
}
.logo-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border-top: 1px solid var(--hairline);
  border-left: 1px solid var(--hairline);
}
@media (min-width: 40rem) {
  .logo-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 64rem) {
  .logo-grid { grid-template-columns: repeat(6, 1fr); }
}
.logo-grid__item {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  min-height: 5rem;
  transition: background-color var(--duration-fast) ease;
}
.logo-grid__item:hover { background: var(--accent); }
.logo-grid__item img { max-height: 2.25rem; width: auto; filter: grayscale(1); opacity: 0.75; transition: filter var(--duration-fast) ease, opacity var(--duration-fast) ease; }
.logo-grid__item:hover img { filter: grayscale(0); opacity: 1; }
.logo-grid__placeholder {
  font-size: var(--text-xs);
  color: var(--muted);
  text-align: center;
  line-height: 1.3;
}

/* ---------- 11. Forms ---------- */
.form { max-width: 40rem; }
.form-row { margin-bottom: var(--space-5); }
.form-row--split { display: grid; gap: var(--space-5); }
@media (min-width: 40rem) {
  .form-row--split { grid-template-columns: 1fr 1fr; }
}
.form label {
  display: block;
  font-size: var(--text-sm);
  font-weight: 600;
  margin-bottom: var(--space-2);
}
.form input,
.form select,
.form textarea {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--hairline);
  background: var(--white);
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  transition: border-color var(--duration-fast) ease;
}
.form input:hover,
.form select:hover,
.form textarea:hover { border-color: var(--muted); }
.form input:focus-visible,
.form select:focus-visible,
.form textarea:focus-visible { border-color: var(--secondary); }
.form textarea { resize: vertical; min-height: 8rem; }
.form input[type="checkbox"] {
  width: auto;
  display: inline-block;
  margin-right: var(--space-2);
  vertical-align: middle;
}
.form label.form-label--inline { display: inline-flex; align-items: center; font-weight: 400; }
.form-hint { font-size: var(--text-xs); color: var(--muted); margin-top: var(--space-2); }

/* Honeypot — hidden from sighted users and screen readers, left open for bots */
.form-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-status {
  display: none;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-5);
  font-size: var(--text-sm);
}
.form-status.is-visible { display: block; }
.form-status--success { border-color: var(--primary); color: var(--primary); }
.form-status--error { border-color: var(--body-text); color: var(--body-text); }

/* ---------- 12. Page-specific components ---------- */

/* Hero — dark navy band, the site's one deliberately bold surface */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-9);
  background: linear-gradient(155deg, var(--navy-deep) 0%, var(--navy-mid) 55%, var(--primary) 100%);
}
@media (min-width: 60rem) { .hero { padding-block: var(--space-10); } }
.hero .eyebrow { color: var(--accent); }
.hero h1 { color: var(--white); }
.hero__tagline { font-size: var(--text-md); color: rgba(255, 255, 255, 0.82); margin-top: var(--space-4); max-width: var(--measure); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-4); margin-top: var(--space-6); }
.hero__actions--flush { margin-top: 0; }
.hero .btn-primary { background: var(--white); color: var(--primary); }
.hero .btn-primary:hover { background: var(--accent); }
.hero .btn-secondary { background: transparent; color: var(--white); border-color: rgba(255, 255, 255, 0.5); }
.hero .btn-secondary:hover { background: rgba(255, 255, 255, 0.14); border-color: var(--white); color: var(--white); }
.hero-crumb { color: var(--accent); border-bottom: 1px solid rgba(255, 255, 255, 0.35); padding-bottom: 1px; }
.hero-crumb:hover { border-bottom-color: var(--accent); }

/* Photo hero — homepage only. Solid navy on the left fading into the photo on the right. */
.hero--photo {
  background: var(--hero-photo-navy);
  min-height: min(70vh, 640px);
  display: flex;
  align-items: center;
}
.hero--photo .hero-bg {
  position: absolute;
  inset: 0;
  background-image: url('../img/hero/heronewer2.jpeg');
  background-size: cover;
  background-position: right center;
}
/* Below the nav breakpoint, keep the photo present and behind the text (like
   nerdwallet) rather than stacking it above — but give it a FIXED height
   instead of matching the full (text-driven) section height, since that's
   what caused the earlier stretch/zoom: a full-bleed image scaled to cover a
   height that ballooned with every extra wrapped line. */
@media (max-width: 63.9375rem) {
  .hero--photo .hero-bg {
    inset: auto;
    top: 0;
    left: 0;
    right: 0;
    height: 22rem;
    background-image:
      linear-gradient(180deg,
        rgba(16, 36, 64, 0.6) 0%,
        rgba(16, 36, 64, 0.3) 40%,
        rgba(16, 36, 64, 0.55) 70%,
        rgba(16, 36, 64, 1) 100%),
      url('../img/hero/heronewer2.jpeg');
    background-position: center, center 35%;
  }
  .hero--photo::after { display: none; }
}
.hero--photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg,
      var(--hero-photo-navy) 0%,
      var(--hero-photo-navy) 34%,
      rgba(16, 36, 64, 0.72) 46%,
      rgba(16, 36, 64, 0.28) 60%,
      rgba(16, 36, 64, 0) 76%),
    linear-gradient(180deg,
      rgba(16, 36, 64, 0) 0%,
      rgba(16, 36, 64, 0) 78%,
      rgba(16, 36, 64, 0.22) 100%);
}
.hero--photo > .container { position: relative; z-index: 2; width: 100%; }
.hero-highlight { color: var(--hero-gold); }
/* Keep hero copy inside the solid/dark portion of the photo — the gradient stays
   solid until 34% and doesn't clear until 76%, so a column narrower than that
   never spills onto the photo. */
.hero--photo h1,
.hero--photo .hero__tagline,
.hero--photo .hero__actions {
  max-width: 34rem;
}
.hero--photo h1 { font-size: var(--text-3xl); }
@media (min-width: 60rem) {
  .hero--photo h1 { font-size: var(--text-4xl); }
}

/* Floating stat card — overlaps the hero edge, homepage only */
.hero-float {
  display: grid;
  gap: var(--space-5);
  margin-top: var(--space-8);
  padding: var(--space-6);
  background: var(--white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}
@media (min-width: 40rem) {
  .hero-float { grid-template-columns: repeat(3, 1fr); }
}
.hero-float__figure {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-2xl);
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}
.hero-float__label { display: block; margin-top: var(--space-1); font-size: var(--text-xs); color: var(--muted); }

/* Rounded, tinted panel that overlaps the bottom of the photo hero — the rounded
   top corners sit visibly against the hero photo, nerdwallet-style */
.products-panel {
  position: relative;
  z-index: 3;
  margin-top: calc(-1 * var(--space-6));
  margin-bottom: var(--space-8);
  background: var(--accent);
  border-radius: var(--radius-md);
  padding: var(--space-7) var(--space-5);
  box-shadow: var(--shadow-lg);
}
/* Full-bleed edge-to-edge on mobile, nerdwallet-style — only the top corners
   stay rounded, cutting into the hero photo above; the sides run flush with
   the screen instead of leaving a gap inside the container's padding. */
@media (max-width: 59.9375rem) {
  .products-panel {
    margin-inline: calc(-1 * var(--space-5));
    border-radius: var(--radius-md) var(--radius-md) 0 0;
  }
}
@media (min-width: 60rem) {
  .products-panel { margin-top: calc(-1 * var(--space-9)); padding: var(--space-8) var(--space-7); margin-bottom: var(--space-10); }
}
.products-panel .section-header { margin-bottom: var(--space-6); }

/* Scrolling ribbon banner — two full-bleed, oppositely-rotated marquee bands
   (navy over blue, gold accents), each looping seamlessly via a doubled
   track translated by -50%. Purely decorative, so it's inert to screen
   readers and disabled for reduced-motion users. */
.ribbon {
  position: relative;
  overflow: hidden;
  /* Both bands pivot on the same centre, so the vertical daylight between
     them at the edges equals the rise a band sweeps across its own width:
     width * tan(angle). Fixing the *angle* therefore ties the gap to the
     viewport — it grew with width, and the old 4deg/11deg breakpoint swap
     made it jump outright. Fixing the *rise* and deriving the angle from it
     keeps the gap identical at every width instead. */
  /* Capped against width so shrinking the page can only ever reduce the
     gap, never grow it: below ~400px the rise tapers with the viewport. */
  --ribbon-rise: min(4.25rem, 17vw);
  /* Bands are 106% of .ribbon, which is itself capped at 100rem. */
  --ribbon-band-width: min(106vw, 106rem);
  --ribbon-angle: atan2(var(--ribbon-rise), var(--ribbon-band-width));
  /* The band box plus the rise it sweeps: no clipped corners, no dead space. */
  height: calc(3.75rem + var(--ribbon-rise));
  max-width: 100rem;
  margin-inline: auto;
}
.ribbon__band {
  position: absolute;
  left: -3%;
  width: 106%;
  /* Both bands share this exact pivot (their own center, landed on
     .ribbon's center via top:50%/translateY(-50%)) so the two opposing
     rotations cross exactly at the middle instead of off to one side. */
  top: 50%;
  overflow: hidden;
  padding-block: var(--space-3);
  box-shadow: 0 4px 16px rgba(10, 19, 48, 0.12);
  backface-visibility: hidden;
  will-change: transform;
}
/* A shallow angle keeps the two bands nearly parallel across most of
   their width, so the front band sits directly over the back band's
   text far past the crossing point instead of a brief, clean X. Angle
   is doubled from before for a sharper cross with real daylight between
   the bands away from center. Rotating a full-width band tilts its ends
   up/down by roughly width * sin(angle); .ribbon's height above is sized
   for this angle so the corners don't get clipped, and it shrinks at the
   desktop breakpoint (where width grows most) to compensate. */
.ribbon__band--top {
  background: linear-gradient(135deg, var(--secondary) 0%, var(--primary) 100%);
  transform: translateY(-50%) rotate(-4deg);
  z-index: 2;
}
.ribbon__band--bottom {
  background: linear-gradient(135deg, var(--primary) 0%, var(--navy-mid) 100%);
  transform: translateY(-50%) rotate(4deg);
  z-index: 1;
}
/* Where CSS trig exists, derive the angle so the gap stops tracking width.
   The fixed-degree rules above stay as the fallback: a bare var() fallback
   would not do, since an unsupported atan2() makes the declaration invalid at
   computed-value time and resets transform to none, losing translateY too. */
@supports (transform: rotate(atan2(1px, 1px))) {
  .ribbon__band--top { transform: translateY(-50%) rotate(calc(-1 * var(--ribbon-angle))); }
  .ribbon__band--bottom { transform: translateY(-50%) rotate(var(--ribbon-angle)); }
}
.ribbon__track {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  width: max-content;
  white-space: nowrap;
  will-change: transform;
  backface-visibility: hidden;
}
/* Animation is added only once web fonts have finished loading (see
   main.js) — starting it before Montserrat swaps in would mean the
   track's width (and so the -50% loop point) changes mid-animation,
   causing a visible snap the instant the font finishes loading. Using
   translate3d (not translateX) in the keyframes forces both tracks onto
   their own GPU layer for the whole animation, which stops the other
   twitch: browsers occasionally re-rasterize a plain 2D transform on a
   rotated ancestor, producing a one-frame jump mid-scroll. */
.fonts-ready .ribbon__track--left { animation: ribbon-scroll-left 30s linear infinite; }
.fonts-ready .ribbon__track--right { animation: ribbon-scroll-right 25s linear infinite; }
.ribbon__text {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-md);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.ribbon__band--top .ribbon__text { color: var(--white); }
.ribbon__band--bottom .ribbon__text { color: var(--hero-gold); }
.ribbon__icon { width: 1.35rem; height: 1.35rem; flex-shrink: 0; }
.ribbon__band--top .ribbon__icon path { fill: url(#ribbonGoldGrad); }
.ribbon__band--bottom .ribbon__icon path { fill: url(#ribbonSilverGrad); }
@keyframes ribbon-scroll-left {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-50%, 0, 0); }
}
@keyframes ribbon-scroll-right {
  from { transform: translate3d(-50%, 0, 0); }
  to { transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .ribbon__track--left, .ribbon__track--right,
  .fonts-ready .ribbon__track--left, .fonts-ready .ribbon__track--right { animation: none; }
}

/* Three persona routes */
.routes {
  display: grid;
  gap: var(--space-5);
  margin-top: var(--space-8);
}
.routes--standalone { margin-top: 0; }
@media (min-width: 48rem) {
  .routes { grid-template-columns: repeat(2, 1fr); }
}
.route {
  padding: var(--space-6);
  background: var(--white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  transition: transform var(--duration-fast) ease, box-shadow var(--duration-fast) ease;
}
.route:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.route__title { font-family: var(--font-display); font-weight: 600; font-size: var(--text-lg); color: var(--primary); }
.route__desc { font-size: var(--text-sm); color: var(--muted); }

/* Row list — replaces card grids for services / feature lists */
.row-list { border-top: 1px solid var(--hairline); }
.row-list__item {
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--hairline);
  display: grid;
  gap: var(--space-2);
}
@media (min-width: 48rem) {
  .row-list__item { grid-template-columns: 16rem 1fr; gap: var(--space-6); }
}
.row-list__title { font-weight: 600; }
.row-list__title-wrap { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-1); }
.row-list__icon { width: 1.75rem; height: 1.75rem; border-radius: var(--radius-sm); flex-shrink: 0; }
.row-list__desc { color: var(--muted); font-size: var(--text-sm); }

.qr-card {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-5);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--white);
  box-shadow: var(--shadow-sm);
}
.qr-card img { width: 4.5rem; height: 4.5rem; flex-shrink: 0; }
.qr-card__title { font-weight: 600; }
.qr-card__desc { color: var(--muted); font-size: var(--text-sm); margin-top: var(--space-1); }

/* Badge / trust tag */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--accent);
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
}

/* Trust statement / pull quote */
.pull-statement--spaced { margin-top: var(--space-8); }
.row-list--spaced { margin-top: var(--space-6); }
.pull-statement {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 400;
  color: var(--primary);
  line-height: 1.3;
  max-width: 46rem;
}

/* Calculators */
.calculator {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  background: var(--white);
  box-shadow: var(--shadow-sm);
}
.calculator__result {
  margin-top: var(--space-6);
  padding-top: var(--space-6);
  border-top: 1px solid var(--hairline);
}
.calculator__figure {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-2xl);
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}
.calculator__meta { font-size: var(--text-xs); color: var(--muted); margin-top: var(--space-4); }

/* Guide / article prose */
.prose h2 { margin-top: var(--space-8); margin-bottom: var(--space-4); }
.prose h3 { margin-top: var(--space-6); margin-bottom: var(--space-3); color: var(--body-text); font-family: var(--font-body); }
.prose p { color: var(--body-text); margin-bottom: var(--space-4); }
.prose ul, .prose ol { margin: 0 0 var(--space-5) 0; padding-left: 1.25em; list-style: disc; }
.prose ol { list-style: decimal; }
.prose li { margin-bottom: var(--space-2); }
.prose a { color: var(--secondary); text-decoration: underline; }

.guide-hero-img { border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-sm); margin-bottom: var(--space-6); }
.guide-hero-img img { width: 100%; }

/* Guide index cards (row style, not shadow cards) */
.guide-group + .guide-group { margin-top: var(--space-8); }
.guide-group__title { font-family: var(--font-display); font-size: var(--text-xl); color: var(--primary); font-weight: 600; margin-bottom: var(--space-3); }
.guide-list__item { padding-block: var(--space-6); border-bottom: 1px solid var(--hairline); }
.guide-list__item:first-child { border-top: 1px solid var(--hairline); }
.guide-list__title { display: block; font-family: var(--font-display); font-size: var(--text-lg); color: var(--primary); font-weight: 600; }
.guide-list__desc { color: var(--muted); margin-top: var(--space-2); }

/* Map embed frame */
.map-frame { border: 1px solid var(--hairline); border-radius: var(--radius-md); overflow: hidden; }
.map-frame iframe { display: block; width: 100%; height: 22rem; border: 0; }

/* Floating action buttons */
.floating-actions {
  position: fixed;
  right: var(--space-4);
  bottom: var(--space-4);
  z-index: 50;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-3);
  max-width: calc(100vw - (2 * var(--space-4)));
}

/* "View Case Study" glowing border-trace button — CodeFronts gbb-03, pasted as
   given. Kept --beam (used by the glow gradient below) but dropped the rest
   of the bare .gbb-03 demo-page rule (100vh centering block + dark gradient
   background) since that would wrap the button in a full-viewport box; every
   button/pseudo-element rule below is untouched. */
.gbb-03 {
  --beam: oklch(0.85 0.15 142);
}
.gbb-03,
.gbb-03 *,
.gbb-03 *::before,
.gbb-03 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

@property --gbb-a3 {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

.gbb-03 .gbb-03__btn {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 16px 30px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255,255,255,.14);
  background: var(--whatsapp-green);
  font: 600 15px/1 'Segoe UI',system-ui,sans-serif;
  color: #fff;
  text-decoration: none;
  transition: border-color .3s ease;
}

.gbb-03 .gbb-03__icon { width: 18px; height: 18px; }

.gbb-03 .gbb-03__btn::before,
.gbb-03 .gbb-03__btn::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 2px;
  background: conic-gradient(from var(--gbb-a3),transparent 0 82%,color-mix(in oklab,var(--beam) 45%,transparent) 88%,var(--beam) 93%,transparent 97%);
  -webkit-mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s ease;
}

.gbb-03 .gbb-03__btn::after {
  filter: blur(8px);
  inset: -3px;
  padding: 4px;
}

.gbb-03 .gbb-03__btn:hover,
.gbb-03 .gbb-03__btn:focus-visible {
  border-color: rgba(255,255,255,.22);
}

.gbb-03 .gbb-03__btn:hover::before,
.gbb-03 .gbb-03__btn:hover::after,
.gbb-03 .gbb-03__btn:focus-visible::before,
.gbb-03 .gbb-03__btn:focus-visible::after {
  opacity: 1;
  animation: gbb03-lap 1.4s linear infinite;
}

/* Periodic glow: one full lap every 4.4s (1.4s rotation + 3s pause), toggled
   via .is-glowing from assets/js/main.js. Independent of the :hover trigger
   above — both can fire the same animation. */
.gbb-03 .gbb-03__btn.is-glowing::before,
.gbb-03 .gbb-03__btn.is-glowing::after {
  opacity: 1;
  animation: gbb03-lap 1.4s linear;
}

.gbb-03 .gbb-03__btn:focus-visible {
  outline: 2px solid var(--beam);
  outline-offset: 4px;
}

.gbb-03 .gbb-03__arrow {
  transition: translate .3s ease;
}

.gbb-03 .gbb-03__btn:hover .gbb-03__arrow {
  translate: 4px 0;
}

@keyframes gbb03-lap {
  to {
    --gbb-a3: 360deg;
  }
}

@media (prefers-reduced-motion: reduce) {
  .gbb-03 .gbb-03__btn:hover::before,
    .gbb-03 .gbb-03__btn:hover::after,
    .gbb-03 .gbb-03__btn:focus-visible::before,
    .gbb-03 .gbb-03__btn:focus-visible::after {
    animation: none;
    opacity: .6;
  }
}

/* Reusable glow-trace mechanic — same technique as .gbb-03 above, but
   self-contained (sets its own --beam, no ancestor scope class, no reset)
   so it can wrap an existing styled button, like Call us, without touching
   that button's own background/padding/font. */
.btn-glow {
  position: relative;
  isolation: isolate;
  --beam: oklch(0.8 0.15 265); /* blue tint matching --primary */
}
.btn-glow::before,
.btn-glow::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 2px;
  background: conic-gradient(from var(--gbb-a3),transparent 0 82%,color-mix(in oklab,var(--beam) 45%,transparent) 88%,var(--beam) 93%,transparent 97%);
  -webkit-mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s ease;
}
.btn-glow::after { filter: blur(8px); inset: -3px; padding: 4px; }
.btn-glow:hover::before,
.btn-glow:hover::after,
.btn-glow:focus-visible::before,
.btn-glow:focus-visible::after {
  opacity: 1;
  animation: gbb03-lap 1.4s linear infinite;
}
.btn-glow.is-glowing::before,
.btn-glow.is-glowing::after {
  opacity: 1;
  animation: gbb03-lap 1.4s linear;
}
.btn-glow:focus-visible { outline: 2px solid var(--beam); outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) {
  .btn-glow:hover::before, .btn-glow:hover::after,
  .btn-glow:focus-visible::before, .btn-glow:focus-visible::after {
    animation: none;
    opacity: .6;
  }
}

/* Products grid — icon cards */
.products-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 40rem) {
  .products-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 60rem) {
  .products-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6) var(--space-7); }
}
.product-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-5) var(--space-5);
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--duration-fast) ease, transform var(--duration-fast) ease;
}
.product-card:hover { box-shadow: var(--shadow-md); transform: translateY(-4px); }
.product-card__icon { width: 3.5rem; height: 3.5rem; margin-bottom: var(--space-1); }
.product-card__title { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--primary); white-space: nowrap; }
@media (max-width: 26.5rem) {
  .product-card { padding: var(--space-5) var(--space-3) var(--space-4); }
  .product-card__title { font-size: var(--text-sm); }
}
.product-card__desc { font-size: var(--text-sm); color: var(--muted); }
.product-card__arrow {
  position: absolute;
  top: var(--space-5);
  right: var(--space-5);
  width: 1.1rem;
  height: 1.1rem;
  overflow: hidden;
}
.product-card__arrow-glyph {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-md);
  line-height: 1;
  color: var(--muted);
  transition: transform var(--duration-fast) ease, color var(--duration-fast) ease;
}
.product-card__arrow-glyph--in { top: 100%; left: -100%; }
.product-card:hover .product-card__arrow-glyph { color: var(--secondary); transform: translate(100%, -100%); }

/* ---------- 13b. Homepage additions: marquee, testimonial, FAQ, mobile CTA bar ---------- */

/* Partner marquee — replaces static logo grid on the homepage */
.marquee-group { margin-top: var(--space-2); display: flex; flex-direction: column; gap: var(--space-4); }
.marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, black 5%, black 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, black 5%, black 95%, transparent);
}
.marquee__track {
  display: flex;
  width: max-content;
  gap: var(--space-4);
  animation: marquee-scroll 34s linear infinite;
}
.marquee--reverse .marquee__track { animation-direction: reverse; animation-duration: 40s; }
@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
.marquee__item {
  display: inline-flex;
  align-items: center;
  padding: var(--space-3) var(--space-5);
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--body-text);
  white-space: nowrap;
  box-shadow: var(--shadow-sm);
}
.marquee__item--logo {
  justify-content: center;
  height: 3rem;
  padding: 0 var(--space-7);
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
}
.marquee__item--logo img {
  max-height: 2rem;
  max-width: 8rem;
  width: auto;
  height: auto;
  object-fit: contain;
}
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .marquee { overflow-x: auto; }
}

/* Testimonial */
.testimonial {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 400;
  color: var(--primary);
  line-height: 1.3;
  max-width: 46rem;
  border-left: 3px solid var(--secondary);
  padding-left: var(--space-6);
}
.testimonial p { color: inherit; }
.testimonial cite {
  display: block;
  margin-top: var(--space-4);
  font-family: var(--font-body);
  font-style: normal;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--muted);
}
.testimonial cite em { font-weight: 400; font-style: italic; }

/* FAQ accordion */
.faq-list { border-top: 1px solid var(--hairline); }
.faq-item { border-bottom: 1px solid var(--hairline); padding-block: var(--space-5); }
.faq-item summary {
  cursor: pointer;
  font-weight: 600;
  font-size: var(--text-md);
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--muted);
  transition: transform var(--duration-fast) ease;
  flex-shrink: 0;
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item p { color: var(--muted); margin-top: var(--space-3); }

/* Guides carousel (homepage) — centre-focused, three size tiers, infinite loop.
   Sizing/opacity tiers and the 700ms ease mirror the reference carousel: the
   active card is large and fully opaque, neighbours step down in size and
   fade, so the eye lands on the middle card. */
.nwc { --nwc-gap: 8px; --nwc-active-w: 326px; --nwc-active-h: 300px; --nwc-adjacent-w: 272px; --nwc-adjacent-h: 240px; --nwc-distant-w: 202px; --nwc-distant-h: 300px; --nwc-ease: cubic-bezier(0.22, 0.61, 0.36, 1); --nwc-dur: 700ms; }
@media (min-width: 64rem) {
  .nwc { --nwc-gap: 24px; --nwc-active-w: 700px; --nwc-active-h: 450px; --nwc-adjacent-w: 202px; --nwc-adjacent-h: 402px; --nwc-distant-w: 202px; --nwc-distant-h: 354px; }
}

.nwc__head { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); margin-bottom: var(--space-7); text-align: center; }
.nwc__heading { text-wrap: balance; }
.nwc__all {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: 0.25rem;
  border-bottom: 2px solid var(--secondary);
  color: var(--secondary);
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  text-decoration: none;
  transition: color var(--duration-fast) ease, border-color var(--duration-fast) ease;
}
.nwc__all:hover { color: var(--primary); border-bottom-color: var(--primary); }
.nwc__all-arrow { position: relative; display: inline-flex; width: 1rem; height: 1rem; overflow: hidden; }
.nwc__all-arrow svg { position: absolute; inset: 0; width: 100%; height: 100%; transition: transform 300ms ease; }
.nwc__all-arrow-in { transform: translateX(-100%); }
.nwc__all:hover .nwc__all-arrow-out { transform: translateX(100%); }
.nwc__all:hover .nwc__all-arrow-in { transform: translateX(0); }

.nwc__region { display: flex; flex-direction: column; align-items: center; gap: var(--space-6); outline: none; }
.nwc__window { position: relative; width: 100%; max-width: 900px; margin-inline: auto; overflow: hidden; }
@media (min-width: 64rem) { .nwc__window { max-width: 1630px; } }

.nwc__track {
  display: flex;
  align-items: center;
  gap: var(--nwc-gap);
  height: var(--nwc-active-h);
  touch-action: pan-y;
  will-change: transform;
  transition: transform var(--nwc-dur) var(--nwc-ease);
}
.nwc--no-anim .nwc__track { transition: none; }

.nwc__cell {
  flex: 0 0 auto;
  align-self: center;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Pre-JS default: behaves as a plain row of adjacent-sized cards. */
  width: var(--nwc-adjacent-w);
  height: var(--nwc-adjacent-h);
  transition: width var(--nwc-dur) var(--nwc-ease), height var(--nwc-dur) var(--nwc-ease), opacity var(--nwc-dur) var(--nwc-ease);
}
.nwc__cell[data-variant="active"]   { width: var(--nwc-active-w);   height: var(--nwc-active-h);   opacity: 1; }
.nwc__cell[data-variant="adjacent"] { width: var(--nwc-adjacent-w); height: var(--nwc-adjacent-h); opacity: 0.775; }
.nwc__cell[data-variant="distant"]  { width: var(--nwc-distant-w);  height: var(--nwc-distant-h);  opacity: 0.475; }
.nwc__cell[data-variant="far"]      { width: var(--nwc-distant-w);  height: var(--nwc-distant-h);  opacity: 0.35; }

.nwc__card {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 12px;
  background: var(--primary);
  box-shadow: var(--shadow-sm);
}
@media (min-width: 64rem) { .nwc__card { border-radius: 16px; } }
.nwc__media { position: absolute; inset: 0; }
.nwc__media img { width: 100%; height: 100%; object-fit: cover; }
.nwc__scrim { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.92) 100%); }
@media (min-width: 64rem) { .nwc__scrim { background: linear-gradient(180deg, rgba(0,0,0,0) 50.2%, rgba(0,0,0,0.92) 100%); } }

.nwc__body {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  height: 100%;
  padding: var(--space-4);
  color: var(--white);
  text-decoration: none;
  transition: padding var(--nwc-dur) var(--nwc-ease);
}
@media (min-width: 64rem) { .nwc__cell[data-variant="active"] .nwc__body { padding: var(--space-6); } }

/* The meta row belongs to the active card only, and fades in after the
   size transition has mostly settled — matching the reference's staged reveal. */
.nwc__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  font-size: var(--text-xs);
  line-height: 1;
  opacity: 0;
  transition: opacity 260ms ease 0ms;
}
.nwc__cell[data-variant="active"] .nwc__meta { opacity: 1; transition-delay: 420ms; }
@media (min-width: 64rem) { .nwc__meta { font-size: var(--text-sm); } }
.nwc__cat { padding: 0.35em 0.75em; border-radius: var(--radius-pill); background: rgba(255,255,255,0.18); font-weight: 600; }
.nwc__time { color: rgba(255,255,255,0.8); }

.nwc__title {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.25;
  color: var(--white);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: var(--text-base);
  transition: font-size var(--nwc-dur) var(--nwc-ease);
}
.nwc__cell[data-variant="adjacent"] .nwc__title { font-size: var(--text-md); }
.nwc__cell[data-variant="active"] .nwc__title { font-size: var(--text-lg); }
@media (min-width: 64rem) {
  .nwc__cell[data-variant="active"] .nwc__title { font-size: 28px; -webkit-line-clamp: 2; }
}

.nwc__controls { display: flex; align-items: center; justify-content: center; gap: var(--space-6); }
.nwc__nav {
  width: 2.75rem; height: 2.75rem;
  display: flex; align-items: center; justify-content: center;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--primary);
  cursor: pointer;
  transition: background-color var(--duration-fast) ease, color var(--duration-fast) ease;
}
.nwc__nav:hover { background: var(--primary); color: var(--white); }
.nwc__nav svg { width: 1.15rem; height: 1.15rem; }
.nwc__dots { display: flex; align-items: center; gap: var(--space-4); }
.nwc__dot {
  width: 0.625rem; height: 0.625rem;
  padding: 0;
  border: 1px solid var(--primary);
  border-radius: var(--radius-pill);
  background: transparent;
  cursor: pointer;
  transition: background-color 300ms ease;
}
.nwc__dot[aria-current="true"] { background: var(--primary); }

@media (prefers-reduced-motion: reduce) {
  .nwc__track, .nwc__cell, .nwc__body, .nwc__title, .nwc__meta { transition: none; }
}

/* Google reviews — a fanned deck of review cards with the front card upright
   and the rest rotated behind it. Renders from the JSON block in index.html;
   with no reviews it falls back to an invite state rather than showing an
   empty shell, so the section is honest before any reviews exist. */
.gr__head { text-align: center; max-width: 40rem; margin-inline: auto; }
.gr__head .eyebrow { justify-content: center; }
.gr__sub { color: var(--muted); margin-top: var(--space-3); }
.gr__head .btn { margin-top: var(--space-5); }

.gr__empty {
  margin-top: var(--space-7);
  padding: var(--space-7) var(--space-6);
  border: 1px dashed var(--hairline);
  border-radius: var(--radius-md);
  background: var(--white);
  text-align: center;
}
.gr__empty-mark { display: flex; justify-content: center; margin-bottom: var(--space-4); }
.gr__empty-mark svg { width: 2.5rem; height: 2.5rem; }
.gr__empty p { color: var(--muted); max-width: 30rem; margin-inline: auto; }

/* Deck: cards share one grid cell so they stack; the front one is upright and
   each card behind is rotated and pushed back a little. */
.gr__deck {
  position: relative;
  display: grid;
  max-width: 34rem;
  margin: var(--space-7) auto 0;
  perspective: 1200px;
}
.gr__card {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-7) var(--space-6);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--white);
  box-shadow: var(--shadow-md);
  text-align: center;
  transform-origin: 50% 100%;
  transition: transform var(--duration-entrance) var(--ease-entrance),
              opacity var(--duration-entrance) var(--ease-entrance);
}
/* Depth is driven by --i (0 = front), set on each card by the script. */
.gr__card {
  transform: translateX(calc(var(--i) * 2.5%)) rotate(calc(var(--i) * 3deg)) scale(calc(1 - var(--i) * 0.04));
  z-index: calc(10 - var(--i));
  opacity: 1;
}
.gr__card[data-hidden="true"] { opacity: 0; pointer-events: none; }
.gr__card[aria-hidden="true"] { pointer-events: none; }

.gr__stars { display: flex; gap: 0.25rem; }
.gr__stars svg { width: 1.25rem; height: 1.25rem; fill: var(--hero-gold); }
.gr__quote { color: var(--body-text); font-size: var(--text-md); line-height: 1.6; }
/* Stretched link: covers the whole card so the card itself is clickable,
   without nesting the Read more control inside an anchor. */
.gr__card-link { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.gr__card-link:focus-visible { outline: 2px solid var(--secondary); outline-offset: 3px; }
.gr__card:hover { box-shadow: var(--shadow-lg); }

.gr__more {
  /* Above the stretched link, so expanding the text still beats navigating. */
  position: relative;
  z-index: 2;
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  color: var(--secondary);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
}
.gr__person { display: flex; flex-direction: column; align-items: center; gap: var(--space-3); }
.gr__avatar-wrap { position: relative; }
.gr__avatar {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: var(--radius-pill);
  object-fit: cover;
  background: var(--accent);
}
.gr__initials {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--primary);
}
.gr__badge {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 1.5rem;
  height: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--white);
  box-shadow: var(--shadow-sm);
}
.gr__badge svg { width: 0.875rem; height: 0.875rem; }
.gr__author { font-family: var(--font-display); font-weight: 700; color: var(--primary); }
.gr__date { display: block; font-size: var(--text-sm); color: var(--muted); margin-top: 0.125rem; }

.gr__controls { display: flex; align-items: center; justify-content: center; gap: var(--space-6); margin-top: var(--space-6); }
.gr__nav {
  width: 2.75rem;
  height: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--primary);
  cursor: pointer;
  transition: background-color var(--duration-fast) ease, color var(--duration-fast) ease;
}
.gr__nav:hover { background: var(--primary); color: var(--white); }
.gr__nav svg { width: 1.15rem; height: 1.15rem; }
.gr__dots { display: flex; align-items: center; gap: var(--space-4); }
.gr__dot {
  width: 0.625rem;
  height: 0.625rem;
  padding: 0;
  border: 1px solid var(--primary);
  border-radius: var(--radius-pill);
  background: transparent;
  cursor: pointer;
  transition: background-color 300ms ease;
}
.gr__dot[aria-current="true"] { background: var(--primary); }

.gr__summary { display: flex; flex-direction: column; align-items: center; gap: var(--space-3); margin-top: var(--space-6); }
.gr__faces { display: flex; }
.gr__faces img, .gr__faces span {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-pill);
  border: 2px solid var(--white);
  object-fit: cover;
  background: var(--accent);
}
.gr__faces > * + * { margin-left: -0.6rem; }
/* Smaller than the card avatar, so two initials still clear the circle that
   overlaps them when a reviewer has no photo. */
.gr__faces .gr__initials { font-size: var(--text-sm); }
.gr__summary-text { font-size: var(--text-sm); color: var(--muted); }
.gr__summary-text strong { color: var(--body-text); }

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

/* ---------- 13. Scroll reveal ---------- */
.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--duration-entrance) var(--ease-entrance),
              transform var(--duration-entrance) var(--ease-entrance);
}
.reveal.is-visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}
