/* ============================================================
   Xaver Brand System: design tokens + base styles
   Reference var(--xv-*) in components; never hardcode hex.
   Source of truth: XAVER 2026 Design System (Claude Design),
   mirrored locally at .claude/skills/xaver-design
   ============================================================ */

@import url("https://fonts.googleapis.com/css2?family=Funnel+Display:wght@300..800&family=Figtree:ital,wght@0,300..900;1,300..900&display=swap");

:root {
  /* Brand colors */
  --xv-navy:      #091435;
  --xv-charcoal:  #323132;
  --xv-blue:      #8EB8DF;
  --xv-orange:    #F09124;
  --xv-pink:      #F087B2;

  /* Neutral surfaces */
  --xv-paper:     #FFFFFF;
  --xv-mist:      #EDF1F7;

  /* Semantic aliases */
  --xv-bg:        var(--xv-navy);
  --xv-bg-light:  var(--xv-paper);
  --xv-text:      var(--xv-charcoal);
  --xv-text-soft: #5A5358;
  --xv-on-navy:   #FFFFFF;
  --xv-link:      var(--xv-navy);
  --xv-cta:       var(--xv-orange);

  /* Legacy aliases (templates still reference these) */
  --xv-cream:     var(--xv-paper);
  --xv-cream-2:   var(--xv-mist);
  --xv-sky:       var(--xv-blue);
  --xv-navy-deep: #060D24;
  --xv-navy-soft: #0E1C4A;
  --xv-orange-soft: var(--xv-mist);
  --xv-sky-soft:    #EDF4FB;
  --fg-1: var(--xv-charcoal);
  --fg-2: var(--xv-text-soft);
  --fg-3: #8A8490;

  /* Hairlines */
  --xv-line:      rgba(50, 49, 50, .14);
  --xv-line-navy: rgba(255, 255, 255, .16);

  /* Typography */
  --font-display: "Funnel Display", system-ui, sans-serif;
  --font-body:    "Figtree", system-ui, sans-serif;
  --font-mono:    ui-monospace, "JetBrains Mono", "SF Mono", Menlo, monospace;

  /* Radii */
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 24px;

  /* Shadows */
  --shadow-1: 0 1px 2px rgba(9,20,53,.06), 0 2px 8px rgba(9,20,53,.06);
  --shadow-2: 0 6px 18px -8px rgba(9,20,53,.28);
  --shadow-3: 0 18px 40px -20px rgba(9,20,53,.45);

  /* Motion */
  --ease-standard: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 140ms;
  --dur-2: 220ms;
  --dur-slow: 420ms;
}


/* -------- Typography -------- */

.xv-display {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(56px, 9vw, 116px);
  line-height: .95;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.xv-display-2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(40px, 5vw, 72px);
  line-height: 1.02;
  letter-spacing: -0.02em;
}

.xv-h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(34px, 4.6vw, 58px);
  line-height: 1.02;
  letter-spacing: -0.02em;
}

.xv-h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(28px, 3.4vw, 40px);
  line-height: 1.02;
  letter-spacing: -0.02em;
}

.xv-h3 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.18;
  letter-spacing: -0.02em;
}

.xv-eyebrow {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--xv-text-soft);
  display: flex;
  align-items: center;
  gap: 10px;
}

.xv-eyebrow::before {
  content: "";
  width: 26px;
  height: 2px;
  background: currentColor;
  display: inline-block;
}

.xv-eyebrow .dot {
  display: none;
}

.xv-lede {
  font-family: var(--font-body);
  font-weight: 330;
  font-size: clamp(17px, 1.5vw, 20px);
  line-height: 1.6;
}

.xv-body {
  font-family: var(--font-body);
  font-weight: 330;
  font-size: 16px;
  line-height: 1.6;
}

.xv-stat-number {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 40px;
  letter-spacing: -0.02em;
}

.xv-mono {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
}


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

.xv-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 22px;
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  border: none;
  text-decoration: none;
  transition: background var(--dur-2) var(--ease-standard),
              box-shadow var(--dur-2) var(--ease-standard);
}

.xv-btn--primary {
  background: var(--xv-orange);
  color: #fff;
}
.xv-btn--primary:hover {
  background: #d97f12;
}

.xv-btn--navy {
  background: var(--xv-navy);
  color: #fff;
}
.xv-btn--navy:hover {
  background: #060d24;
}

.xv-btn--ghost {
  background: transparent;
  color: #fff;
  border: 1px solid var(--xv-line-navy);
}
.xv-btn--ghost:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.4);
}

.xv-btn--ghost-light {
  background: transparent;
  color: var(--xv-navy);
  border: 1px solid var(--xv-line);
}
.xv-btn--ghost-light:hover {
  background: var(--xv-mist);
}


/* -------- Cards -------- */

.xv-card {
  background: var(--xv-paper);
  border: 1px solid var(--xv-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  transition: box-shadow var(--dur-2) var(--ease-standard);
}
.xv-card:hover {
  box-shadow: var(--shadow-2);
}

.xv-card--navy {
  background: var(--xv-navy);
  border-color: var(--xv-line-navy);
  color: #fff;
}
.xv-card--navy .xv-body {
  color: rgba(255, 255, 255, 0.72);
}
.xv-card--navy .xv-mono {
  color: rgba(255, 255, 255, 0.5);
}


/* -------- Sections -------- */

.xv-section--navy {
  background: var(--xv-navy);
  color: #fff;
}

.xv-section--cream {
  background: var(--xv-paper);
  color: var(--xv-charcoal);
}

/* -------- Container -------- */

.xv-container {
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: 1.5rem; /* px-6 */
}
@media (min-width: 768px) {
  .xv-container {
    padding-inline: 4rem; /* md:px-16 */
  }
}

/* -------- Hero padding (homepage + services index) -------- */

.xv-hero {
  padding-block: clamp(96px, 10vw, 128px);
}

/* -------- Card keyboard affordance -------- */

.xv-card:focus-within {
  box-shadow: var(--shadow-2);
}


/* -------- Service card CTA link -------- */

.xv-card-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--xv-orange);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  border-bottom: 1.5px solid currentColor;
  padding-bottom: 1px;
  text-decoration: none;
  white-space: nowrap;
}
.xv-card-cta:hover {
  color: #d97f12;
}


/* -------- Nav -------- */

.xv-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(9, 20, 53, 0.92);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--xv-line-navy);
  color: #fff;
}
.xv-nav a {
  color: rgba(255, 255, 255, 0.7);
  border-bottom: none;
  text-decoration: none;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  transition: color var(--dur-2) var(--ease-standard);
}
.xv-nav a:hover {
  color: #fff;
}
.xv-nav button {
  color: rgba(255, 255, 255, 0.7);
  font-family: var(--font-body);
}
.xv-nav button:hover {
  color: #fff;
}
.xv-nav .nav-logo {
  height: 30px;
  width: auto;
  display: block;
}
.xv-nav-trigger {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 14px;
  font-weight: 500;
}
.xv-nav .xv-nav-cta {
  padding: 9px 18px;
  font-size: 14px;
  color: #fff;
}
.xv-nav .xv-nav-cta:hover {
  color: #fff;
}


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

.xv-footer {
  background: var(--xv-navy);
  color: #fff;
  font-family: var(--font-body);
}
.xv-footer a {
  color: rgba(255, 255, 255, 0.6);
  border-bottom: none;
  text-decoration: none;
  transition: color var(--dur-2) var(--ease-standard);
}
.xv-footer a:hover {
  color: #fff;
}
.xv-footer h3 {
  color: #fff;
}


/* -------- Recolorable organic shape -------- */

.xv-shape {
  display: inline-block;
  -webkit-mask: var(--shape) no-repeat center / contain;
          mask: var(--shape) no-repeat center / contain;
  background: var(--shape-color, var(--xv-orange));
}

/* Decorative hero shapes are flourish only (aria-hidden). On small screens they
   sit behind hero copy and cut through the text, so hide them for legibility. */
@media (max-width: 767px) {
  .xv-shape {
    display: none;
  }
}


/* -------- Pixel-grid texture -------- */

.xv-pixel-grid {
  background-image:
    linear-gradient(var(--xv-line-navy) 1px, transparent 1px),
    linear-gradient(90deg, var(--xv-line-navy) 1px, transparent 1px);
  background-size: 34px 34px;
}


/* -------- Focus (accessible) -------- */

:focus-visible {
  outline: 3px solid rgba(142, 184, 223, .4);
  outline-offset: 2px;
}


/* -------- Portfolio filter tabs -------- */

.xv-filter-tab {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  padding: 6px 16px;
  border-radius: 999px;
  border: 1px solid var(--xv-line);
  background: transparent;
  color: var(--xv-text-soft);
  cursor: pointer;
  transition: all var(--dur-2) var(--ease-standard);
}
.xv-filter-tab:hover { border-color: var(--xv-orange); color: var(--xv-charcoal); }
.xv-filter-tab.is-active { background: var(--xv-navy); color: #fff; border-color: var(--xv-navy); }


/* -------- Selected work (homepage editorial cards) -------- */

.xv-work-card {
  display: flex;
  flex-direction: column;
  background: var(--xv-navy);
  border-radius: var(--radius-xl);
  overflow: hidden;
  box-shadow: var(--shadow-2);
  color: #fff;
  text-decoration: none;
  transition: box-shadow var(--dur-2) var(--ease-standard),
              transform var(--dur-2) var(--ease-standard);
}
a.xv-work-card:hover {
  box-shadow: var(--shadow-3);
  transform: translateY(-2px);
}

.xv-work-media {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(240px, 34vw, 320px);
}
.xv-work-card--hero .xv-work-media {
  min-height: clamp(320px, 42vw, 460px);
}
.xv-work-media--flat {
  background-color: var(--xv-navy);
}

.xv-work-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  /* The signature moment: hovering slowly scrolls the shipped site inside the frame. */
  transition: object-position 5s var(--ease-standard);
}
a.xv-work-card:hover .xv-work-img {
  object-position: center bottom;
}
@media (prefers-reduced-motion: reduce) {
  .xv-work-img {
    transition: none;
  }
  a.xv-work-card:hover .xv-work-img {
    object-position: center top;
  }
}

.xv-work-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(6, 13, 36, .96), rgba(6, 13, 36, .58) 38%, rgba(6, 13, 36, 0) 62%);
}

.xv-work-kicker {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 26px 14px;
}
.xv-work-kicker .xv-work-badge {
  margin-left: auto;
}
.xv-work-card .xv-eyebrow {
  color: var(--xv-blue);
}

.xv-work-badge {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  padding: 4px 12px;
  border-radius: 999px;
  background: rgba(9, 20, 53, 0.55);
  border: 1px solid var(--xv-line-navy);
  color: #fff;
  white-space: nowrap;
}
.xv-work-badge--wip {
  color: rgba(255, 255, 255, 0.65);
}

.xv-work-headline {
  position: relative;
  padding: 24px 26px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(22px, 2.2vw, 27px);
  line-height: 1.12;
  letter-spacing: -0.02em;
  max-width: 30ch;
  text-wrap: balance;
}
.xv-work-card--hero .xv-work-headline {
  font-size: clamp(26px, 3.4vw, 44px);
  line-height: 1.05;
}

.xv-work-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 24px;
  padding: 18px 26px;
  border-top: 1px solid var(--xv-line-navy);
  background: var(--xv-navy-deep);
}
.xv-work-foot-id {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 16px;
}
.xv-work-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
}

.xv-work-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
}
.xv-work-metric {
  display: flex;
  flex-direction: column;
}
.xv-work-metric-value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 26px;
  letter-spacing: -0.02em;
  color: var(--xv-orange);
}
.xv-work-metric-label {
  font-family: var(--font-body);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.62);
}


/* -------- Brand marquee ticker -------- */

.xv-ticker {
  overflow: hidden;
  background: var(--xv-paper);
  border-bottom: 1px solid var(--xv-line);
  padding-block: 16px;
}

.xv-ticker-track {
  display: flex;
  width: max-content;
  animation: xv-ticker-scroll 70s linear infinite;
}
/* No-JS fallback; with JS the marquee controller eases and scrubs. */
.xv-ticker:not(.xv-marquee-managed):hover .xv-ticker-track {
  animation-play-state: paused;
}

.xv-ticker-item {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.01em;
  color: var(--xv-navy);
}
.xv-ticker-item::after {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--xv-orange);
  margin-inline: 26px;
}

/* Track holds the phrase list twice, so -50% lands exactly on the seam. */
@keyframes xv-ticker-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .xv-ticker-track {
    animation: none;
  }
}


/* -------- Founder card (hero) -------- */

.xv-founder-card {
  display: block;
  width: 240px;
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--xv-navy-soft);
  border: 1px solid var(--xv-line-navy);
  box-shadow: var(--shadow-3);
  text-decoration: none;
  color: #fff;
  transition: transform var(--dur-2) var(--ease-standard),
              box-shadow var(--dur-2) var(--ease-standard);
}
.xv-founder-card:hover {
  transform: translateY(-3px);
}
@media (min-width: 1024px) {
  .xv-founder-card {
    width: 264px;
  }
}

.xv-founder-card-photo {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  /* The portrait source is 2:3; anchor the square crop to the face. */
  object-position: top;
  display: block;
}

.xv-founder-card-caption {
  display: block;
  padding: 14px 18px 16px;
}

.xv-founder-card-name {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
}

.xv-founder-card-role {
  display: block;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--xv-blue);
}

.xv-founder-card-cta {
  display: inline-block;
  margin-top: 8px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--xv-orange);
}
.xv-founder-card:hover .xv-founder-card-cta {
  color: #d97f12;
}

/* -------- Lead form band -------- */

.xv-lead-card:hover {
  box-shadow: var(--shadow-1); /* form card: suppress xv-card hover lift */
}

.xv-label {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 14px;
}

.xv-input {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--xv-text);
  background: var(--xv-paper);
  border: 1px solid var(--xv-line);
  border-radius: var(--radius-md);
  padding: 11px 14px;
  width: 100%;
}
.xv-input:focus {
  outline: none;
  border-color: var(--xv-navy);
  box-shadow: 0 0 0 3px var(--xv-sky-soft);
}

.xv-lead-doors {
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--xv-text-soft);
}
.xv-lead-doors a {
  color: var(--xv-link);
  font-weight: 600;
  text-decoration: none;
}
.xv-lead-doors a:hover {
  text-decoration: underline;
}
/* -------- Process timeline -------- */

.xv-process-grid {
  list-style: none;
  padding: 0;
  margin: 0;
}

.xv-process-step {
  position: relative;
  background: var(--xv-navy-soft);
  border: 1px solid var(--xv-line-navy);
  border-radius: var(--radius-lg);
  padding: 24px 22px;
}

.xv-process-week {
  color: var(--xv-orange);
  text-transform: uppercase;
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.xv-process-week::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--xv-orange);
  flex-shrink: 0;
}

/* Rail connecting the steps across the grid gaps on wide screens */
@media (min-width: 1024px) {
  .xv-process-step:not(:last-child)::before {
    content: "";
    position: absolute;
    top: 36px;
    left: 100%;
    width: 24px;
    height: 1px;
    background: var(--xv-line-navy);
  }
}

.xv-process-deliverables {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.xv-process-deliverables li {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid var(--xv-line-navy);
  color: rgba(255, 255, 255, 0.78);
}


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

.xv-faq-item {
  border-bottom: 1px solid var(--xv-line);
}
.xv-faq-q {
  cursor: pointer;
  list-style: none;
  padding: 20px 4px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  color: var(--xv-charcoal);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}
.xv-faq-q::-webkit-details-marker { display: none; }
.xv-faq-q::after {
  content: "+";
  font-size: 26px;
  line-height: 1;
  color: var(--xv-orange);
  flex-shrink: 0;
}
details[open] > .xv-faq-q::after { content: "\2013"; }
.xv-faq-a {
  padding: 0 4px 22px;
  color: var(--fg-2);
}


/* Find-your-fit quiz (audit round 3) */
.xv-quiz-card { background: var(--xv-navy); border-radius: var(--radius-lg); }
.xv-quiz-chip {
  border: 1px solid rgba(255, 255, 255, 0.35); border-radius: 999px;
  color: #fff; padding: 10px 18px; cursor: pointer;
  transition: background var(--dur-2) var(--ease-standard), border-color var(--dur-2) var(--ease-standard);
}
.xv-quiz-chip:hover { border-color: var(--xv-orange); }
.xv-quiz-chip[aria-pressed="true"] { background: var(--xv-orange); border-color: var(--xv-orange); color: var(--xv-navy); font-weight: 600; }
.xv-quiz-dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 255, 255, 0.25); }
.xv-quiz-dot--done { background: var(--xv-orange); }
.xv-quiz-dim { opacity: 0.35; transition: opacity var(--dur-2) var(--ease-standard); }
.xv-quiz-winner { outline: 2px solid var(--xv-orange); outline-offset: 2px; border-radius: var(--radius-lg); }

/* Scroll reveal (audit round 3): armed only when JS + motion allowed */
.xv-reveal--armed { opacity: 0; transform: translateY(14px); transition: opacity var(--dur-2) var(--ease-standard), transform var(--dur-2) var(--ease-standard); }
.xv-reveal--armed.xv-reveal--in { opacity: 1; transform: none; }

/* Service hero scene */
.xv-service-hero { display: block; }
.xv-service-hero-img { border-radius: var(--radius-lg); width: 100%; height: auto; }
.xv-service-hero--banner .xv-service-hero-img { max-height: 320px; object-fit: cover; }

/* Click-to-play player: the vertical cut stands upright instead of cropping to 16:9. */
.xv-video--vertical {
  aspect-ratio: 9 / 16;
  max-width: 420px;
  margin-inline: auto;
}


/* -------- Hero lockup (homepage) --------
   The primary lockup assembles on first visit per session: strokes draft the
   mark, the fill inks it, the icon settles from hero scale into true lockup
   proportion (icon = 52.32% of wordmark width, gap 16.68%, both measured from
   the primary asset), the wordmark rises, and a light pass crosses the mark.
   The hero-lockup Stimulus controller adds .xv-lockup--settled after the intro
   (or immediately on repeat visits) so effects below compose against static
   end states, never against animation fill. */

.xv-lockup { perspective: 1200px; }

.xv-lockup-tilt {
  transform: rotateX(calc(var(--ry, 0) * 1deg)) rotateY(calc(var(--rx, 0) * 1deg));
  will-change: transform;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.xv-lockup-icon {
  position: relative;
  width: 52.32%;
  animation: xv-lockup-settle .8s var(--ease-out) 2.7s both;
}
.xv-lockup-icon svg { display: block; width: 100%; height: auto; }

.xv-lockup-wordmark {
  display: block;
  width: 100%;
  height: auto;
  margin-top: 16.68%;
  fill: #fff;
  opacity: 0;
  /* viewBox hugs the letters; without this the wave effect clips their tops */
  overflow: visible;
  animation: xv-lockup-rise .7s var(--ease-out) 3.05s forwards;
}

.xv-lockup-piece {
  fill: none;
  stroke: var(--xv-blue);
  stroke-width: 1.4;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation:
    xv-lockup-draw 1s var(--ease-standard) calc(.2s + var(--i) * 90ms) forwards,
    xv-lockup-fadeout .9s var(--ease-standard) 2.4s forwards;
}

.xv-lockup-whole {
  fill: var(--xv-blue);
  opacity: 0;
  animation: xv-lockup-fadein .9s var(--ease-standard) 1.9s forwards;
}

.xv-lockup-sweep {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  -webkit-mask-image: var(--xv-lockup-mask);
  -webkit-mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-image: var(--xv-lockup-mask);
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  overflow: clip;
  animation: xv-lockup-sweepvis 1.2s var(--ease-standard) 3.7s both;
}
.xv-lockup-sweep::before {
  content: "";
  position: absolute;
  inset: -40%;
  background: linear-gradient(135deg, transparent 42%, rgba(255, 255, 255, .9) 50%, transparent 58%);
  transform: translate3d(-32%, -32%, 0);
  animation: xv-lockup-sweepmove 1.2s var(--ease-standard) 3.7s both;
}

.xv-lockup-corner {
  fill-opacity: 0;
  cursor: pointer;
  pointer-events: none;
  transition: fill-opacity var(--dur-2) var(--ease-standard), opacity var(--dur-fast) var(--ease-standard);
}
.xv-lockup-corner:hover { fill-opacity: .95; }
.xv-lockup-corner--tl { fill: var(--xv-blue); }
.xv-lockup-corner--tr { fill: #fff; }
.xv-lockup-corner--bl { fill: var(--xv-pink); }
.xv-lockup-corner--br { fill: var(--xv-orange); }

/* Orange wash for the flood effect; the circle is anchored on the bottom-right
   corner square so the colour visibly pours out of the square that was clicked. */
.xv-lockup-flood { position: absolute; inset: 0; opacity: 0; pointer-events: none; }
.xv-lockup-flood svg { display: block; width: 100%; height: 100%; fill: var(--xv-orange); }

/* Settled: static end states, added by the controller (repeat visits get it
   immediately). Kept in sync with the reduced-motion block below. */
.xv-lockup--settled .xv-lockup-piece { animation: none; opacity: 0; }
.xv-lockup--settled .xv-lockup-whole { animation: none; opacity: 1; }
.xv-lockup--settled .xv-lockup-icon { animation: none; transform: none; }
.xv-lockup--settled .xv-lockup-wordmark { animation: none; opacity: 1; }
.xv-lockup--settled .xv-lockup-sweep { animation: none; }
.xv-lockup--settled .xv-lockup-sweep::before { animation: none; }
.xv-lockup--settled .xv-lockup-corner { pointer-events: all; }

/* Corner click effects. These rules sit after the settled block on purpose:
   equal specificity, so source order lets an effect override the static state
   while it runs. */
.xv-fx-redraw .xv-lockup-piece {
  opacity: 1;
  animation:
    xv-lockup-draw .8s var(--ease-standard) calc(var(--i) * 50ms) forwards,
    xv-lockup-fadeout .7s var(--ease-standard) 1.5s forwards;
}
.xv-fx-redraw .xv-lockup-whole {
  opacity: 0;
  animation: xv-lockup-fadein .8s var(--ease-standard) 1.3s forwards;
}

.xv-fx-shine .xv-lockup-sweep { animation: xv-lockup-sweepvis 1.1s var(--ease-standard) both; }
.xv-fx-shine .xv-lockup-sweep::before { animation: xv-lockup-sweepmove 1.1s var(--ease-standard) both; }

.xv-fx-flood .xv-lockup-flood {
  opacity: 1;
  animation: xv-lockup-flood 1.4s var(--ease-standard) both;
}

.xv-fx-wave .xv-lockup-wordmark > * {
  transform-box: fill-box;
  animation: xv-lockup-lift .55s var(--ease-out) calc(var(--l) * 70ms) both;
}

@keyframes xv-lockup-draw { to { stroke-dashoffset: 0; } }
@keyframes xv-lockup-fadein { to { opacity: 1; } }
@keyframes xv-lockup-fadeout { to { opacity: 0; } }
@keyframes xv-lockup-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes xv-lockup-settle { from { transform: scale(1.911); } to { transform: none; } }
@keyframes xv-lockup-sweepvis { 0% { opacity: 0; } 20% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; } }
@keyframes xv-lockup-sweepmove { to { transform: translate3d(32%, 32%, 0); } }
@keyframes xv-lockup-flood {
  0%, 100% { clip-path: circle(0% at 87.3% 87.3%); }
  45%, 60% { clip-path: circle(135% at 87.3% 87.3%); }
}
@keyframes xv-lockup-lift { 0%, 100% { transform: none; } 40% { transform: translateY(-8%); } }

@media (prefers-reduced-motion: reduce) {
  .xv-lockup-piece { animation: none; opacity: 0; }
  .xv-lockup-whole { animation: none; opacity: 1; }
  .xv-lockup-icon { animation: none; transform: none; }
  .xv-lockup-wordmark { animation: none; opacity: 1; }
  .xv-lockup-sweep { display: none; }
  .xv-lockup-corner { transition: none; pointer-events: all; }
  .xv-lockup-flood { display: none; }
  .xv-fx-redraw .xv-lockup-piece { animation: none; }
  .xv-fx-redraw .xv-lockup-whole { animation: none; opacity: 1; }
  .xv-fx-wave .xv-lockup-wordmark > * { animation: none; }
}


/* -------- Featured clients marquee --------
   Runs opposite the phrase ticker: logos drift right in one continuous line.
   Same seam trick as the ticker (two copies, half-track travel), just from
   -50% back to 0. Spacing lives on the items, not a container gap, so the
   seam between copies is invisible. */

.xv-clients {
  overflow: hidden;
}

.xv-clients-track {
  display: flex;
  width: max-content;
  animation: xv-clients-scroll 45s linear infinite;
}
/* No-JS fallback; with JS the marquee controller eases and scrubs. */
.xv-clients:not(.xv-marquee-managed):hover .xv-clients-track {
  animation-play-state: paused;
}

/* Two copies only tile seamlessly while a single copy covers the band. A
   handful of logos falls short of a wide screen, so the loop ran out
   mid-cycle: empty space on the right, then a snap back to the left at the
   seam. Floor a copy at the viewport and share the slack out with
   space-around, whose half-size end gaps meet at the seam to make one full
   gap, so the rhythm holds across the join. Narrow screens are already
   wider than the viewport and keep the spacing they had. */
.xv-clients-set {
  display: flex;
  align-items: center;
  min-width: 100vw;
  justify-content: space-around;
}
.xv-clients-set img {
  margin-inline: clamp(24px, 3.5vw, 44px);
}

@keyframes xv-clients-scroll {
  from { transform: translateX(-50%); }
  to   { transform: translateX(0); }
}

@media (prefers-reduced-motion: reduce) {
  .xv-clients-track {
    animation: none;
    width: auto;
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 40px;
  }
  .xv-clients-set[aria-hidden="true"] {
    display: none;
  }
  .xv-clients-set {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 40px;
    min-width: auto;
  }
}

/* -------- Homepage process strip -------- */

.xv-process-strip {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 24px;
}

@media (min-width: 640px) {
  .xv-process-strip {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .xv-process-strip {
    grid-template-columns: repeat(4, 1fr);
  }
  /* Rail running from each week label to the next week's dot. The week
     row is a flex line, so the pseudo-element fills the leftover column
     width; the negative margin carries it across the grid gap. */
  .xv-process-strip li:not(:last-child) .xv-process-week::after {
    content: "";
    flex: 1;
    height: 1px;
    margin-right: -24px;
    background: var(--xv-line-navy);
  }
}

/* -------- Scroll-driven reveals -------- */
/* Section headings rise in as they enter the viewport. Gated so that
   browsers without scroll-driven timelines, and reduced-motion readers,
   get the static heading. */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .xv-reveal {
      animation: xv-reveal-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 35%;
    }
  }
}

@keyframes xv-reveal-rise {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* -------- FAQ auto-answer word cascade -------- */
/* faq_autoplay wraps the first answer's words in these spans; while
   --speaking they hold hidden, then cascade in via per-word inline
   delays, always well ahead of reading speed. */

.xv-faq-word {
  display: inline-block;
  transition: opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out);
}

.xv-faq-a--speaking .xv-faq-word {
  opacity: 0;
  transform: translateY(4px);
  transition: none;
}

/* -------- FAQ keyword emphasis -------- */
/* *marked* words in FAQ answers. Statically bold with a soft orange
   underline; after the auto-typed answer finishes, faq_autoplay drops
   the --settling class and they sweep in one by one. */

/* Weight stays constant so emphasising never re-wraps the line; the
   sweep animates colour and the underline instead. */
.xv-faq-key {
  font-weight: 600;
  color: var(--xv-charcoal);
  background-image: linear-gradient(transparent 68%, rgba(240, 145, 36, 0.32) 68%);
  background-repeat: no-repeat;
  background-size: 100% 100%;
  transition: color 0.45s var(--ease-standard),
              background-size 0.45s var(--ease-standard);
}

.xv-faq-key:nth-of-type(2) { transition-delay: 0.14s; }
.xv-faq-key:nth-of-type(3) { transition-delay: 0.28s; }
.xv-faq-key:nth-of-type(4) { transition-delay: 0.42s; }

.xv-faq-a--settling .xv-faq-key {
  color: inherit;
  background-size: 0% 100%;
  transition: none;
}

/* -------- FAQ accordion motion -------- */
/* Answers slide open and closed instead of snapping. Browsers without
   ::details-content / interpolate-size fall back to the instant
   toggle, as does reduced motion. */

@media (prefers-reduced-motion: no-preference) {
  .xv-faq details {
    interpolate-size: allow-keywords;
  }
  .xv-faq details::details-content {
    block-size: 0;
    overflow: clip;
    transition: block-size var(--dur-slow) var(--ease-out),
                content-visibility var(--dur-slow) allow-discrete;
  }
  .xv-faq details[open]::details-content {
    block-size: auto;
  }
}

/* -------- Managed marquees -------- */
/* Added by marquee_controller on the ticker and client bands: the
   drift eases to a stop on hover and the loop can be dragged. */

.xv-marquee-managed {
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: pan-y;
}

.xv-marquee-dragging {
  cursor: grabbing;
}

/* -------- Service cards (drawn construction) -------- */
/* Echoes the icon's outlined-prism look: sharp corners, ink outline,
   a flat offset for depth, and a numbered corner square. The offset is
   two positioned strips rather than a box-shadow: at rest they match a
   7px 7px shadow exactly; on hover they extend to the card's top and
   left edges, turning shading into the full-length parallel lines the
   logo's prisms are drawn with. The number square carries the orange.
   Inset values are relative to the padding box, hence the 1.5px border
   arithmetic. */

.xv-svc-card {
  position: relative;
  background: var(--xv-paper);
  border: 1.5px solid var(--xv-navy);
  border-radius: 0;
}

.xv-svc-card::before,
.xv-svc-card::after {
  content: "";
  position: absolute;
  background: var(--xv-blue);
}

/* Right strip */
.xv-svc-card::before {
  top: 5.5px;
  right: -8.5px;
  bottom: -8.5px;
  width: 7px;
  transition: top var(--dur-2) var(--ease-standard);
}

/* Bottom strip */
.xv-svc-card::after {
  left: 5.5px;
  bottom: -8.5px;
  right: -8.5px;
  height: 7px;
  transition: left var(--dur-2) var(--ease-standard);
}

.xv-svc-card:hover::before,
a:focus-visible > .xv-svc-card::before {
  top: -1.5px;
}

.xv-svc-card:hover::after,
a:focus-visible > .xv-svc-card::after {
  left: -1.5px;
  /* The bottom stroke draws a beat after the right one; both retract
     together on mouse-out (the base rule has no delay). */
  transition-delay: 90ms;
}

.xv-svc-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1.5px solid var(--xv-navy);
  border-radius: 0;
  color: var(--xv-navy);
  transition: background var(--dur-2) var(--ease-standard),
              border-color var(--dur-2) var(--ease-standard),
              color var(--dur-2) var(--ease-standard);
}

.xv-svc-card:hover .xv-svc-num,
a:focus-visible > .xv-svc-card .xv-svc-num {
  background: var(--xv-orange);
  border-color: var(--xv-orange);
  color: #fff;
}

/* -------- Founder card candid portrait -------- */
/* At rest the portrait looks at the visitor. The candid frame from the
   same shoot appears only while the band's form has focus: the founder
   noticing that someone is writing. Hovering the card keeps its lift
   but never switches the photo. */

.xv-founder-card-media {
  position: relative;
  display: block;
}

.xv-founder-card-photo--candid {
  position: absolute;
  inset: 0;
  height: 100%;
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease-standard);
}

.xv-lead-band:has(.xv-input:focus) .xv-founder-card-photo--candid {
  opacity: 1;
}

/* Contact doors as a single centred row under the band's photo + form */
.xv-lead-doors--row {
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  column-gap: 36px;
  row-gap: 8px;
}

/* -------- Footer newsletter panel -------- */
/* The signup gets the drawn-construction treatment on a light surface,
   so it pops out of the navy footer instead of dissolving into it. */

.xv-news-panel {
  background: var(--xv-mist);
  color: var(--xv-charcoal);
  border: 1.5px solid var(--xv-navy);
  border-radius: 0;
  box-shadow: 7px 7px 0 var(--xv-blue);
  padding: clamp(22px, 3vw, 34px);
}
.xv-news-panel .xv-h3 {
  color: var(--xv-navy);
}
