/* ==========================================================================
   PatientZer0 — stylesheet
   Plain CSS, no framework. Sections run top to bottom in the same order as
   index.html. Brand colours are the custom properties in :root below.
   ========================================================================== */

:root {
  /* Brand */
  --purple: #6d28d9;
  --violet: #7c3aed;
  --blue: #2563eb;
  --sky: #3b82f6;
  --ink: #12101f;
  --paper: #fafaff;
  --white: #fff;
  --danger: #dc2626;

  /* Ink tints (text on light backgrounds) */
  --ink-70: rgba(18, 16, 31, 0.7);
  --ink-60: rgba(18, 16, 31, 0.6);
  --ink-45: rgba(18, 16, 31, 0.45);
  --ink-35: rgba(18, 16, 31, 0.35);
  --ink-15: rgba(18, 16, 31, 0.15);
  --ink-08: rgba(18, 16, 31, 0.08);

  /* Type */
  --font-heading: 'Blinker', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body: 'Roboto', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --radius: 16px;
  --radius-sm: 10px;
  --shell: 1152px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- Reset ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
* {
  margin: 0;
}
html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
body {
  font-family: var(--font-body);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
img,
svg {
  display: block;
  max-width: 100%;
}
/* Must beat any class that sets `display`, or [hidden] elements stay visible. */
[hidden] {
  display: none !important;
}
ul {
  list-style: none;
  padding: 0;
}
a {
  color: inherit;
  text-decoration: none;
}
button,
input {
  font: inherit;
  color: inherit;
}
h1,
h2,
h3 {
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

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

/* Icons: stroked by default */
svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
svg.filled {
  fill: currentColor;
  stroke: none;
}
.icon {
  width: 1.05em;
  height: 1.05em;
  flex: none;
}
/* Symbol definitions only — never painted itself, but must stay in the layout
   tree (not display:none) for <use> to resolve reliably. */
.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}
/* Announced by screen readers, invisible on screen. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Layout ---------- */
.container {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: 20px;
}
.section {
  position: relative;
  padding-block: 80px;
  overflow: hidden;
}
.section-white {
  background: var(--white);
}
.section-paper {
  background: var(--paper);
}
.section-dark {
  background: var(--ink);
  color: var(--white);
}
.split {
  display: grid;
  gap: 48px;
  align-items: center;
}

/* Narrower measure for long-form reading — the FAQ answers get unreadable
   at the full shell width. */
.container-narrow {
  max-width: 46rem;
}

/* ---------- USP bar ---------- */
/* Thin strip under the hero. Ink like the hero above it, so it reads as the
   hero's base rather than a separate band. */
.usp-bar {
  background: var(--ink);
  color: var(--white);
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  padding-block: 18px;
}
.usp-list {
  display: grid;
  gap: 14px 28px;
}
.usp-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.7);
}
.usp-list strong {
  color: var(--white);
}
.usp-list svg {
  width: 20px;
  height: 20px;
  flex: none;
  color: var(--sky);
  stroke-width: 1.8;
}

/* ---------- FAQ ---------- */
.faq-list {
  display: grid;
  gap: 12px;
  margin-top: 36px;
}
.faq {
  border-radius: var(--radius);
  border: 1px solid var(--ink-08);
  background: var(--paper);
  transition: border-color 0.2s;
}
.faq[open] {
  border-color: rgba(109, 40, 217, 0.3);
}
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 22px;
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.02rem;
  list-style: none; /* hide the default marker, Firefox */
}
.faq summary::-webkit-details-marker {
  display: none; /* and Safari/Chrome */
}
.faq summary:hover {
  color: var(--purple);
}
.faq-chevron {
  width: 20px;
  height: 20px;
  flex: none;
  color: var(--purple);
  transition: transform 0.25s var(--ease);
}
.faq[open] .faq-chevron {
  transform: rotate(180deg);
}
.faq p {
  padding: 0 22px 20px;
  color: var(--ink-70);
}

/* ---------- Buttons ---------- */
.btn-primary,
.btn-outline,
.btn-alert,
.btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: 12px;
  border: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  cursor: pointer;
  transition:
    filter 0.2s,
    box-shadow 0.2s,
    background 0.2s,
    border-color 0.2s;
}
.btn-primary {
  background: linear-gradient(90deg, var(--purple), var(--blue));
  color: var(--white);
  padding: 12px 22px;
  font-size: 1.05rem;
  box-shadow: 0 8px 20px rgba(109, 40, 217, 0.28);
}
.btn-primary:hover {
  filter: brightness(1.1);
  box-shadow: 0 12px 26px rgba(109, 40, 217, 0.34);
}
.btn-sm {
  padding: 9px 17px;
  font-size: 0.9rem;
}
.btn-lg {
  padding: 15px 26px;
  font-size: 1.1rem;
}
.btn-outline {
  border: 2px solid rgba(109, 40, 217, 0.25);
  color: var(--purple);
  background: transparent;
  padding: 11px 22px;
  font-size: 1.05rem;
}
.btn-outline:hover {
  border-color: var(--purple);
  background: rgba(109, 40, 217, 0.04);
}
/* Same button on an ink section, where the purple-on-dark of .btn-outline
   would fall away. */
.btn-outline-light {
  border-color: rgba(255, 255, 255, 0.3);
  color: var(--white);
}
.btn-outline-light:hover {
  border-color: rgba(167, 139, 250, 0.8);
  background: rgba(124, 58, 237, 0.18);
}
.btn-alert {
  background: var(--danger);
  border: 1px solid var(--danger);
  color: var(--white);
  padding: 8px 14px;
  font-size: 0.9rem;
  border-radius: var(--radius-sm);
}
.btn-alert:hover {
  background: #b91c1c;
  border-color: #b91c1c;
}
.btn-danger {
  background: var(--danger);
  color: var(--white);
  padding: 14px 24px;
  font-size: 1.1rem;
  box-shadow: 0 8px 20px rgba(220, 38, 38, 0.25);
}
.btn-danger:hover {
  background: #ef4444;
}
.full {
  width: 100%;
}

/* ---------- Header ---------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 40;
}
.header-bg {
  position: absolute;
  inset: 0;
  background: var(--white);
  border-bottom: 1px solid rgba(18, 16, 31, 0.05);
  box-shadow: 0 4px 18px rgba(18, 16, 31, 0.08);
  opacity: 0;
  transition: opacity 0.25s;
}
.site-header.scrolled .header-bg {
  opacity: 1;
}
.header-inner {
  position: relative;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.logo {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}
.logo-img {
  display: block;
  height: 38px;
  width: auto;
}
/* Two marks, stacked in one grid cell so the swap crossfades without moving
   anything: the white one reads over the transparent hero, the gradient one
   takes over as soon as the white header background fades in (scrolled, or
   mobile menu open). */
.site-header .logo {
  display: inline-grid;
}
.site-header .logo-img {
  grid-area: 1 / 1;
  height: 28px;
  transition: opacity 0.25s;
}
/* The hero-state logo is the full wordmark rather than the bare mark, so it
   is set taller — its tagline sits in the lower third and needs the height
   to stay legible. Both still share one grid cell and crossfade in place. */
.site-header .logo-img-top {
  height: 36px;
  justify-self: start;
}
.site-header .logo-img-solid,
.site-header.scrolled .logo-img-top,
.site-header.menu-open .logo-img-top {
  opacity: 0;
}
.site-header.scrolled .logo-img-solid,
.site-header.menu-open .logo-img-solid {
  opacity: 1;
}
.nav-desktop {
  display: none;
  gap: 28px;
}
.nav-desktop a {
  font-size: 0.9rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.7);
  transition: color 0.2s;
}
.nav-desktop a:hover {
  color: var(--white);
}
.site-header.scrolled .nav-desktop a {
  color: var(--ink-60);
}
.site-header.scrolled .nav-desktop a:hover {
  color: var(--purple);
}
.header-actions {
  display: none;
  align-items: center;
  gap: 12px;
}
.menu-toggle {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--white);
  cursor: pointer;
}
.site-header.scrolled .menu-toggle,
.site-header.menu-open .menu-toggle {
  color: var(--ink);
}
.menu-toggle svg {
  width: 22px;
  height: 22px;
}
.menu-toggle .icon-close,
.site-header.menu-open .menu-toggle .icon-menu {
  display: none;
}
.site-header.menu-open .menu-toggle .icon-close {
  display: block;
}
.site-header.menu-open .header-bg {
  opacity: 1;
}

.mobile-menu {
  position: relative;
  background: rgba(255, 255, 255, 0.97);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid rgba(18, 16, 31, 0.05);
  padding: 8px 20px 18px;
  display: grid;
  gap: 10px;
}
.mobile-menu nav {
  display: grid;
}
.mobile-menu nav a {
  padding: 11px 12px;
  border-radius: var(--radius-sm);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ink-70);
}
.mobile-menu nav a:hover {
  background: rgba(109, 40, 217, 0.06);
  color: var(--purple);
}
.mobile-menu .btn-alert {
  padding: 12px;
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  background: var(--ink);
  color: var(--white);
  overflow: hidden;
  padding-block: 120px 72px;
}
.hero-bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
/* Background clip pairs, used by the hero and the footer. The resting opacity
   lives on the per-place class below and is read straight off the element by
   main.js, which then scales it down near each clip's start and end so the
   pair crossfades. No blend mode: the footage is bright, and screen blending
   would blow out the ink ground. */
.video-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
/* Clips waiting their turn sit at zero so nothing shows through the one
   playing. main.js takes over the opacity of whichever clip is current. */
.video-bg-queued {
  opacity: 0;
}
.hero-art {
  transform: scale(1.05);
  opacity: 0.45;
}
/* Gentler than the hero — this section's headline shares the frame with the
   white wizard card, so the footage stays well back. */
.cta-art {
  opacity: 0.18;
}
/* Scrims protect the headline column and blend into the next section. */
.hero-scrim-x {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--ink) 8%, rgba(18, 16, 31, 0.3) 45%, transparent);
}
.hero-scrim-y {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent, transparent 60%, var(--ink) 95%);
}
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(110px);
}
.orb-purple {
  top: -160px;
  left: 22%;
  width: 34rem;
  height: 34rem;
  background: rgba(109, 40, 217, 0.25);
  animation: pulse-orb 9s ease-in-out infinite;
}
.orb-blue {
  top: 33%;
  right: -128px;
  width: 28rem;
  height: 28rem;
  background: rgba(37, 99, 235, 0.2);
  animation: pulse-orb 11s ease-in-out infinite reverse;
}
@keyframes pulse-orb {
  0%,
  100% {
    opacity: 0.5;
    transform: scale(1);
  }
  50% {
    opacity: 0.85;
    transform: scale(1.08);
  }
}
.grid-overlay {
  position: absolute;
  inset: 0;
  opacity: 0.06;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.5) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.5) 1px, transparent 1px);
  background-size: 56px 56px;
}
.hero-grid {
  position: relative;
  display: grid;
  gap: 44px;
  align-items: center;
}
.hero h1 {
  font-size: clamp(2.1rem, 6vw, 3.4rem);
  line-height: 1.08;
}
.gradient-text {
  background: linear-gradient(90deg, var(--violet), var(--sky));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero-sub {
  margin-top: 20px;
  max-width: 36rem;
  font-size: 1.12rem;
  color: rgba(255, 255, 255, 0.66);
}
.eyebrow-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 20px;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.06);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}
.eyebrow-pill .icon {
  color: var(--sky);
}
.eyebrow-pill-light {
  border-color: rgba(109, 40, 217, 0.2);
  background: rgba(109, 40, 217, 0.06);
  color: var(--purple);
}
.eyebrow-pill-light .icon {
  color: var(--purple);
}

/* threat pulse */
.pulse {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-top: 26px;
  padding: 11px 16px;
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(4px);
  font-size: 0.9rem;
}
.pulse-dot {
  position: relative;
  width: 10px;
  height: 10px;
  flex: none;
}
.pulse-dot .ping,
.pulse-dot .dot {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: currentColor;
}
.pulse-dot .ping {
  animation: ping 1.6s cubic-bezier(0, 0, 0.2, 1) infinite;
  opacity: 0.6;
}
@keyframes ping {
  75%,
  100% {
    transform: scale(2.2);
    opacity: 0;
  }
}
.pulse-label {
  font-weight: 700;
}
.pulse-detail {
  color: rgba(255, 255, 255, 0.5);
}
.pulse.state-detected {
  color: #f87171;
}
.pulse.state-quarantined {
  color: #fcd34d;
}
.pulse.state-online {
  color: #34d399;
}
.pulse-fade {
  animation: pulse-in 0.35s var(--ease);
}
@keyframes pulse-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.trust-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  margin-top: 28px;
  font-size: 0.87rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.6);
}
.trust-strip li {
  display: flex;
  align-items: center;
  gap: 8px;
}
.trust-strip .icon {
  width: 17px;
  height: 17px;
  color: var(--sky);
}

/* ---------- Section headings ---------- */
.section-head {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
  margin-bottom: 48px;
}
.eyebrow {
  margin-bottom: 12px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--purple);
}
.eyebrow-light {
  color: var(--sky);
}
.section h2 {
  font-size: clamp(1.7rem, 4vw, 2.35rem);
}
.lede {
  margin-top: 16px;
  font-size: 1.1rem;
  color: var(--ink-60);
}
.section-dark .lede {
  color: rgba(255, 255, 255, 0.6);
}
.lede-left {
  max-width: 34rem;
}

/* ---------- Cards ---------- */
.cards-2,
.cards-3,
.cards-4 {
  display: grid;
  gap: 20px;
}
.card {
  position: relative;
  padding: 26px;
  border-radius: var(--radius);
  border: 1px solid rgba(18, 16, 31, 0.07);
  background: var(--white);
  box-shadow: 0 1px 2px rgba(18, 16, 31, 0.04);
  transition:
    transform 0.3s var(--ease),
    box-shadow 0.3s,
    border-color 0.3s;
}
.card:hover {
  transform: translateY(-4px);
  border-color: rgba(109, 40, 217, 0.25);
  box-shadow: 0 18px 40px rgba(109, 40, 217, 0.12);
}
.card h3 {
  font-size: 1.2rem;
}
.card p {
  margin-top: 8px;
  color: var(--ink-60);
}
.card-dark {
  border-color: rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.04);
  box-shadow: none;
}
.card-dark:hover {
  border-color: rgba(124, 58, 237, 0.5);
  background: rgba(255, 255, 255, 0.07);
  box-shadow: none;
}
.card-dark p {
  color: rgba(255, 255, 255, 0.55);
}
/* Bare icons, no tile behind them — the glyph itself carries the brand
   colour, so a lighter stroke keeps it from looking heavy at this size. */
.card-icon {
  display: inline-grid;
  place-items: center;
  margin-bottom: 16px;
  color: var(--purple);
  transition: color 0.3s;
}
.card:hover .card-icon {
  color: var(--blue);
}
.card-icon svg {
  width: 36px;
  height: 36px;
  stroke-width: 1.6;
}
/* On the ink cards the purple goes muddy; sky reads cleanly instead. */
.card-icon-solid {
  color: var(--sky);
}
.card-dark:hover .card-icon {
  color: var(--white);
}
.step-num {
  position: absolute;
  top: 20px;
  right: 20px;
  font-family: var(--font-heading);
  font-size: 0.85rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.2);
}
.card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}
.card-head .card-icon {
  margin-bottom: 0;
}

/* tick lists */
.ticks {
  display: grid;
  gap: 10px;
}
.ticks li {
  position: relative;
  padding-left: 26px;
  font-size: 0.96rem;
  line-height: 1.45;
  color: var(--ink-70);
}
.ticks li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.42em;
  width: 13px;
  height: 7px;
  border-left: 2px solid var(--purple);
  border-bottom: 2px solid var(--purple);
  transform: rotate(-45deg);
}

/* add-ons */
.addons {
  margin-top: 28px;
  padding: 26px;
  border-radius: var(--radius);
  border: 1px dashed rgba(109, 40, 217, 0.3);
  background: rgba(109, 40, 217, 0.04);
}
.addons h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1.08rem;
  margin-bottom: 16px;
}
.addons h3 .icon {
  color: var(--purple);
}
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.chips li {
  padding: 6px 16px;
  border-radius: 999px;
  border: 1px solid rgba(109, 40, 217, 0.2);
  background: var(--white);
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--ink-70);
}

/* check grid (agencies) */
.check-grid {
  display: grid;
  gap: 10px;
  margin-top: 26px;
}
.check-grid li {
  position: relative;
  padding-left: 30px;
  font-size: 0.96rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.75);
}
.check-grid li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.15em;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: rgba(59, 130, 246, 0.2);
}
.check-grid li::after {
  content: '';
  position: absolute;
  left: 6px;
  top: 0.5em;
  width: 8px;
  height: 4px;
  border-left: 2px solid var(--sky);
  border-bottom: 2px solid var(--sky);
  transform: rotate(-45deg);
}
.check-grid + div {
  margin-top: 32px;
}

/* Full-bleed background image on a dark section. The image is bright neon,
   so it sits well below the white text — keep the opacity low. */
.section-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.18;
  pointer-events: none;
}

/* glows */
.glow-top {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse at top, rgba(109, 40, 217, 0.22), transparent 55%);
}
.glow-corner {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse at bottom left, rgba(37, 99, 235, 0.2), transparent 55%),
    radial-gradient(ellipse at top right, rgba(124, 58, 237, 0.18), transparent 50%);
}
.section-dark .container {
  position: relative;
}

/* ---------- Image placeholders ---------- */
.placeholder {
  display: grid;
  place-items: center;
  padding: 24px;
  text-align: center;
  border-radius: var(--radius);
  border: 1px dashed rgba(109, 40, 217, 0.25);
  background: linear-gradient(135deg, rgba(109, 40, 217, 0.06), rgba(37, 99, 235, 0.08));
  color: var(--ink-35);
  font-size: 0.85rem;
  font-weight: 500;
}
.placeholder-dark {
  border-color: rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.04);
  color: rgba(255, 255, 255, 0.4);
}
.ratio-wide {
  aspect-ratio: 16 / 7;
}
.ratio-banner {
  aspect-ratio: 16 / 6;
  margin-top: 40px;
}
.ratio-portrait {
  aspect-ratio: 4 / 3;
}

/* Row of product shots. These mockups ship on a white ground, which on the
   ink section would read as three bright slabs — so each one is rounded off
   and given a hairline, letting its own ground act as the card. Blend modes
   are no help here: multiply would crush the screenshots into the dark
   background, screen would leave the white ground glowing. */
.shot-grid {
  display: grid;
  gap: 18px;
  margin-top: 40px;
}
.shot-open {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  border-radius: var(--radius);
  cursor: zoom-in;
  transition:
    transform 0.3s var(--ease),
    box-shadow 0.3s;
}
.shot-open:hover {
  transform: translateY(-4px);
}
/* Same layered purple glow as .split-shot — a hairline edge plus two soft
   falloffs, so the shots read as lit rather than outlined. Hovering lifts the
   card and pushes the glow up rather than dropping a black shadow, which
   would muddy the purple. */
.shot-grid img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  box-shadow:
    0 0 0 1px rgba(124, 58, 237, 0.45),
    0 0 40px rgba(124, 58, 237, 0.45),
    0 0 90px rgba(109, 40, 217, 0.3);
  transition: box-shadow 0.3s;
}
.shot-open:hover img {
  box-shadow:
    0 0 0 1px rgba(167, 139, 250, 0.7),
    0 0 55px rgba(124, 58, 237, 0.65),
    0 0 120px rgba(109, 40, 217, 0.45);
}

/* Full-width artwork closing a section, at its own aspect ratio rather than
   cropped. The artwork sits on a white ground, so multiply drops that ground
   into the page instead of leaving a pale slab on the off-white section.
   Only safe while the section behind it stays light. */
.banner-shot {
  display: block;
  width: 100%;
  height: auto;
  margin-top: 40px;
  mix-blend-mode: multiply;
}

/* Flex rather than a plain block so further buttons can sit alongside and
   wrap cleanly on narrow screens. */
.cta-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 26px;
}

/* Wordmark sitting above the closing CTA heading. Width-capped rather than
   height-fixed so it scales down with the column on narrow screens, and
   capped tighter on phones where it otherwise crowds the headline. */
.cta-logo {
  width: 100%;
  max-width: 14rem;
  height: auto;
  margin-bottom: 18px;
}
@media (min-width: 768px) {
  .cta-logo {
    max-width: 19rem;
    margin-bottom: 22px;
  }
}

/* Artwork filling one column of a .split. No blend mode here — this artwork
   is dark and belongs on a dark section, so it composites straight. A drawn
   purple border rings the image, with two soft falloffs outside it so the
   glow reads as light spilling off the edge rather than a second outline. */
.split-shot {
  display: block;
  width: 100%;
  height: auto;
  align-self: center;
  border: 2px solid var(--violet);
  border-radius: var(--radius);
  box-shadow:
    0 0 50px rgba(124, 58, 237, 0.5),
    0 0 110px rgba(109, 40, 217, 0.35);
}

/* Product shots. The mockup ships on a white ground, so multiply drops that
   ground into the page rather than leaving a pale rectangle floating on the
   off-white section. Only safe while the section behind it stays light. */
.shot {
  display: block;
  width: 100%;
  height: auto;
  align-self: center;
  mix-blend-mode: multiply;
}

/* ---------- Pricing ---------- */
.pricing-grid {
  display: grid;
  gap: 22px;
}
.tier {
  display: flex;
  flex-direction: column;
  padding: 26px;
  border-radius: var(--radius);
  border: 1px solid var(--ink-08);
  background: var(--paper);
  transition:
    transform 0.3s var(--ease),
    box-shadow 0.3s;
}
.tier:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 40px rgba(109, 40, 217, 0.12);
}
.tier h3 {
  font-size: 1.2rem;
}
.tier-blurb {
  margin-top: 4px;
  font-size: 0.9rem;
  color: var(--ink-45);
}
.tier-price {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin: 18px 0 22px;
}
.tier-price .amount {
  font-family: var(--font-heading);
  font-size: 2.4rem;
  font-weight: 700;
}
/* Purple reads well on the light cards; the featured card is ink, so its
   price stays white. */
.tier:not(.tier-featured) .tier-price .amount {
  color: var(--purple);
}
.tier-price .per,
.tier-price .from {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--ink-45);
}
/* Sits under the price, so it pulls up into the price's bottom margin. */
.tier-setup {
  margin: -14px 0 22px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-45);
}
.tier .ticks {
  flex: 1;
  margin-bottom: 26px;
}
.tier-featured {
  position: relative;
  background: var(--ink);
  color: var(--white);
  border-color: rgba(124, 58, 237, 0.4);
  box-shadow: 0 24px 50px rgba(109, 40, 217, 0.25);
}
.tier-featured .tier-blurb,
.tier-featured .tier-setup,
.tier-featured .tier-price .per,
.tier-featured .tier-price .from {
  color: rgba(255, 255, 255, 0.55);
}
.tier-featured .ticks li {
  color: rgba(255, 255, 255, 0.8);
}
.tier-featured .ticks li::before {
  border-color: var(--sky);
}
.tier-badge {
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%);
  padding: 4px 16px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--purple), var(--blue));
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 8px 18px rgba(109, 40, 217, 0.3);
}
/* Tinted panel so the closing reassurance reads as a block of its own rather
   than as small print trailing off the bottom of the pricing grid. */
.reassure {
  margin-top: 40px;
  padding: 30px 26px;
  border-radius: var(--radius);
  border: 1px solid rgba(109, 40, 217, 0.16);
  background: linear-gradient(135deg, rgba(109, 40, 217, 0.06), rgba(37, 99, 235, 0.06));
  text-align: center;
}
.reassure-line {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
}
.reassure-line strong {
  background: linear-gradient(90deg, var(--purple), var(--blue));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.reassure ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 20px;
}
/* Each promise as its own tinted chip, with a brand tick in front. */
.reassure li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px;
  border-radius: 999px;
  border: 1px solid rgba(109, 40, 217, 0.2);
  background: var(--white);
  font-size: 0.87rem;
  font-weight: 700;
  color: var(--purple);
}
.reassure li::before {
  content: '';
  width: 11px;
  height: 6px;
  flex: none;
  border-left: 2px solid var(--blue);
  border-bottom: 2px solid var(--blue);
  transform: translateY(-2px) rotate(-45deg);
}

/* ---------- Social proof ---------- */
.stats {
  display: grid;
  gap: 20px;
}
.stat {
  padding: 30px;
  text-align: center;
  border-radius: var(--radius);
  border: 1px solid rgba(18, 16, 31, 0.07);
  background: var(--white);
}
.stat-value {
  font-family: var(--font-heading);
  font-size: clamp(2.2rem, 6vw, 3rem);
  font-weight: 700;
  background: linear-gradient(90deg, var(--purple), var(--sky));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.stat-label {
  margin-top: 6px;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-45);
}
.stat-note {
  margin-top: 12px;
  text-align: center;
  font-size: 0.75rem;
  color: var(--ink-35);
}
.testimonials {
  margin-top: 44px;
}
/* Solid, not the dashed border these carried while they held placeholder
   text — dashed reads as unfinished now the quotes are real. */
.quote {
  display: flex;
  flex-direction: column;
  padding: 26px;
  border-radius: var(--radius);
  border: 1px solid rgba(18, 16, 31, 0.08);
  background: var(--white);
  box-shadow: 0 1px 2px rgba(18, 16, 31, 0.04);
}
.quote-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.stars {
  display: flex;
  gap: 2px;
}
.stars svg {
  width: 17px;
  height: 17px;
  fill: #fbbc04; /* Google's review-star amber */
  stroke: none;
}
.g-badge svg {
  width: 20px;
  height: 20px;
  stroke: none; /* the four brand fills live on the paths */
}
.quote p {
  flex: 1;
  color: var(--ink-70);
}
.quote-person {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid rgba(18, 16, 31, 0.07);
}
.quote-who {
  display: grid;
  line-height: 1.35;
}
.quote-who strong {
  font-size: 0.95rem;
}
.quote-who span {
  font-size: 0.85rem;
  color: var(--ink-45);
}

/* logo marquee */
.carousel-note {
  margin-top: 56px;
  text-align: center;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-35);
}
.marquee {
  margin-top: 24px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 15%, #000 85%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 15%, #000 85%, transparent);
}
.marquee-track {
  display: flex;
  gap: 24px;
  width: max-content;
  animation: marquee 28s linear infinite;
}
@keyframes marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}
.marquee-item {
  display: grid;
  place-items: center;
  width: 160px;
  height: 72px;
  flex: none;
  padding: 0 18px;
  border-radius: 12px;
  border: 1px solid rgba(18, 16, 31, 0.07);
  background: var(--white);
}
/* Per-logo height comes from main.js; the width cap stops the widest
   wordmarks from crowding their tile. */
.marquee-logo {
  max-width: 100%;
  width: auto;
  object-fit: contain;
}

/* ---------- Wizard ---------- */
.wizard {
  padding: 24px;
  border-radius: var(--radius);
  background: var(--white);
  color: var(--ink);
  box-shadow: 0 24px 50px rgba(109, 40, 217, 0.12);
  border: 1px solid rgba(18, 16, 31, 0.05);
}
.wiz-progress-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-45);
}
.wiz-progress-row .pct {
  color: var(--purple);
}
.wiz-bar {
  height: 6px;
  border-radius: 999px;
  background: rgba(18, 16, 31, 0.06);
  overflow: hidden;
  margin-bottom: 22px;
}
.wiz-bar span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--purple), var(--sky));
  transition: width 0.4s var(--ease);
}
.wiz-body {
  min-height: 320px;
}
.wiz-step {
  animation: step-in 0.3s var(--ease);
}
@keyframes step-in {
  from {
    opacity: 0;
    transform: translateX(24px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.wiz-title {
  font-size: 1.18rem;
  margin-bottom: 4px;
}
.wiz-hint {
  font-size: 0.87rem;
  color: rgba(18, 16, 31, 0.5);
  margin-bottom: 12px;
}
.wiz-options {
  display: grid;
  gap: 10px;
}
.wiz-options.two-col {
  grid-template-columns: 1fr 1fr;
}
.opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 13px 16px;
  text-align: left;
  font-size: 0.95rem;
  font-weight: 500;
  border-radius: 12px;
  border: 1px solid rgba(18, 16, 31, 0.1);
  background: var(--white);
  color: rgba(18, 16, 31, 0.8);
  cursor: pointer;
  transition:
    border-color 0.2s,
    background 0.2s,
    color 0.2s,
    box-shadow 0.2s;
}
.opt:hover {
  border-color: rgba(109, 40, 217, 0.4);
  background: rgba(109, 40, 217, 0.03);
}
.opt .box {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  flex: none;
  border: 1px solid rgba(18, 16, 31, 0.2);
  border-radius: 50%;
  background: var(--white);
  transition:
    background 0.2s,
    border-color 0.2s;
}
.opt.multi .box {
  border-radius: 6px;
}
.opt .box svg {
  width: 12px;
  height: 12px;
  stroke: var(--white);
  stroke-width: 2.6;
  opacity: 0;
}
.opt[aria-checked='true'] {
  border-color: var(--purple);
  background: rgba(109, 40, 217, 0.06);
  color: var(--purple);
  box-shadow: 0 0 0 1px var(--purple);
}
.opt[aria-checked='true'] .box {
  background: var(--purple);
  border-color: var(--purple);
}
.opt[aria-checked='true'] .box svg {
  opacity: 1;
}

.wiz-fields {
  display: grid;
  gap: 12px;
}
.field-row {
  display: grid;
  gap: 12px;
}
.wizard label {
  display: block;
  margin-bottom: 4px;
  font-size: 0.87rem;
  font-weight: 600;
  color: var(--ink-70);
}
.wizard input[type='text'],
.wizard input[type='email'],
.wizard input[type='tel'],
.wizard input[type='datetime-local'],
.modal input {
  width: 100%;
  padding: 10px 14px;
  font-size: 0.95rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--ink-15);
  background: var(--white);
  transition:
    border-color 0.2s,
    box-shadow 0.2s;
}
.wizard input:focus,
.modal input:focus {
  outline: none;
  border-color: var(--purple);
  box-shadow: 0 0 0 3px rgba(109, 40, 217, 0.2);
}
.req {
  color: var(--purple);
}
.consent {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 4px;
  font-size: 0.87rem;
  font-weight: 400;
  color: var(--ink-60);
  cursor: pointer;
}
.consent input {
  margin-top: 3px;
  width: 16px;
  height: 16px;
  flex: none;
  accent-color: var(--purple);
}
.honeypot {
  position: absolute;
  left: -9999px;
}
.wiz-submit {
  margin-top: 8px;
}
/* Shown when send.php can't be reached or refuses the enquiry. */
.form-error {
  margin-top: 12px;
  font-size: 0.87rem;
  line-height: 1.5;
  color: var(--danger);
}
.form-error a {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
}
button[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
  box-shadow: none;
}
.wiz-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 20px;
  min-height: 42px;
}
.wiz-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 0;
  font-size: 0.88rem;
  font-weight: 600;
  color: rgba(18, 16, 31, 0.5);
  cursor: pointer;
}
.wiz-back:hover {
  color: var(--ink);
}
.wiz-next {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 20px;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--purple);
  color: var(--white);
  font-family: var(--font-heading);
  font-size: 0.88rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 6px 14px rgba(109, 40, 217, 0.25);
}
.wiz-next:hover:not([disabled]) {
  filter: brightness(1.1);
}
.wiz-done {
  display: grid;
  place-items: center;
  min-height: 416px;
  text-align: center;
  padding: 16px;
}
.wiz-done .done-icon {
  width: 56px;
  height: 56px;
  margin-inline: auto;
  color: var(--purple);
  animation: pop 0.5s var(--ease);
}
@keyframes pop {
  from {
    opacity: 0;
    transform: scale(0.6);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.wiz-done h3 {
  margin-top: 18px;
  font-size: 1.45rem;
}
.wiz-done p {
  margin-top: 12px;
  max-width: 24rem;
  color: var(--ink-60);
}

/* ---------- Modal ---------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 20px;
}
.modal[hidden] {
  display: none;
}
.modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(18, 16, 31, 0.6);
  backdrop-filter: blur(4px);
  animation: fade 0.25s;
}
@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.modal-panel {
  position: relative;
  width: 100%;
  max-width: 27rem;
  padding: 28px;
  border-radius: var(--radius);
  background: var(--white);
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.35);
  animation: pop-modal 0.3s var(--ease);
}
@keyframes pop-modal {
  from {
    opacity: 0;
    transform: scale(0.92) translateY(16px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-35);
  cursor: pointer;
}
.modal-close:hover {
  background: rgba(18, 16, 31, 0.05);
  color: var(--ink);
}
.modal-close svg {
  width: 18px;
  height: 18px;
}
.pill-alert {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: 999px;
  background: #fef2f2;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--danger);
}
.modal-panel h3 {
  margin-top: 10px;
  font-size: 1.45rem;
}

/* ---------- Article pages ---------- */
.article-hero {
  position: relative;
  padding-block: 108px 56px;
  background: var(--ink);
  color: var(--white);
  overflow: hidden;
}
.article-bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
/* Fainter than the home hero: this block is mostly text, and the headline
   here runs the full width rather than sitting in a protected column. */
.article-art {
  opacity: 0.32;
}
/* Darkens the footage under the copy and blends the bottom edge into the
   section below, the way the home hero's scrims do. */
.article-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(18, 16, 31, 0.72), rgba(18, 16, 31, 0.55) 55%, var(--ink)),
    linear-gradient(90deg, rgba(18, 16, 31, 0.65), transparent 70%);
}
.article-hero > .container {
  position: relative;
}
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 18px;
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.45);
}
.breadcrumb a:hover {
  color: var(--white);
}
.breadcrumb svg {
  width: 13px;
  height: 13px;
  opacity: 0.5;
}
.article-hero h1 {
  font-size: clamp(2rem, 5vw, 3rem);
  max-width: 20ch;
}
.article-hero .lede {
  margin-top: 16px;
  max-width: 46rem;
  color: rgba(255, 255, 255, 0.6);
}
.article-meta {
  margin-top: 22px;
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.4);
}

/* Long-form body copy. Spacing is set on the flow rather than per element so
   new headings and lists inherit the rhythm automatically. */
.prose > * + * {
  margin-top: 18px;
}
.prose h2 {
  margin-top: 44px;
  font-size: clamp(1.4rem, 3vw, 1.75rem);
}
.prose h3 {
  margin-top: 32px;
  font-size: 1.12rem;
}
.prose p,
.prose li {
  color: var(--ink-70);
}
.prose ul,
.prose ol {
  display: grid;
  gap: 10px;
  padding-left: 22px;
}
.prose ul {
  list-style: disc;
}
.prose ol {
  list-style: decimal;
}
.prose li::marker {
  color: var(--purple);
}
.prose strong {
  color: var(--ink);
}
/* Scoped to running text only. Targeting every link in .prose also caught the
   related-guide cards and the CTA buttons, underlining them and overriding
   their colours. */
.prose p a,
.prose li a {
  color: var(--purple);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.prose p a:hover,
.prose li a:hover {
  color: var(--blue);
}
/* Pulled-out aside — used for the "what we actually see" notes. */
.callout {
  margin-top: 28px;
  padding: 22px 24px;
  border-radius: var(--radius);
  border: 1px solid rgba(109, 40, 217, 0.2);
  border-left: 4px solid var(--purple);
  background: linear-gradient(135deg, rgba(109, 40, 217, 0.05), rgba(37, 99, 235, 0.05));
}
.callout h3 {
  margin-top: 0;
  font-size: 1.02rem;
}
.callout p {
  margin-top: 8px;
}
/* Marks a figure the owner still has to source. Loud on purpose. */
.needs-source {
  padding: 2px 8px;
  border-radius: 4px;
  background: #fef3c7;
  color: #92400e;
  font-size: 0.85em;
  font-weight: 700;
}
.article-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-top: 40px;
  padding: 26px;
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--white);
}
.article-cta p {
  flex: 1 1 16rem;
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.08rem;
  /* Must beat `.prose p`, which is ink-coloured and vanishes on this ink box. */
  color: var(--white);
}
.related-guides {
  display: grid;
  gap: 14px;
  margin-top: 22px;
}
.related-guides a {
  display: block;
  padding: 18px 20px;
  border-radius: var(--radius);
  border: 1px solid var(--ink-08);
  background: var(--white);
  font-family: var(--font-heading);
  font-weight: 700;
  transition:
    border-color 0.2s,
    transform 0.2s var(--ease);
}
.related-guides a:hover {
  border-color: rgba(109, 40, 217, 0.4);
  transform: translateY(-2px);
  color: var(--purple);
}
.related-guides span {
  display: block;
  margin-top: 4px;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.88rem;
  color: var(--ink-45);
}

/* ---------- Cookie banner ---------- */
/* Sits above the sticky mobile CTA (30) but below the modals, so a visitor
   can still reach the emergency form while deciding. */
.cookie-banner {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 45;
  padding: 16px 20px calc(16px + env(safe-area-inset-bottom));
  background: var(--white);
  border-top: 1px solid var(--ink-08);
  box-shadow: 0 -6px 24px rgba(18, 16, 31, 0.12);
}
.cookie-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px 24px;
  max-width: var(--shell);
  margin-inline: auto;
}
.cookie-inner p {
  flex: 1 1 22rem;
  margin: 0;
  font-size: 0.88rem;
  color: var(--ink-70);
}
.cookie-inner a {
  color: var(--purple);
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* Both choices are the same size and sit together — rejecting must be no
   harder than accepting, so the two buttons are matched deliberately rather
   than left to fall out of their differing padding and border widths. */
.cookie-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.cookie-actions .btn-outline,
.cookie-actions .btn-primary {
  min-height: 44px;
  white-space: nowrap;
}
/* While the banner is up, lift the sticky bar clear of it on phones. */
.cookie-open .sticky-cta {
  bottom: 100%;
}
/* A button that reads as a link — used for "Cookie settings", which must be
   a button because it opens a dialog rather than navigating. */
.link-button {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.link-button:hover {
  color: var(--white);
}

/* ---------- Page loader ---------- */
/* The overlay is HIDDEN by default and only shown while <html> carries
   .js-loading, which a tiny inline script in <head> adds. That inversion is
   deliberate: with JavaScript disabled the class is never added, so the
   loader stays out of the way instead of leaving a blank ink screen. The
   same inline script clears the class on a timer, so even a crash inside
   main.js cannot strand it. */
.page-loader {
  position: fixed;
  inset: 0;
  z-index: 100; /* above the lightbox (60) and the fast-track modal (50) */
  display: grid;
  place-items: center;
  background: var(--ink);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.5s ease,
    visibility 0s linear 0.5s;
}
.js-loading .page-loader {
  opacity: 1;
  visibility: visible;
  transition: none;
}
/* Scales with the viewport so it stays large on desktop without overflowing
   a phone screen. */
.page-loader img {
  width: min(46vw, 260px);
  height: auto;
  animation: loader-pulse 1.7s ease-in-out infinite;
}
@keyframes loader-pulse {
  0%,
  100% {
    transform: scale(1);
    opacity: 0.82;
  }
  50% {
    transform: scale(1.07);
    opacity: 1;
  }
}

/* ---------- Sticky mobile CTA ---------- */
/* Phone widths only — hidden from 768px up, where the header actions are
   already visible. Sits below the modals so it can never cover them. */
.sticky-cta {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 30;
  display: flex;
  gap: 10px;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  background: rgba(18, 16, 31, 0.92);
  backdrop-filter: blur(12px);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.sticky-cta > * {
  flex: 1;
  justify-content: center;
}
/* Keep the last of the footer clear of the bar. */
body {
  padding-bottom: 68px;
}

/* ---------- Lightbox ---------- */
/* Sits above the fast-track modal's z-index so the two can never fight. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 20px;
}
.lightbox[hidden] {
  display: none;
}
.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(18, 16, 31, 0.85);
  backdrop-filter: blur(6px);
  animation: fade 0.25s;
}
.lightbox-panel {
  position: relative;
  display: grid;
  justify-items: center;
  animation: pop-modal 0.3s var(--ease);
}
.lightbox-panel img {
  display: block;
  /* Fit the viewport whichever way the window is shaped, leaving room for
     the caption underneath. */
  max-width: min(100%, 76rem);
  max-height: calc(100vh - 132px);
  width: auto;
  height: auto;
  border-radius: var(--radius);
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.5);
}
.lightbox-caption {
  margin-top: 14px;
  max-width: 44rem;
  text-align: center;
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.65);
}
.lightbox-close,
.lightbox-nav {
  position: absolute;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  background: rgba(18, 16, 31, 0.6);
  color: rgba(255, 255, 255, 0.75);
  cursor: pointer;
  transition:
    color 0.2s,
    background 0.2s,
    border-color 0.2s;
}
.lightbox-close:hover,
.lightbox-nav:hover {
  background: rgba(109, 40, 217, 0.7);
  border-color: rgba(167, 139, 250, 0.7);
  color: var(--white);
}
.lightbox-close {
  top: -6px;
  right: -6px;
  width: 40px;
  height: 40px;
}
.lightbox-close svg {
  width: 19px;
  height: 19px;
}
.lightbox-nav {
  top: calc(50% - 46px);
  width: 44px;
  height: 44px;
}
.lightbox-nav.prev {
  left: -8px;
}
.lightbox-nav.next {
  right: -8px;
}
.lightbox-nav svg {
  width: 22px;
  height: 22px;
}
@media (min-width: 768px) {
  .lightbox {
    padding: 40px 68px;
  }
  .lightbox-close {
    top: -14px;
    right: -14px;
  }
  .lightbox-nav.prev {
    left: -56px;
  }
  .lightbox-nav.next {
    right: -56px;
  }
}
.modal-sub {
  margin-top: 6px;
  font-size: 0.98rem;
  color: var(--ink-60);
}
#fastTrackForm {
  display: grid;
  gap: 12px;
  margin-top: 20px;
}
.modal-done {
  text-align: center;
  padding-block: 20px;
}
.modal-done .done-icon {
  width: 48px;
  height: 48px;
  margin-inline: auto;
  color: var(--purple);
  animation: pop 0.45s var(--ease);
}
.modal-done h3 {
  margin-top: 16px;
}
.modal-done p {
  margin-top: 8px;
  color: var(--ink-60);
}

/* ---------- Footer ---------- */
.site-footer {
  position: relative;
  overflow: hidden;
  padding-block: 56px;
  background: var(--ink);
  color: var(--white);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.site-footer > .container {
  position: relative;
}
/* Sits with the copyright line. On narrow screens it drops to its own line
   rather than trailing off the end of it, so the separator only appears at
   widths where the two genuinely sit side by side. */
.footer-partner {
  display: block;
  margin-top: 6px;
}
.footer-partner a {
  color: rgba(255, 255, 255, 0.65);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.footer-partner a:hover {
  color: var(--white);
}
.footer-grid {
  display: grid;
  gap: 40px;
}
.footer-blurb {
  margin-top: 16px;
  max-width: 24rem;
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.45);
}
.site-footer h3 {
  margin-bottom: 16px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.35);
}
.site-footer li {
  margin-bottom: 10px;
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.6);
}
.site-footer nav a:hover {
  color: var(--white);
}
.footer-bottom {
  display: grid;
  gap: 12px;
  margin-top: 48px;
  padding-top: 28px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.35);
}

/* Trust strip closing the footer: accepted payment marks and the encryption
   badge. Each mark sits on its own white chip so the brand colours read
   against the ink footer without needing per-brand background tweaks. */
.footer-trust {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin-top: 24px;
  padding-top: 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.pay-marks {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
/* Scoped under .footer-trust so these beat `.site-footer li`, which would
   otherwise paint every chip in translucent white and hide it. */
.footer-trust .pay-mark {
  display: grid;
  grid-auto-flow: column;
  place-items: center;
  gap: 3px;
  min-width: 56px;
  height: 34px;
  margin: 0;
  padding-inline: 10px;
  border-radius: 6px;
  background: var(--white);
  font-family: var(--font-heading);
  font-size: 0.82rem;
  font-weight: 700;
}
.footer-trust .pay-visa {
  color: #1434cb;
  font-style: italic;
  letter-spacing: 0.06em;
}
.footer-trust .pay-amex {
  color: #006fcf;
}
.footer-trust .pay-stripe {
  color: #635bff;
}
.footer-trust .pay-apple {
  color: #000;
}
.footer-trust .pay-apple svg {
  width: 15px;
  height: 15px;
}
.pay-mc {
  width: 40px;
  height: 22px;
  stroke: none;
}
.ssl-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.55);
}
.ssl-badge svg {
  width: 16px;
  height: 16px;
  stroke-width: 1.8;
  color: var(--sky);
}
.footer-bottom div {
  display: flex;
  gap: 20px;
}
.footer-bottom a:hover {
  color: rgba(255, 255, 255, 0.7);
}

/* ---------- Scroll reveal ---------- */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity 0.65s var(--ease),
    transform 0.65s var(--ease);
}
.reveal.visible {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   Responsive — mobile first, so these widen the layout on bigger screens
   ========================================================================== */
@media (min-width: 640px) {
  .container {
    padding-inline: 24px;
  }
  .cards-3 {
    grid-template-columns: repeat(3, 1fr);
  }
  .cards-4 {
    grid-template-columns: repeat(2, 1fr);
  }
  .stats {
    grid-template-columns: repeat(3, 1fr);
  }
  .field-row {
    grid-template-columns: 1fr 1fr;
  }
  .check-grid {
    grid-template-columns: 1fr 1fr;
  }
  .footer-bottom {
    grid-template-columns: 1fr auto;
    align-items: center;
  }
  .footer-partner {
    display: inline;
    margin-top: 0;
  }
  .footer-partner::before {
    content: '·';
    margin: 0 10px;
    opacity: 0.5;
  }
  .wizard {
    padding: 30px;
  }
}

@media (min-width: 768px) {
  .section {
    padding-block: 104px;
  }
  .nav-desktop,
  .header-actions {
    display: flex;
  }
  .menu-toggle,
  .mobile-menu,
  .sticky-cta {
    display: none !important;
  }
  body {
    padding-bottom: 0;
  }
  .usp-list {
    grid-template-columns: repeat(4, 1fr);
  }
  .cards-2 {
    grid-template-columns: 1fr 1fr;
  }
  .shot-grid {
    grid-template-columns: repeat(3, 1fr);
  }
  .related-guides {
    grid-template-columns: 1fr 1fr;
  }
  .article-hero {
    padding-block: 140px 68px;
  }
  .footer-grid {
    grid-template-columns: 1.5fr 1fr 1.2fr 1fr;
  }
}

@media (min-width: 1024px) {
  .hero {
    padding-block: 150px 104px;
  }
  .hero-grid {
    grid-template-columns: 1.05fr 0.95fr;
    gap: 54px;
  }
  .cards-4 {
    grid-template-columns: repeat(4, 1fr);
  }
  .pricing-grid {
    grid-template-columns: repeat(2, 1fr);
    max-width: 820px;
    margin-inline: auto;
  }
  .split {
    grid-template-columns: 1fr 1fr;
    gap: 60px;
  }
  .order-last-desktop {
    order: -1;
  }
  /* Roomier bar on desktop: the padding sits above the centred row, so the
     wordmark clears the top of the viewport rather than hugging it. */
  .header-inner {
    height: 88px;
    padding-top: 14px;
  }
  .site-header .logo-img-top {
    height: 46px;
  }
}

/* Respect people who ask for less motion */
@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;
  }
  .reveal {
    opacity: 1;
    transform: none;
  }
}
