/* Type scale. The root stays FIXED at 16px: an earlier fluid-root scheme
   used per-band formulas that only met 16px at each band's top edge, so
   the whole rem-based interface sawtoothed at breakpoints (19.7px root at
   480px viewport, 10.0px at 481px). Fluidity belongs on display elements
   via clamp(), never on the document root. */
html {
  font-size: 16px;
}

/* ---- GUTENBERG RHYTHM: the vertical unit -------------------------------
   Every vertical gap on a landing surface is a multiple of one baseline, so
   the page advances on a single grid instead of two competing scales. This
   replaces the Fibonacci px ladder (13/21/34/55/89) that used to set spacing.

   Declared on :root, not .marketing-page: ccw_root.html.heex loads this file
   unconditionally and root.html.heex opts in via :landing_styles, so a rule
   here can match an element with no .marketing-page ancestor. An unresolved
   var() in `padding` is invalid at computed-value time and collapses to 0 —
   at :root every consumer resolves. --gb-baseline is overridden below on the
   same element, so the --sp-* calcs re-resolve against it at each width. */
:root {
  --gb-baseline: 1.625rem; /* 26px */
  --sp-1: calc(var(--gb-baseline) * 0.5); /* 13   / 15.5 */
  --sp-2: calc(var(--gb-baseline) * 1); /* 26   / 31   */
  --sp-3: calc(var(--gb-baseline) * 1.5); /* 39   / 46.5 */
  --sp-4: calc(var(--gb-baseline) * 2); /* 52   / 62   */
  --sp-5: calc(var(--gb-baseline) * 3); /* 78   / 93   */
}

@media (width >= 64rem) {
  :root {
    --gb-baseline: 1.9375rem; /* 31px */
  }
}

* {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Display type: Instrument Sans at weight 500 with tight tracking —
   single family across display and body. */
.landing-heading {
  font-family: "Instrument Sans", var(--font-sans), ui-sans-serif, system-ui, sans-serif;
  font-weight: 500;
  letter-spacing: -0.02em;
}

/* Continuous: 36px at 390px viewport -> 60px at 1280px, floor 34px.
   Anchored to the validated mobile and desktop sizes; every width in
   between interpolates with no jumps. This is the ONLY font-size rule
   for the hero title — don't add stepped overrides below. */
.landing-hero-title {
  font-size: clamp(2.125rem, 1.593rem + 2.697vw, 3.75rem);
  line-height: 1.04;
  letter-spacing: -0.025em;
  /* Even line lengths when a segment wraps; markup keeps "firearm log"
     unbreakable so older browsers never orphan a word. */
  text-wrap: balance;
}

/* Phones: sized so each headline segment holds ONE line (two lines
   total, like the reference composition). 7.7vw fits "The private
   firearm log" at 390 (30px) down to 320 (24.6px); the 2rem cap stops
   growth before the >=40rem clamp takes over. */
@media (width < 40rem) {
  .landing-hero-title {
    font-size: clamp(1.45rem, 7.7vw, 2rem);
    line-height: 1.12;
  }
}

/* Quiet supporting voice: regular weight, a step smaller than the old
   lead, and dimmer than body copy so the headline and CTA carry. */
.landing-hero-lead {
  font-size: 1.0625rem;
  line-height: 1.6;
  font-weight: 400;
}

@media (width >= 64rem) {
  .landing-hero-lead {
    font-size: 1.125rem;
    line-height: 1.6;
  }
}

.landing-section-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.landing-section-title {
  margin-top: 0.75rem;
  font-size: clamp(2rem, 3.55vw, 2.75rem);
  line-height: 1.12;
}

.landing-section-lead {
  margin-top: 1rem;
  font-size: 0.95rem;
  line-height: 1.6;
}

@media (width >= 64rem) {
  .landing-section-lead {
    margin-top: 1.25rem;
  }
}

.landing-body-copy {
  line-height: 1.6;
}

/* LS-style spacing scale (rem-based, follows fluid root) */
.landing-mt-xs { margin-top: 0.5rem; }
.landing-mt-sm { margin-top: 1rem; }
.landing-mt-md { margin-top: 1.75rem; }
.landing-mt-lg { margin-top: 2.5rem; }
.landing-mt-xl { margin-top: 4rem; }

.landing-page-pad {
  padding-inline: var(--landing-px);
}

/* Mobile nav drawer — LS: logo + CTA + menu, no second pill row */
.landing-nav-menu summary {
  list-style: none;
  cursor: pointer;
}
.landing-nav-menu summary::-webkit-details-marker {
  display: none;
}
.landing-nav-menu[open] summary {
  color: var(--color-blueprint-text);
  border-color: color-mix(in srgb, var(--color-blueprint-accent) 45%, transparent);
}
/* Hero depth: a faint grid + soft brand glow behind the content, masked so
   it's strongest toward the top and fades to clean black before the CTA.
   Purely decorative; content sits at z-10 above it. */
.landing-hero-grid {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(ellipse 68% 52% at 12% 4%, color-mix(in srgb, var(--color-blueprint-accent) 14%, transparent), transparent 55%),
    linear-gradient(to right, rgb(255 255 255 / 0.028) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 255 255 / 0.028) 1px, transparent 1px);
  background-size: 100% 100%, 58px 58px, 58px 58px;
  -webkit-mask-image: radial-gradient(128% 92% at 50% -6%, #000 30%, transparent 74%);
  mask-image: radial-gradient(128% 92% at 50% -6%, #000 30%, transparent 74%);
}

/* Legal pages (terms, privacy): long-form prose, and the surface Gutenberg is
   actually designed for. Sizes come off the shared ladder, and every vertical
   gap is a whole multiple of --gb-baseline so the text holds its rhythm down
   the page. Gutenberg's own heading margins (h1 4 units above / 1 below, h2
   2.5 / 0.5) are used as-is here, because this IS flowing article copy.
   Element selectors stay scoped under .legal-prose so nothing leaks. */
/* Each block's line-height AND its margins are baseline units, and each pair
   sums to a whole number of units, so a one-line heading advances the grid by
   exactly 3 or 5 baselines and the column below it stays aligned. Line-height
   must be set explicitly on anything not at the body size: the inherited value
   is a unitless ratio, so a 14.4px caption would re-resolve it to 24.8px and
   drop half a baseline. */
.legal-prose h1 {
  font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: var(--fs-page-title);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--color-blueprint-text);
  line-height: calc(var(--gb-baseline) * 2);
  margin-bottom: var(--gb-baseline); /* 2 + 1 = 3 units */
}
.legal-prose .last-updated {
  color: var(--color-blueprint-muted);
  font-size: var(--fs-caption);
  line-height: var(--gb-baseline);
  margin-bottom: calc(var(--gb-baseline) * 2); /* 1 + 2 = 3 units */
}
.legal-prose .intro {
  font-size: var(--fs-lead);
  color: var(--color-blueprint-muted);
  border-left: 2px solid var(--color-blueprint-accent);
  padding-left: 1.25rem;
  line-height: var(--gb-baseline);
  margin-bottom: calc(var(--gb-baseline) * 2); /* 1 + 2 = 3 units */
}
.legal-prose h2 {
  font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: var(--fs-title);
  font-weight: 600;
  color: var(--color-brand-700);
  letter-spacing: -0.01em;
  line-height: calc(var(--gb-baseline) * 1.5);
  margin-top: calc(var(--gb-baseline) * 2.5);
  margin-bottom: var(--gb-baseline); /* 2.5 + 1.5 + 1 = 5 units */
}
.legal-prose h3 {
  font-size: var(--fs-lead);
  font-weight: 600;
  color: var(--color-blueprint-text);
  line-height: var(--gb-baseline);
  margin-top: calc(var(--gb-baseline) * 1.5);
  margin-bottom: calc(var(--gb-baseline) * 0.5); /* 1.5 + 1 + 0.5 = 3 units */
}
.legal-prose p {
  margin-bottom: var(--gb-baseline);
  color: var(--color-blueprint-muted);
  line-height: var(--gb-baseline);
}
.legal-prose ul,
.legal-prose ol {
  margin-bottom: var(--gb-baseline);
  padding-left: 1.5rem;
}
.legal-prose ul {
  list-style: disc;
}
.legal-prose ol {
  list-style: decimal;
}
/* A full unit between items, never a fraction: with wrapped items the gap
   between two entries has to beat the gap between a single entry's own lines,
   or the list reads as one block — and a fractional gap is exactly what knocks
   a long list off the grid. */
.legal-prose li + li {
  margin-top: var(--gb-baseline);
}
.legal-prose li {
  margin-bottom: 0;
  color: var(--color-blueprint-muted);
  line-height: var(--gb-baseline);
}
.legal-prose a {
  color: var(--color-brand-700);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: color-mix(in srgb, var(--color-blueprint-accent) 50%, transparent);
}
.legal-prose a:hover {
  color: var(--color-brand-800);
}
.legal-prose strong {
  color: var(--color-blueprint-text);
  font-weight: 600;
}
.legal-prose .warning-box {
  background-color: var(--color-blueprint-warning-tint);
  border: 1px solid var(--color-blueprint-warning-border);
  border-radius: 0;
  padding: 1.25rem 1.5rem;
  margin: 1.5rem 0;
}
.legal-prose .warning-box p {
  margin-bottom: 0.5rem;
  color: var(--color-blueprint-text);
  font-weight: 500;
}
.legal-prose .warning-box p:first-child {
  color: color-mix(in srgb, var(--color-blueprint-warning) 72%, white);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}
.legal-prose .warning-box p:last-child {
  margin-bottom: 0;
}

.legal-table-scroll {
  max-width: 100%;
  margin: 1.5rem 0;
  overflow-x: auto;
  border: 1px solid var(--color-blueprint-border);
  background: var(--color-blueprint-panel);
  scrollbar-gutter: stable;
}

.legal-table-scroll:focus-visible {
  outline: 2px solid var(--color-blueprint-accent);
  outline-offset: 2px;
}

.legal-prose table {
  width: 100%;
  min-width: 40rem;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.legal-prose th,
.legal-prose td {
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--color-blueprint-divider);
  color: var(--color-blueprint-muted);
  line-height: 1.5;
  text-align: left;
  vertical-align: top;
}

.legal-prose th {
  color: var(--color-blueprint-text);
  background: var(--color-blueprint-overlay);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.legal-prose tr:last-child td {
  border-bottom: 0;
}

/* Same treatment tuned for the short, wide secondary-page hero (explore,
   pricing): the grid reads across the band and fades downward, rather than
   the tall home mask which fades within ~100px here. */
.landing-page-hero-grid {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(ellipse 52% 130% at 10% -20%, color-mix(in srgb, var(--color-blueprint-accent) 13%, transparent), transparent 62%),
    linear-gradient(to right, rgb(255 255 255 / 0.028) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 255 255 / 0.028) 1px, transparent 1px);
  background-size: 100% 100%, 58px 58px, 58px 58px;
  -webkit-mask-image: linear-gradient(to bottom, #000 42%, transparent 92%);
  mask-image: linear-gradient(to bottom, #000 42%, transparent 92%);
}

.landing-hero-media {
  position: relative;
  flex: 0 0 auto;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem 1rem var(--sp-2);
}
@media (width >= 40rem) {
  .landing-hero-media {
    padding: 2.25rem 2rem 2.75rem;
  }
}
@media (width >= 64rem) {
  .landing-hero-media {
    flex: 0 0 46%;
    max-width: 46%;
    /* Leave 5rem of the next band visible at common desktop heights so the
       hero cannot read as a complete, self-contained page. */
    min-height: calc(100svh - 8.75rem);
    align-self: stretch;
    justify-content: flex-end;
    overflow: visible;
    padding: 3rem 0;
  }
}

.hero-device-stage {
  position: relative;
  width: 100%;
  max-width: 30rem;
  perspective: 2000px;
}

@media (width >= 64rem) {
  .hero-device-stage {
    width: min(44rem, 50vw);
    max-width: none;
  }
}

.hero-device-stage::before {
  content: "";
  position: absolute;
  inset: -10% -8% -14%;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(
    58% 54% at 58% 40%,
    color-mix(in srgb, var(--color-blueprint-accent-deep) 22%, transparent),
    transparent 70%
  );
  filter: blur(22px);
}

.hero-tablet {
  position: relative;
  z-index: 1;
  margin: 0;
  padding: clamp(8px, 1.05vw, 14px);
  border-radius: clamp(18px, 2.4vw, 30px);
  background: linear-gradient(
    152deg,
    var(--color-brand-400) 0%,
    var(--color-blueprint-overlay) 34%,
    var(--color-blueprint-ground) 68%,
    var(--color-brand-300) 100%
  );
  box-shadow:
    inset 0 0 0 1px rgb(255 255 255 / 0.11),
    inset 0 0 0 2px rgb(0 0 0 / 0.55),
    0 24px 44px -16px rgb(0 0 0 / 0.6),
    0 54px 80px -42px rgb(0 0 0 / 0.72);
  transform: rotateY(-9deg) rotateX(2.5deg) rotate(0.4deg);
  transform-origin: 62% 50%;
}

.hero-tablet-screen {
  position: relative;
  overflow: hidden;
  padding: clamp(5px, 0.6vw, 8px);
  border-radius: clamp(11px, 1.55vw, 19px);
  aspect-ratio: 2000 / 1140;
  background: var(--color-blueprint-ground);
  box-shadow:
    inset 0 0 0 1px rgb(0 0 0 / 0.92),
    inset 0 0 0 1.5px rgb(255 255 255 / 0.04);
}

.hero-tablet-shot {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: top center;
  filter: brightness(1.16) contrast(1.03);
}

.hero-tablet-glare {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  background:
    linear-gradient(
      105deg,
      rgb(255 255 255 / 0.13) 0%,
      rgb(255 255 255 / 0.04) 9%,
      transparent 24%
    ),
    radial-gradient(130% 62% at 82% -12%, rgb(255 255 255 / 0.07), transparent 60%);
}

.hero-tablet-screen-edge {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  box-shadow:
    inset 0 1px 1px rgb(255 255 255 / 0.06),
    inset 0 -12px 26px rgb(0 0 0 / 0.16);
}

.hero-tablet-cam {
  position: absolute;
  top: clamp(3px, 0.45vw, 6px);
  left: 50%;
  width: clamp(4px, 0.45vw, 6px);
  height: clamp(4px, 0.45vw, 6px);
  border-radius: 50%;
  background: radial-gradient(
    circle at 35% 35%,
    var(--color-blueprint-sidebar),
    var(--color-blueprint-ground) 72%
  );
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.6), inset 0 0 1px rgb(120 170 200 / 0.55);
  transform: translateX(-50%);
}

@media (width < 64rem) {
  .hero-device-stage {
    perspective: none;
  }

  .hero-tablet {
    transform: none;
  }
}

/* Mobile: stack copy and dashboard without viewport-height centering gaps. */
@media (width < 64rem) {
  .landing-hero-section {
    min-height: 0;
  }

  .landing-hero-copy-panel {
    flex: 0 0 auto;
    justify-content: flex-start;
    /* Keep enough separation from the fixed nav while letting the next band
       enter the first viewport. The previous 8vh top pad plus a duplicate
       proof list made the hero read as a false bottom on phones. */
    padding-top: var(--sp-3);
    padding-bottom: var(--sp-1);
  }

  .landing-hero-title {
    line-height: 1.08;
  }
}

/* Pricing toggle — CSS-only with checkbox hack */
#pricing-toggle:checked ~ .pricing-grid .price-annual { visibility: hidden; }
#pricing-toggle:checked ~ .pricing-grid .price-monthly { visibility: visible; }
#pricing-toggle:not(:checked) ~ .pricing-grid .price-annual { visibility: visible; }
#pricing-toggle:not(:checked) ~ .pricing-grid .price-monthly { visibility: hidden; }
#pricing-toggle:checked ~ .pricing-grid .plan-cta-annual { display: none; }
#pricing-toggle:checked ~ .pricing-grid .plan-cta-monthly { display: block; }
#pricing-toggle:not(:checked) ~ .pricing-grid .plan-cta-annual { display: block; }
#pricing-toggle:not(:checked) ~ .pricing-grid .plan-cta-monthly { display: none; }

#pricing-toggle:checked ~ .toggle-row .toggle-track .toggle-knob { transform: translateX(24px); }
#pricing-toggle:checked ~ .toggle-row .toggle-label-annual { color: var(--color-blueprint-faint); }
#pricing-toggle:checked ~ .toggle-row .toggle-label-monthly { color: var(--color-blueprint-text); }
#pricing-toggle:not(:checked) ~ .toggle-row .toggle-label-annual { color: var(--color-blueprint-text); }
#pricing-toggle:not(:checked) ~ .toggle-row .toggle-label-monthly { color: var(--color-blueprint-faint); }

/* Period words are controls, not decoration. The selected word is inert so
   clicking "Annual" while annual is already selected cannot switch away from
   the value the user explicitly chose. */
#pricing-toggle:not(:checked) ~ .toggle-row .toggle-label-annual,
#pricing-toggle:checked ~ .toggle-row .toggle-label-monthly {
  cursor: default;
  pointer-events: none;
}

.toggle-knob { transition: transform 150ms ease; }

details summary { list-style: none; }
details summary::-webkit-details-marker { display: none; }
details summary::marker { display: none; }
details[open] .faq-chevron { transform: rotate(180deg); }

a:focus-visible,
button:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--color-blueprint-accent);
  outline-offset: 2px;
}

/* The focusable control is the sr-only checkbox; show its keyboard focus ring
   on the visible track (the label itself is not focusable). */
#pricing-toggle:focus-visible ~ .toggle-row .toggle-track {
  box-shadow: 0 0 0 3px var(--color-blueprint-accent);
}

/*
  Primary button — Lemon Squeezy interaction:
  shadow layer on .landing-btn-primary, face on .landing-btn-overlay;
  hover lifts overlay (-0.5rem) and slides icon (+0.5rem).
*/
.landing-btn-wrap {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
}

.landing-btn-primary {
  display: inline-block;
  border-radius: 10px;
  text-decoration: none;
  color: var(--color-blueprint-ground);
  background-color: var(--color-brand-300);
  padding: 0;
  transition: background-color 150ms ease;
}

.landing-btn-primary:focus-visible {
  outline: 2px solid var(--color-blueprint-accent);
  outline-offset: 3px;
}

/* Solid brand button (quiet rectangle, not a pill); the slide-reveal
   base underneath is a darker steel edge. */
.landing-btn-overlay {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  padding: 0.875rem 1.375rem;
  border-radius: 10px;
  background: var(--color-blueprint-accent);
  font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 550;
  font-size: 1rem;
  line-height: 1;
  transition: transform 150ms ease, background-color 150ms ease;
}

.landing-btn-icon {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  pointer-events: none;
  transition: transform 150ms ease;
}

.landing-btn-wrap.is-brand:hover .landing-btn-primary {
  background-color: var(--color-brand-400);
}

.landing-btn-wrap.is-brand:hover .landing-btn-overlay {
  transform: translate(-0.5rem, -0.5rem);
  background: var(--color-brand-700);
}

.landing-btn-wrap:hover .landing-btn-icon {
  transform: translate(0.5rem, 0);
}

.landing-btn-primary.landing-btn-sm .landing-btn-overlay {
  padding: 0.5625rem 1.125rem;
  font-size: 0.8125rem;
  gap: 0.5rem;
}

.landing-btn-wrap.is-brand:hover .landing-btn-primary.landing-btn-sm .landing-btn-overlay {
  transform: translate(-0.35rem, -0.35rem);
}

.landing-btn-primary.landing-btn-block {
  display: block;
  width: 100%;
}

/* Nav CTA on narrow phones: drop the arrow so the wordmark, 44px menu
   target, and button all clear a 320px viewport. */
@media (width < 40rem) {
  .landing-nav-cta .landing-btn-icon {
    display: none;
  }
  .landing-nav-cta .landing-btn-overlay {
    gap: 0;
  }
}

.landing-btn-primary.landing-btn-block .landing-btn-overlay {
  width: 100%;
}

.landing-btn-wrap-block {
  width: 100%;
}

.landing-cta-outline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 600;
  line-height: 1.25;
  text-decoration: none;
  white-space: nowrap;
  border-radius: 9999px;
  background: transparent;
  color: var(--color-blueprint-text);
  border: 1px solid rgb(255 255 255 / 0.22);
  transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}
.landing-cta-outline:hover {
  border-color: rgb(255 255 255 / 0.38);
  background: rgb(255 255 255 / 0.05);
}

.landing-cta-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
}

.landing-footer-cta {
  border-bottom: 1px solid rgb(255 255 255 / 0.06);
  background: linear-gradient(
    118deg,
    color-mix(in srgb, var(--color-blueprint-accent) 16%, transparent) 0%,
    color-mix(in srgb, var(--color-blueprint-accent-deep) 8%, transparent) 38%,
    var(--color-blueprint-ground) 72%
  );
}

.landing-footer-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-blueprint-muted);
  margin-bottom: 1rem;
}

.landing-footer-links {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.landing-footer-link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-blueprint-muted);
  text-decoration: none;
  transition: color 0.15s ease;
}

.landing-footer-link:hover {
  color: var(--color-blueprint-text);
}

.landing-footer-link-icon {
  opacity: 0;
  transform: translateX(-0.15rem);
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.landing-footer-link:hover .landing-footer-link-icon {
  opacity: 1;
  transform: translateX(0);
}

.landing-cta-text {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--color-blueprint-muted);
  text-decoration: none;
  transition: color 0.15s ease;
}
.landing-cta-text:hover {
  color: var(--color-blueprint-text);
}
.landing-cta-text .cta-arrow {
  display: inline-block;
  transition: transform 150ms ease;
}
.landing-cta-text:hover .cta-arrow {
  transform: translateX(3px);
}

/* No vertical padding: min-height plus the inline-flex centering sets the
   height, exactly as the primary button does it, so the two CTA styles match
   in a card. A control's internal padding is NOT page rhythm — putting the
   baseline token here grew this button to 51px against the primary's 44px and
   knocked the bottom-pinned CTAs out of line with each other. */
.landing-cta-card {
  width: 100%;
  font-size: 0.875rem;
  padding: 0 1.25rem;
  min-height: 2.875rem;
}

.landing-cta-inline {
  font-size: 0.8125rem;
  padding: 0.5625rem 1rem;
  min-height: 2.375rem;
}

.landing-cta-note {
  font-size: 0.8125rem;
  color: var(--color-blueprint-muted);
}

/* Shared horizontal grid — nav logo and hero copy share the same left edge */
:root {
  --landing-max-w: 72rem;
  /* The public templates historically mixed px-4 (16px) with a 20px shell.
     One 16px mobile rail prevents nav, copy, cards, and media from drifting
     four pixels every time a page switches between the two container APIs. */
  --landing-px: 1rem;
}
/* Widen the content column on large monitors so the page fills the screen
   instead of a fixed 72rem column marooned in the margins. Copy blocks keep
   their own inner max-widths, so line length stays readable; this mainly gives
   the hero split, nav, and section grids more room. */
@media (width >= 96rem) {
  :root {
    --landing-max-w: 80rem;
  }
}
@media (width >= 120rem) {
  :root {
    --landing-max-w: 88rem;
  }
}
@media (width >= 160rem) {
  :root {
    --landing-max-w: 96rem;
  }
}
/* Section containers share the same responsive column so the nav, hero, and
   every section align to one edge on large screens. `max-w-6xl` is a
   landing-only utility; scope to .marketing-page and match --landing-max-w
   (identical to 72rem below the first breakpoint, so laptops are unchanged). */
.marketing-page .max-w-6xl {
  max-width: var(--landing-max-w);
}
@media (width >= 40rem) {
  :root {
    --landing-px: 1.5rem;
  }
}
@media (width >= 64rem) {
  :root {
    --landing-px: 2rem;
  }
}

.landing-shell {
  box-sizing: border-box;
  width: 100%;
  max-width: var(--landing-max-w);
  margin-inline: auto;
  padding-inline: var(--landing-px);
}

.landing-page-gutter {
  padding-left: max(var(--landing-px), calc((100vw - var(--landing-max-w)) / 2 + var(--landing-px)));
}

.landing-hero-layout {
  display: flex;
  flex-direction: column;
}

@media (width >= 64rem) {
  .landing-hero-layout {
    flex-direction: row;
    align-items: center;
  }
}

.landing-hero-copy-panel {
  flex: 1 1 auto;
}
@media (width >= 64rem) {
  .landing-hero-copy-panel {
    /* The shell around this pair now supplies both page gutters (same as the
       explore hero), so these columns just split the rail between them and
       the device is no longer paying for the right gutter out of its own
       width — which is what shrank it to 373px. */
    flex: 0 0 54%;
    max-width: 54%;
    padding-inline: 0 2rem;
  }
}

/* Split hero: copy left, video right — no full-bleed scrim */
.landing-hero-copy .landing-heading,
.landing-hero-copy > p {
  text-shadow: none;
}

/* Horizontal card strips — swipe on small screens, grid on lg+ */
.landing-mobile-hscroll {
  -webkit-overflow-scrolling: touch;
  scroll-padding-inline: 1.25rem;
  scrollbar-width: thin;
}

/* Scrollbar-free horizontal rail (jump-nav pills on phones). */
.landing-hscroll {
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.landing-hscroll::-webkit-scrollbar {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .toggle-knob {
    transition: none;
  }
  .landing-btn-wrap.is-brand:hover .landing-btn-overlay {
    transform: none;
    background: var(--color-blueprint-text);
  }
  .landing-btn-wrap.is-brand:hover .landing-btn-primary {
    background-color: var(--color-blueprint-accent-deep);
  }
  .landing-btn-wrap:hover .landing-btn-icon,
  .landing-cta-text:hover .cta-arrow {
    transform: none;
  }
}

/* Fixed chrome — single nav bar (LS pattern) */
:root {
  --landing-chrome-top: calc(3.75rem + 0.75rem);
}

/*
  scroll-margin aligns hashed section tops with sticky chrome (pill bar + navbar + air).
  (scroll-padding-top on html is omitted — combined with scroll-margin it can double the offset.)
*/
.landing-anchor-target {
  scroll-margin-top: var(--landing-chrome-top);
}

/* Short vertical viewports — tighten copy rhythm. Desktop-width ONLY:
   this targets 13" laptops, landscape tablets, and split-screen windows.
   Phones in portrait also have effective heights under 46rem once the
   browser chrome is counted, and these !important rules were crushing
   the mobile hero's breathing room.
   The heading lives inside a wrapper div, not as a direct child of the
   density container, so these use the heading's SIBLINGS (lead p, CTA
   stack, trust list) rather than child combinators that never matched. */
@media (max-height: 46rem) and (min-width: 64rem) {
  .landing-hero-copy.landing-hero-density .landing-heading {
    margin-top: clamp(0.75rem, 2vh, 1.5rem) !important;
  }
  .landing-hero-copy.landing-hero-density .landing-heading ~ p,
  .landing-hero-copy.landing-hero-density .landing-heading ~ div,
  .landing-hero-copy.landing-hero-density .landing-heading ~ ul {
    margin-top: clamp(0.5rem, 1.5vh, 1rem) !important;
  }
}

/* ── Pricing page: comparison matrix ── */
.pricing-mobile-compare {
  min-width: 0;
  border: 1px solid rgb(255 255 255 / 0.12);
  background: var(--color-blueprint-panel);
}

.pricing-mobile-plan-picker {
  position: sticky;
  top: 3.75rem;
  z-index: 8;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding: 0.3125rem;
  border-bottom: 1px solid rgb(255 255 255 / 0.12);
  background: var(--color-blueprint-overlay);
  box-shadow: 0 0.8125rem 1.3125rem -1.3125rem rgb(0 0 0 / 0.9);
}

.pricing-mobile-plan-picker label {
  display: inline-flex;
  min-height: 2.75rem;
  align-items: center;
  justify-content: center;
  padding-inline: 0.5rem;
  color: var(--color-blueprint-muted);
  font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  transition:
    color 150ms ease,
    background-color 150ms ease;
}

#pricing-mobile-plan-recon:checked
  ~ .pricing-mobile-plan-picker
  label[data-plan="recon"],
#pricing-mobile-plan-operator:checked
  ~ .pricing-mobile-plan-picker
  label[data-plan="operator"],
#pricing-mobile-plan-arsenal:checked
  ~ .pricing-mobile-plan-picker
  label[data-plan="arsenal"] {
  color: var(--color-blueprint-ground);
  background: var(--color-brand-600);
}

#pricing-mobile-plan-recon:focus-visible
  ~ .pricing-mobile-plan-picker
  label[data-plan="recon"],
#pricing-mobile-plan-operator:focus-visible
  ~ .pricing-mobile-plan-picker
  label[data-plan="operator"],
#pricing-mobile-plan-arsenal:focus-visible
  ~ .pricing-mobile-plan-picker
  label[data-plan="arsenal"] {
  outline: 2px solid var(--color-brand-700);
  outline-offset: -2px;
}

.pricing-mobile-plan-panel {
  display: none;
}

#pricing-mobile-plan-recon:checked
  ~ .pricing-mobile-plan-panels
  [data-plan="recon"],
#pricing-mobile-plan-operator:checked
  ~ .pricing-mobile-plan-panels
  [data-plan="operator"],
#pricing-mobile-plan-arsenal:checked
  ~ .pricing-mobile-plan-panels
  [data-plan="arsenal"] {
  display: block;
}

.pricing-mobile-section-label {
  display: flex;
  min-height: 3.4375rem;
  cursor: pointer;
  list-style: none;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  padding: var(--sp-1) 1rem;
  border-top: 1px solid rgb(255 255 255 / 0.08);
  color: var(--color-blueprint-text);
  background: var(--color-blueprint-tile);
  font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.02em;
}

.pricing-mobile-section-label::-webkit-details-marker {
  display: none;
}

.pricing-mobile-section-label:focus-visible {
  outline: 2px solid var(--color-blueprint-accent);
  outline-offset: -2px;
}

.pricing-mobile-section[open] > .pricing-mobile-section-label {
  color: var(--color-blueprint-accent);
  background: var(--color-blueprint-overlay);
}

.pricing-mobile-plan-panel dl {
  margin: 0;
}

.pricing-mobile-feature-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(5.5rem, auto);
  gap: 1rem;
  align-items: center;
  min-height: 3.4375rem;
  padding: var(--sp-1) 1rem;
  border-bottom: 1px solid rgb(255 255 255 / 0.06);
}

.pricing-mobile-feature-row dt {
  color: var(--color-blueprint-muted);
  font-size: 0.875rem;
  line-height: 1.45;
}

.pricing-mobile-feature-row dd {
  margin: 0;
  color: var(--color-blueprint-muted);
  font-size: 0.8125rem;
  line-height: 1.4;
  text-align: right;
}

.pricing-mobile-feature-row .cell-yes {
  color: var(--color-blueprint-accent);
}

.pricing-mobile-feature-row .cell-no {
  color: var(--color-blueprint-faint);
}

.pricing-compare-wrap {
  --pricing-feature-column-width: 12rem;

  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 1.25rem;
  border: 1px solid rgb(255 255 255 / 0.07);
  background: color-mix(in srgb, var(--color-blueprint-panel) 82%, transparent);
  box-shadow: inset 0 1px 0 0 rgb(255 255 255 / 0.04);
}

/* >=48rem the table fits without horizontal scroll, so the wrap stops
   being a scroll container (position:sticky can't escape one) and the
   plan-name header pins below the fixed 3.75rem nav while the long
   table scrolls. */
@media (width >= 48rem) {
  .pricing-compare-wrap {
    overflow-x: visible;
  }
  .pricing-compare {
    min-width: 0;
  }
}

/* Phones still h-scroll the table; vertical sticky can't work inside
   that scroll container, so the FEATURE column pins left instead to
   keep row context while swiping across plans. */
@media (width < 48rem) {
  .pricing-compare {
    table-layout: fixed;
  }

  .pricing-compare .pricing-compare-feature-column {
    width: var(--pricing-feature-column-width);
  }

  .pricing-compare-plan-column {
    width: 10rem;
  }

  .pricing-compare thead th:first-child {
    position: sticky;
    left: 0;
    z-index: 7;
    background: var(--color-blueprint-overlay);
    box-shadow:
      1px 0 0 rgb(255 255 255 / 0.1),
      0 1px 0 rgb(255 255 255 / 0.1);
  }

  .pricing-compare td.feature-label,
  .pricing-compare .section-row > .pricing-section-label {
    position: sticky;
    left: 0;
    z-index: 4;
    background: var(--color-blueprint-overlay);
    box-shadow: 1px 0 0 rgb(255 255 255 / 0.08);
  }
}

.pricing-compare {
  width: 100%;
  min-width: 42rem;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.pricing-compare-feature-column {
  width: 38%;
}

.pricing-compare th,
.pricing-compare td {
  padding: 0.875rem 1rem;
  text-align: left;
  border-bottom: 1px solid rgb(255 255 255 / 0.06);
  vertical-align: middle;
}

/* Pins below the fixed 3.75rem nav once the wrap stops h-scrolling at
   >=48rem (see the media block above). Opaque bg: rows scroll under. */
.pricing-compare thead th {
  font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 600;
  color: var(--color-blueprint-text);
  background: var(--color-blueprint-overlay);
  position: sticky;
  top: 3.75rem;
  z-index: 5;
  box-shadow: 0 1px 0 0 rgb(255 255 255 / 0.1);
}

/* Inside the mobile horizontal scroller, the desktop nav offset creates an
   empty band above the headers. The frozen Feature header still sticks left;
   only its irrelevant vertical inset is disabled. */
@media (width < 48rem) {
  .pricing-compare thead th {
    top: auto;
  }
}

.pricing-compare tbody tr:last-child td {
  border-bottom: none;
}

.pricing-compare .section-row > * {
  padding-top: 1.25rem;
  padding-bottom: 0.5rem;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-blueprint-accent);
  background: transparent;
  border-bottom: none;
}

.pricing-compare .pricing-section-label {
  text-align: left;
}

.pricing-compare .feature-label {
  color: var(--color-blueprint-muted);
  font-weight: 500;
}

.pricing-compare .cell-yes {
  color: var(--color-blueprint-accent);
}

.pricing-compare .cell-no {
  color: var(--color-blueprint-faint);
}

.pricing-compare .cell-text {
  color: var(--color-blueprint-muted);
  font-size: 0.8125rem;
}

/* Shared page hero for secondary marketing pages (pricing, explore):
   identical top chrome so flipping between pages doesn't jump. */
.landing-page-hero {
  padding-top: calc(3.75rem + 2.5rem);
  padding-bottom: 2.5rem;
}

@media (width >= 64rem) {
  .landing-page-hero {
    padding-top: calc(3.75rem + 4rem);
    padding-bottom: 3.5rem;
  }
}

.pricing-included-strip {
  border-top: 1px solid rgb(255 255 255 / 0.06);
  border-bottom: 1px solid rgb(255 255 255 / 0.06);
  background: color-mix(in srgb, var(--color-blueprint-header) 45%, transparent);
}

.pricing-included-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.pricing-included-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.8125rem;
  color: var(--color-blueprint-muted);
}

.pricing-included-list li i {
  color: var(--color-blueprint-accent);
  font-size: 0.65rem;
  margin-top: 0.25rem;
}

@media (width >= 40rem) {
  .pricing-included-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem 1.25rem;
  }

  .pricing-included-list li {
    align-items: center;
  }

  .pricing-included-list li i {
    margin-top: 0;
  }

  .pricing-included-list li:last-child {
    grid-column: 1 / -1;
  }
}

@media (width >= 64rem) {
  .pricing-included-list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .pricing-included-list li:last-child {
    grid-column: span 2;
  }
}

/* Both billing modes occupy the same grid cell. Keeping the hidden mode in
   layout reserves the taller copy height, so changing period cannot resize a
   card or move everything below it. `visibility` also removes the inactive
   copy from the accessibility tree. */
.pricing-price-switcher {
  display: grid;
}

.pricing-grid .price-annual,
.pricing-grid .price-monthly {
  grid-area: 1 / 1;
  min-height: 4.5rem;
}

@media (width >= 40rem) {
  .pricing-grid .price-annual,
  .pricing-grid .price-monthly {
    min-height: 4.75rem;
  }
}

/* Product screenshots in the showcase rows: same luminance lift as the
   hero tablet shot, for the same reason (dark UI on a dark page). */
.landing-product-shot {
  filter: brightness(1.16) contrast(1.03);
}

/* ============================================================
   PUBLIC SITE — BLUEPRINT PRODUCT LANGUAGE

   The marketing and legal pages retain their existing information
   architecture and copy, but share the authenticated application's steel
   blue palette, square geometry, controls, and focus treatment. Scoping the
   remap to .marketing-page keeps the public surface changes scoped.
   ============================================================ */
.marketing-page {
  --control-radius: 2px;
  /* The steel --color-brand-* ramp is the tokens.css default now
     (2026-07 brand guide); the local override this block carried during
     the green-to-steel migration is gone. */
  --color-neutral-950: var(--color-blueprint-ground);
  --color-neutral-900: var(--color-blueprint-panel);
  --color-neutral-800: var(--color-blueprint-tile);
  --color-neutral-700: var(--color-blueprint-overlay);
  /* Four real steps, each a visible drop. 400 and 500 both used to alias to
     muted and 100/200/300 all to text, so five authored levels rendered as
     two and every "quieter footnote" was the same color as its paragraph. */
  --color-neutral-600: rgb(255 255 255 / 0.42); /*  4.1:1  fine print */
  --color-neutral-500: rgb(255 255 255 / 0.62); /*  7.5:1  secondary */
  --color-neutral-400: rgb(255 255 255 / 0.80); /* 11.8:1  body */
  --color-neutral-300: rgb(255 255 255 / 0.86); /* 13.5:1  strong body */
  --color-neutral-200: var(--color-blueprint-text);
  --color-neutral-100: var(--color-blueprint-text);
  --color-cream: var(--color-blueprint-text);
  --color-cream-dim: var(--color-blueprint-muted);
  --marketing-ground: var(--color-blueprint-ground);
  --marketing-band: var(--color-blueprint-panel);
  --marketing-panel: var(--color-blueprint-panel);
  --marketing-tile: var(--color-blueprint-tile);
  --marketing-overlay: var(--color-blueprint-overlay);
  --marketing-header: var(--color-blueprint-header);
  --marketing-text: var(--color-blueprint-text);
  --marketing-muted: var(--color-blueprint-muted);
  --marketing-accent: var(--color-blueprint-accent);
  --marketing-accent-hover: var(--color-brand-700);
  --marketing-border: var(--color-blueprint-border);
  --marketing-divider: var(--color-blueprint-divider);

  color: var(--marketing-text);
  background: var(--marketing-ground);
  color-scheme: dark;
}

.marketing-page :where(table, .pricing-grid) {
  font-variant-numeric: tabular-nums;
}

.marketing-page :where([class*="rounded-"]) {
  border-radius: 0 !important;
}

.marketing-page :where(a, button, input, select, textarea, summary):focus-visible {
  outline: 2px solid var(--marketing-accent) !important;
  outline-offset: 2px;
}

.marketing-page > nav[aria-label="Primary"] {
  border-bottom-color: var(--marketing-divider) !important;
  background: color-mix(in srgb, var(--marketing-header) 96%, transparent) !important;
  box-shadow: none !important;
}

.marketing-page > nav[aria-label="Primary"] a[href="/explore"],
.marketing-page > nav[aria-label="Primary"] a[href="/pricing"],
.marketing-page > nav[aria-label="Primary"] a[href="/login"]:not(.landing-btn-primary) {
  border-radius: var(--control-radius) !important;
}

.marketing-page > nav[aria-label="Primary"] a[aria-current="page"],
.marketing-page > nav[aria-label="Primary"] a[href="/explore"]:hover,
.marketing-page > nav[aria-label="Primary"] a[href="/pricing"]:hover,
.marketing-page > nav[aria-label="Primary"] a[href="/login"]:not(.landing-btn-primary):hover {
  color: var(--marketing-text);
  background: var(--marketing-tile);
}

.marketing-page .landing-hero-grid {
  background-image:
    radial-gradient(
      ellipse 68% 52% at 12% 4%,
      color-mix(in srgb, var(--marketing-accent) 16%, transparent),
      transparent 55%
    ),
    linear-gradient(to right, rgb(255 255 255 / 0.04) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 255 255 / 0.04) 1px, transparent 1px);
}

.marketing-page .landing-page-hero-grid {
  background-image:
    radial-gradient(
      ellipse 52% 130% at 10% -20%,
      color-mix(in srgb, var(--marketing-accent) 15%, transparent),
      transparent 62%
    ),
    linear-gradient(to right, rgb(255 255 255 / 0.04) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 255 255 / 0.04) 1px, transparent 1px);
}

/* Public-page cadence: use the same blueprint palette as the product while
   making each major chapter legible at a glance. These selectors only affect
   direct page bands, so cards retain their own quieter surface hierarchy. */
.marketing-page #site-main > :is(section, header)[class*="bg-neutral-950"] {
  background-color: var(--marketing-ground) !important;
}

/* A quiet one-step alternation separates long page chapters without turning
   the page into stacked cards. Trust stays on Ground because its template
   deliberately uses a neutral-950 band. */
.marketing-page #site-main > :is(section, header)[class*="bg-neutral-900/"] {
  background-color: var(--marketing-band) !important;
}

.marketing-page #site-main > .band-blue {
  background-color: var(--marketing-header) !important;
}

.marketing-page #site-main > .band-raised {
  background-color: var(--marketing-tile) !important;
}

/* Panel: the step between Ground and Tile. It exists because the page ran out
   of alternation at the bottom — Security, Pricing and FAQ were three
   consecutive Ground bands, so the last third read as one undivided slab.

   Which chapters may take it is decided by what they CONTAIN, not by taste:
   a band whose cards sit on Tile has to stay on Ground or the cards lose
   their step and read as recessed holes. Pricing (Tile cards) therefore stays
   Ground; Security (no cards) and FAQ (transparent rows) take Panel. */
.marketing-page #site-main > .band-panel {
  background-color: var(--marketing-panel) !important;
}

.marketing-page .landing-page-hero {
  border-bottom: 1px solid var(--marketing-border);
  background-color: var(--marketing-ground);
}

/* Dark product screens need a small lift when they are reduced on a dark page. */
.marketing-page .landing-product-shot {
  filter: brightness(1.14) contrast(1.04);
}

.marketing-page .surface-panel,
.marketing-page .surface-panel-soft,
.marketing-page main .rounded-xl.border,
.marketing-page .pricing-grid article {
  border-color: var(--marketing-border) !important;
  background-color: var(--marketing-panel) !important;
  background-image: none;
  box-shadow: none !important;
}

/* Blueprint corners are a focal marker, not wallpaper. The selected plan is
   the last surface that still earns them; ordinary FAQ and pricing panels rely
   on the stronger surface ladder instead of another outlined box. */
.marketing-page .pricing-grid article.pricing-card-featured {
  background-image:
    var(--panel-corner-tl), var(--panel-corner-tr),
    var(--panel-corner-bl), var(--panel-corner-br);
  background-position: left 0 top 0, right 0 top 0, left 0 bottom 0, right 0 bottom 0;
  background-repeat: no-repeat;
}

/* Featured treatment is internal; it must not change the card's grid geometry. */
.marketing-page .pricing-grid article.pricing-card-featured {
  box-shadow: inset 0 3px 0 0 var(--marketing-accent) !important;
}

.marketing-page .landing-btn-wrap {
  display: inline-flex;
}

.marketing-page .landing-btn-primary {
  min-height: 2.75rem;
  color: var(--marketing-ground);
  border: 1px solid color-mix(in srgb, var(--marketing-accent) 72%, transparent);
  border-radius: var(--control-radius);
  background: var(--color-brand-400);
  box-shadow: none;
  transition: border-color 150ms ease, background-color 150ms ease;
}

.marketing-page .landing-btn-overlay,
.marketing-page .landing-btn-primary.landing-btn-sm .landing-btn-overlay {
  min-height: 2.625rem;
  padding: 0.75rem 1.25rem;
  /* Nest inside the primary's 1px border: the face radius must equal the
     frame's INNER radius (outer control-radius minus the 1px border), or the
     rounder face corner exposes the darker base + page at each corner. */
  border-radius: calc(var(--control-radius) - 1px);
  background: var(--marketing-accent);
  transition:
    transform 150ms ease,
    background-color 150ms ease;
  will-change: transform;
}

.marketing-page .landing-btn-primary.landing-btn-sm .landing-btn-overlay {
  padding-inline: 1rem;
  font-size: 0.8125rem;
}

/* The primary action in the fixed nav should support the hierarchy, not
   compete with the hero. Keep the full-size treatment everywhere else. */
.marketing-page .landing-nav-cta .landing-btn-primary {
  min-height: 2.25rem;
}

.marketing-page .landing-nav-cta .landing-btn-primary.landing-btn-sm .landing-btn-overlay {
  min-height: 2.125rem;
  padding: 0.5rem 0.875rem;
  gap: 0.375rem;
  font-size: 0.75rem;
}

.marketing-page .landing-btn-wrap.is-brand:hover .landing-btn-primary {
  border-color: var(--color-brand-500);
  background: var(--color-brand-500);
}

.marketing-page .landing-btn-wrap.is-brand:hover .landing-btn-overlay,
.marketing-page .landing-btn-wrap.is-brand:hover .landing-btn-primary.landing-btn-sm .landing-btn-overlay {
  background: var(--marketing-accent-hover);
}

.marketing-page .landing-btn-wrap:hover .landing-btn-icon {
  transform: none;
}

@media (hover: hover) and (pointer: fine) {
  .marketing-page .landing-btn-wrap.is-brand:hover .landing-btn-overlay {
    transform: translate(-0.4rem, -0.4rem);
  }

  .marketing-page .landing-btn-wrap.is-brand:hover .landing-btn-primary.landing-btn-sm .landing-btn-overlay {
    transform: translate(-0.3rem, -0.3rem);
  }

  .marketing-page .landing-btn-wrap:hover .landing-btn-icon {
    transform: translateX(0.4rem);
  }

  .marketing-page .landing-btn-wrap.is-brand:active .landing-btn-overlay,
  .marketing-page .landing-btn-wrap.is-brand:active .landing-btn-primary.landing-btn-sm .landing-btn-overlay {
    transform: translate(-0.12rem, -0.12rem);
    transition-duration: 150ms;
  }
}

@media (prefers-reduced-motion: reduce) {
  .marketing-page .landing-btn-primary,
  .marketing-page .landing-btn-overlay,
  .marketing-page .landing-btn-primary.landing-btn-sm .landing-btn-overlay,
  .marketing-page .landing-btn-icon {
    transition: none;
  }

  .marketing-page .landing-btn-wrap.is-brand:hover .landing-btn-overlay,
  .marketing-page .landing-btn-wrap.is-brand:hover .landing-btn-primary.landing-btn-sm .landing-btn-overlay,
  .marketing-page .landing-btn-wrap:hover .landing-btn-icon {
    transform: none;
  }
}

/* Was --marketing-panel, which is DARKER than the card it sits on, so two of
   the three plan CTAs read as recessed holes on the money surface. A
   secondary button on a raised card is transparent; the border carries it. */
.marketing-page .landing-cta-outline {
  min-height: 2.75rem;
  border-radius: var(--control-radius);
  border-color: var(--rule-raised);
  color: var(--marketing-text);
  background: transparent;
}

.marketing-page .landing-cta-outline:hover {
  border-color: var(--marketing-accent);
  color: var(--marketing-text);
  background: var(--marketing-tile);
}

/* Secondary plan CTAs carry a surface, not just an outline. Transparent was
   fine while the card was Tile — the button read against a lighter field.
   With the cards dropped to Ground the button became the card colour and the
   only thing left marking it was a hairline, so it stopped reading as a
   control. Tile puts it a clear step above the card it sits in, which also
   restores the rank: filled accent (Operator) > raised (Recon, Arsenal). */
.marketing-page .pricing-grid .landing-cta-outline {
  background: var(--marketing-tile);
  border-color: rgb(255 255 255 / 0.16);
}

.marketing-page .pricing-grid .landing-cta-outline:hover {
  background: color-mix(in srgb, var(--marketing-tile) 82%, white);
  border-color: var(--marketing-accent);
}

.marketing-page .landing-cta-text:hover {
  color: var(--marketing-accent-hover);
}

.marketing-page .toggle-track {
  border-color: var(--marketing-border) !important;
  background: var(--marketing-tile) !important;
  box-shadow: none !important;
}

.marketing-page .toggle-knob {
  background: var(--marketing-accent) !important;
  box-shadow: none !important;
}

.marketing-page #pricing-toggle:focus-visible ~ .toggle-row .toggle-track {
  box-shadow: 0 0 0 2px var(--marketing-ground), 0 0 0 4px var(--marketing-accent) !important;
}

.marketing-page .pricing-compare-wrap {
  border-radius: 0;
  box-shadow: none;
}

.marketing-page .pricing-compare thead th,
.marketing-page .pricing-compare thead th:first-child,
.marketing-page .pricing-compare td.feature-label,
.marketing-page .pricing-compare .pricing-section-label {
  background: var(--marketing-overlay);
}

.marketing-page .pricing-compare .section-row > *,
.marketing-page .pricing-compare .cell-yes,
.marketing-page .pricing-included-list li i {
  color: var(--marketing-accent);
}

/* Needs the section qualifier and !important to clear the blanket band rule,
   which is also !important. Deliberately NOT solved with a :not() list on the
   band rule, which would have to be extended for every future band.

   This strip was RAISED when the bands either side of it were Ground. They
   are Panel now, and Tile-between-Panels put three mid-blue bands in a row at
   the decision moment — the plans, this strip and the comparison all read as
   one mass. Inverting it to Ground makes the thin strip a dark seam that
   separates the two, which is the job it was added to do. */
.marketing-page #site-main > section.pricing-included-strip {
  border-color: var(--rule-raised) !important;
  background: var(--marketing-ground) !important;
}

.marketing-page .landing-footer-cta {
  border-color: var(--marketing-divider);
  background: linear-gradient(
    118deg,
    color-mix(in srgb, var(--marketing-accent) 16%, transparent) 0%,
    color-mix(in srgb, var(--color-brand-400) 10%, transparent) 38%,
    var(--marketing-ground) 72%
  );
}

.marketing-page > footer {
  border-color: var(--marketing-divider) !important;
  background: var(--marketing-ground) !important;
}

.marketing-page .legal-prose .intro {
  border-left-color: var(--marketing-accent);
}

.marketing-page .legal-prose h2,
.marketing-page .legal-prose a {
  color: var(--marketing-accent-hover);
}

.marketing-page .legal-prose h2 {
  padding-top: 2rem;
  border-top: 1px solid var(--marketing-divider);
}

.marketing-page .legal-prose a {
  text-decoration-color: color-mix(in srgb, var(--marketing-accent) 55%, transparent);
}

.marketing-page .legal-prose a:hover {
  color: var(--color-brand-900);
}

.marketing-page .legal-prose .warning-box {
  border-color: var(--color-blueprint-warning-border);
  border-radius: 0;
  background: var(--color-blueprint-warning-tint);
}

/* CCW per-state "show another state" dropdown (a <details>, not a native
   <select>). Hide the disclosure marker and match the app's form focus ring
   (blueprint accent border + soft 3px halo), not the white browser default. */
.ccw-jump-summary {
  list-style: none;
}
.ccw-jump-summary::-webkit-details-marker {
  display: none;
}
.ccw-jump-summary:focus-visible {
  outline: none;
  border-color: color-mix(in srgb, var(--color-blueprint-accent) 50%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-blueprint-accent) 15%, transparent);
}

/* Unlayered file: rules below beat Tailwind utilities regardless of specificity. */

@media (width < 40rem) {
  .marketing-page .landing-nav-cta .landing-btn-primary {
    min-height: 2rem;
  }

  .marketing-page .landing-nav-cta .landing-btn-primary.landing-btn-sm .landing-btn-overlay {
    min-height: 1.875rem;
    padding: 0.4375rem 0.625rem;
    font-size: 0.6875rem;
  }
}

@media (pointer: coarse) {
  .landing-cta-text {
    min-height: 2.75rem;
    padding-block: 0.5rem;
  }

  /* 2.25rem, not 2.75: these already pass WCAG 2.5.8 via the spacing
     exception at a 40px pitch, and forcing 44px added ~200px of mobile
     scroll across nine links for no compliance gain. */
  .landing-footer-links {
    gap: 0;
  }

  .landing-footer-link {
    display: inline-flex;
    align-items: center;
    min-height: 2.25rem;
  }
}

#pricing-toggle:checked ~ .toggle-row .toggle-label-annual,
#pricing-toggle:not(:checked) ~ .toggle-row .toggle-label-monthly {
  color: var(--color-blueprint-muted);
}

/* Tailwind's scroll-smooth ships no reduced-motion guard of its own. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto !important;
  }
}

#pricing-toggle:not(:checked) ~ .billing-live .billing-live-monthly,
#pricing-toggle:checked ~ .billing-live .billing-live-annual {
  display: none;
}

/* Inline CTAs measured 20px tall on touch; a class avoids a mt-6 utility clash. */
@media (pointer: coarse) {
  .landing-inline-link {
    min-height: 2.75rem;
  }
}

/* ===================================================================
   LANDING TYPE + SURFACE SYSTEM
   Unlayered, so these beat any Tailwind utility on the same property.
   Type ladder: distinct roles that preserve heading order at every width.
   =================================================================== */

/* ---- GUTENBERG (matejlatin/Gutenberg) ----------------------------------
   Three source values — base size, leading, measure — and the rest derives.
   Sizes are the Perfect Fifth (1.5) modular scale; vertical space in prose is
   a whole multiple of the baseline. Instrument Sans is untouched: this system
   governs size, leading and rhythm, never the family.

   Base is 100% / 112.5% per Gutenberg, but declared HERE rather than on html.
   The root is pinned at 16px deliberately (a fluid root once sawtoothed the
   whole rem interface), and every rem in this file — the Fibonacci layout
   scale included — is measured against that 16px. Scoping the reading size to
   .marketing-page buys Gutenberg's body copy without moving one layout value.

   Steps are therefore written in rem, resolved from the base at each
   breakpoint, not em: a custom property holding `em` resolves against
   whatever element consumes it, so nested type would compound.

   Ladder (x base):  0.75  0.8  1  1.125  1.375  1.6875  2.5
   at 16px base:      12  12.8  16   18     22     27     40
   at 18px base:    13.5  14.4  18  20.25  24.75  30.375  45   */
.marketing-page {
  font-size: 1rem;
  line-height: 1.625;

  --fs-label: 0.75rem;
  --fs-caption: 0.8rem;
  --fs-body: 1rem;
  --fs-lead: 1.125rem;
  /* Headings interpolate between the step at the mobile base and the step at
     the desktop base, so both ends sit on the scale and nothing jumps between.
     The floors also keep h2 and h3 distinct on phones, which a flat size did
     not: they rendered identically below 1018px. */
  --fs-title: clamp(1.375rem, 1.19rem + 0.72vw, 1.546875rem);
  --fs-display: clamp(1.6875rem, 1.42rem + 1.05vw, 1.8984375rem);
  --fs-page-title: clamp(2.5rem, 2.06rem + 1.72vw, 2.8125rem);
  --fs-hero: clamp(2.5rem, 2.06rem + 1.72vw, 2.8125rem);

  /* Gutenberg's measure is 35 base units, which lands on ~68 characters here.
     Expressed in `em`, NOT rem: a measure is a character count, so it has to
     scale with the size of the text it is holding. In rem it was frozen at
     the body's width, which meant every larger role got FEWER characters per
     line — the 20px hero lead was capped at 480px and broke 258 characters
     into six short lines under a 768px headline, reading as a slab.

     A max-width in em resolves against the element's own font-size, so one
     constant now gives every role the same ~68 characters. That also retires
     the separate caption measure, which only existed because small text in a
     rem-fixed box ran to 99 characters. (`ch` is still no good here:
     Instrument Sans has a wide zero, so 62ch resolved to 702px and never
     bound.) */
  --measure: 31em;
  --measure-caption: var(--measure);
}

@media (width >= 64rem) {
  .marketing-page {
    font-size: 1.125rem; /* 112.5% */
    line-height: 1.7222; /* 31px baseline, whole pixels */

    --fs-label: 0.84375rem;
    --fs-caption: 0.9rem;
    --fs-body: 1.125rem;
    --fs-lead: 1.265625rem;
  }
}

/* Display type owns its own colour so no caller can pick a different
   white. Was 20 hardcoded text-white, a value not in the palette. */
.marketing-page .landing-heading {
  color: var(--color-blueprint-text);
}

.marketing-page .landing-hero-title {
  font-size: var(--fs-hero);
  line-height: 1.03;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.marketing-page .landing-page-title {
  margin-top: var(--sp-1);
  font-size: var(--fs-page-title);
  line-height: 1.04;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.marketing-page .landing-section-title {
  margin-top: var(--sp-1);
  font-size: var(--fs-display);
  line-height: 1.08;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.marketing-page .landing-row-title {
  margin-top: var(--sp-1);
  font-size: var(--fs-title);
  line-height: 1.12;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

/* One step below Paper, one above body: the lead was the same colour as every
   heading, which left 6px and 100 weight units separating it from display
   type. Also drops the stray 46ch, which is the unit this file abandoned. */
.marketing-page .landing-lead {
  max-width: var(--measure);
  color: rgb(255 255 255 / 0.86);
  font-size: var(--fs-lead);
  font-weight: 400;
  line-height: 1.45;
  text-wrap: pretty;
}

.marketing-page .landing-body-copy {
  max-width: var(--measure);
  color: rgb(255 255 255 / 0.8);
  font-size: var(--fs-body);
  line-height: inherit;
  text-wrap: pretty;
}

/* Prose flow sits on the baseline: one full unit between a heading and the
   copy under it, and between consecutive paragraphs. The eyebrow-to-title gap
   is NOT part of this — an eyebrow and its heading are one composed unit, not
   two blocks in a column, so it keeps its tight Fibonacci 13px. */
.marketing-page :is(.landing-page-title, .landing-section-title, .landing-row-title) + .landing-body-copy,
.marketing-page .landing-page-title + .landing-lead,
.marketing-page .landing-body-copy + .landing-body-copy {
  margin-top: var(--gb-baseline);
}

.marketing-page .landing-note {
  font-size: var(--fs-caption);
  line-height: 1.5;
  max-width: var(--measure-caption);
  color: rgb(255 255 255 / 0.62);
}

.marketing-page .landing-section-eyebrow {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.62);
}

.marketing-page .landing-faq-header {
  text-align: left;
}

.marketing-page .landing-faq-q {
  padding-right: var(--sp-2);
  color: var(--color-blueprint-text);
  font-size: var(--fs-body);
  line-height: 1.35;
  text-align: left;
}

.marketing-page .pricing-plan-name {
  margin-bottom: 0.3125rem;
  color: var(--color-blueprint-text);
  font-size: var(--fs-title);
  line-height: 1.12;
  letter-spacing: -0.025em;
}

/* Reserves two lines whether the tagline needs one or two, so the price row
   starts at the same height in every card. Without it Recon's two-line
   tagline pushed its price 21px below Operator's and Arsenal's, and the three
   prices — the one thing a visitor scans across — did not line up.

   `em`, so the reservation tracks the tagline's own size. Two lines is the
   budget: a third would push the price down again, and `balance` keeps a
   two-line tagline from breaking as one long line and one short. */
.marketing-page .pricing-plan-tagline {
  margin-bottom: var(--sp-1);
  min-height: 3em; /* 2 x line-height */
  color: rgb(255 255 255 / 0.68);
  font-size: var(--fs-caption);
  line-height: 1.5;
  text-wrap: balance;
}

.marketing-page .pricing-price-period {
  margin-left: 0.5rem;
  color: rgb(255 255 255 / 0.62);
  font-size: var(--fs-caption);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.marketing-page .landing-faq-a {
  font-size: var(--fs-body);
  line-height: 1.6;
  max-width: var(--measure);
  color: rgb(255 255 255 / 0.8);
  padding-bottom: var(--sp-2);
}

@media (width >= 40rem) {
  .marketing-page .landing-faq-a {
    padding-bottom: var(--sp-3);
  }
}


/* Inline prose links: Steel is an affordance, so it stays on anchors. */
.marketing-page .landing-prose-link {
  color: var(--color-brand-600);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: color-mix(in srgb, var(--color-brand-600) 50%, transparent);
}

.marketing-page .landing-prose-link:hover {
  color: var(--color-brand-700);
}

.marketing-page .landing-inline-link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: var(--fs-caption);
  font-weight: 600;
  color: var(--color-brand-600);
}

.marketing-page .landing-inline-link:hover {
  color: var(--color-brand-700);
}

/* Text, not chips. Eight bordered tiles under the header read as a toolbar
   and competed with the tour they point at; the links carry the wayfinding on
   their own. No scroll-position state is possible here (landing pages ship no
   JS), so hover and :focus-visible are the only affordances to spend. */
.marketing-page .landing-jump-link {
  display: inline-flex;
  min-height: 2.75rem;
  flex: 0 0 auto;
  align-items: center;
  padding-inline: 0;
  border: 0;
  color: rgb(255 255 255 / 0.62);
  background: none;
  font-size: var(--fs-caption);
  font-weight: 600;
  white-space: nowrap;
  transition: color 150ms ease;
}

.marketing-page .landing-jump-link:hover,
.marketing-page .landing-jump-link:focus-visible {
  color: var(--marketing-text);
}


/* Steel is an interaction signal. It was on 40 elements and only ~5 were
   clickable, which left the CTA with no differentiator. Punctuation goes
   muted; the accent returns only on the open state. */
.marketing-page #site-main li > i.fa-check,
.marketing-page #site-main .fa-circle-check,
.marketing-page .faq-chevron {
  color: rgb(255 255 255 / 0.42);
}

.marketing-page #site-main .pricing-grid .fa-circle-check,
.marketing-page #site-main .pricing-included-list .fa-circle-check {
  color: var(--marketing-accent);
}

.marketing-page details[open] .faq-chevron {
  color: var(--marketing-accent);
}

/* ---- Band rhythm. Three tiers on the Fibonacci vertical, so a band's
   height states its rank. Replaces py-12 sm:py-16 lg:py-20 (48/64/80,
   none on the scale) repeated across eight sections. ---- */
/* Three tiers a full scale step apart at EVERY width. Previously standard and
   major were identical below 1024px, so the third tier was a no-op on the
   viewport carrying most of the scroll. Mobile also steps down a rung, which
   is where the page could least afford 48px bands. */
.marketing-page .band-minor {
  padding-block: var(--sp-1);
}
.marketing-page .band-standard {
  padding-block: var(--sp-2);
}
.marketing-page .band-major {
  padding-block: var(--sp-3);
}

@media (width >= 40rem) {
  .marketing-page .band-minor {
    padding-block: var(--sp-2);
  }
  .marketing-page .band-standard {
    padding-block: var(--sp-3);
  }
  .marketing-page .band-major {
    padding-block: var(--sp-4);
  }
}

@media (width >= 64rem) {
  .marketing-page .band-minor {
    padding-block: var(--sp-3);
  }
  .marketing-page .band-standard {
    padding-block: var(--sp-4);
  }
  .marketing-page .band-major {
    padding-block: var(--sp-5);
  }
}

/* ---- Elevation. Cards were forced to Panel (L* 8.9) inside bands forced
   to Tile (L* 11.8), so every card rendered DARKER than its own band and
   read as a recessed hole with a hairline 14x stronger than its fill step.
   One rung up, never down. ---- */
/* Declared on .marketing-page, not only on sections: a panel placed in the
   footer or on a div-rooted page would otherwise resolve var(--raised) to
   nothing and compute transparent. */
.marketing-page {
  --raised: var(--color-blueprint-tile);
  --rule-raised: rgb(255 255 255 / 0.12);
  --rule-band: rgb(255 255 255 / 0.055);
}

.marketing-page #site-main > :is(section, header) {
  border-color: var(--rule-band) !important;
}

.marketing-page .surface-panel,
.marketing-page .surface-panel-soft,
.marketing-page #site-main .rounded-xl.border,
.marketing-page .pricing-grid article,
.marketing-page .pricing-compare-wrap {
  background-color: var(--raised) !important;
  border-color: var(--rule-raised) !important;
}

/* Pricing cards cut DOWN from their band rather than up. The band moved to
   Panel to break the three-Ground run at the foot of the page, and a Tile
   card on a Panel band left only one step between them; dropping the cards to
   Ground doubles that separation and lets the plans read as wells cut into
   the band. The border does the lifting now, so it goes up a stop to stay
   visible against the lighter surface behind it. */
.marketing-page .pricing-grid article {
  background-color: var(--marketing-ground) !important;
  border-color: rgb(255 255 255 / 0.14) !important;
}

/* ---- The showcase sequence. The introduction is a single centered thought;
   the alternating product rows below own the directional two-column rhythm. ---- */
.marketing-page .landing-section-intro {
  display: grid;
  width: 100%;
  max-width: 48rem;
  justify-items: center;
  gap: var(--sp-2);
  margin: 0 auto var(--sp-3);
  text-align: center;
}

.marketing-page .landing-section-intro > .landing-body-copy {
  margin: 0 auto;
}

/* When the intro IS the section (nothing follows it inside the band), its
   trailing margin would double the band's own bottom padding. No caller flag:
   the selector decides. */
.marketing-page .landing-section-intro:only-child {
  margin-bottom: 0;
}

/* ---- Band backdrops ----------------------------------------------------
   Shared mechanics: full-bleed, behind the content, inert to the pointer.
   Each band's own texture is a modifier below, so the positioning has one
   owner and a new band can't get it subtly wrong.

   All of these are drawn in CSS, not shipped as images — the landing bundle
   is deliberately small, and a few hundred bytes beats a request.

   No vault, lock or padlock motifs: anything with an outline reads as a stray
   box floating behind the text at these band heights, and the literal
   iconography is a cliché the rest of the page doesn't trade in. Texture
   only, always masked to nothing before the band edges so the seams between
   neighbouring bands stay clean. */
.marketing-page .landing-band-backdrop {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* Security: the same 58px survey grid the hero uses, lifted by a soft steel
   bloom behind the centred copy. The grid already says engineered. */
.marketing-page .security-backdrop {
  background-image:
    radial-gradient(
      ellipse 52% 74% at 50% 48%,
      color-mix(in srgb, var(--marketing-accent) 9%, transparent),
      transparent 72%
    ),
    linear-gradient(to right, rgb(255 255 255 / 0.022) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 255 255 / 0.022) 1px, transparent 1px);
  background-size: 100% 100%, 58px 58px, 58px 58px;
  background-position: center;
  -webkit-mask-image: radial-gradient(78% 92% at 50% 50%, #000 22%, transparent 80%);
  mask-image: radial-gradient(78% 92% at 50% 50%, #000 22%, transparent 80%);
}

/* Pricing: survey DOTS rather than lines — same graph-paper family as the
   security band and on the same rhythm (29px is half its 58px module), but
   distinguishable, so two textured bands on one page don't read as a repeat.
   Dots also stay quieter under a card grid than ruled lines, which would run
   visibly into the card edges.

   Carries the bottom-anchored steel bloom the section already had, so the
   plans sit on a lift rather than a flat field. Slightly stronger alpha than
   the security band because this one sits on Panel, not Ground. */
.marketing-page .pricing-backdrop {
  background-image:
    radial-gradient(
      ellipse 70% 45% at 50% 110%,
      color-mix(in srgb, var(--marketing-accent) 11%, transparent),
      transparent 62%
    ),
    radial-gradient(circle, rgb(255 255 255 / 0.05) 1px, transparent 1.5px);
  background-size: 100% 100%, 29px 29px;
  background-position: center;
  -webkit-mask-image: radial-gradient(88% 96% at 50% 62%, #000 30%, transparent 84%);
  mask-image: radial-gradient(88% 96% at 50% 62%, #000 30%, transparent 84%);
}

.marketing-page .landing-showcase-stack {
  display: grid;
  width: 100%;
  max-width: 72rem;
  gap: var(--sp-4);
  margin-inline: auto;
}

.marketing-page .landing-showcase-row {
  display: grid;
  gap: var(--sp-3);
}

/* Explore groups chapter labels with the first proof row they introduce.
   The old `space-y-*` loop treated the chapter and its row as unrelated
   siblings and added two large gaps (plus an extra margin) around them. */
.marketing-page .product-tour-list {
  display: grid;
  gap: var(--sp-4);
}

.marketing-page .product-tour-item {
  display: grid;
}

@media (width >= 40rem) {
  .marketing-page .landing-section-intro {
    margin-bottom: var(--sp-4);
  }
}

@media (width >= 64rem) {
  .marketing-page .landing-showcase-stack {
    gap: var(--sp-5);
  }
  .marketing-page .landing-showcase-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.618fr);
    gap: var(--sp-4);
    align-items: center;
  }

  .marketing-page .landing-showcase-row.is-reversed {
    grid-template-columns: minmax(0, 1.618fr) minmax(0, 1fr);
  }

  .marketing-page .landing-showcase-row.is-reversed > :first-child {
    grid-column: 2;
    grid-row: 1;
  }

  .marketing-page .landing-showcase-row.is-reversed > .landing-shot {
    grid-column: 1;
    grid-row: 1;
  }

  .marketing-page .product-tour-list {
    gap: var(--sp-5);
  }

}

/* Product proof uses one shared frame on every marketing page. The restrained
   4px mat separates dark application chrome from the page Ground without
   introducing a second card language or changing the screenshot geometry. */
.marketing-page .landing-shot {
  margin: 0;
  padding: 0.25rem;
  border: 1px solid var(--marketing-border);
  background: var(--marketing-panel);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.04),
    0 1.3125rem 3.4375rem -2.125rem rgb(0 0 0 / 0.9);
}

.marketing-page .landing-shot picture {
  display: block;
}

.marketing-page .landing-shot img {
  display: block;
  width: 100%;
  height: auto;
}

/* Copy left, document deck right — the same two-column rhythm as the product
   rows above. The previous single centered column stranded a near-square
   1200x1218 sheet under centered prose in a 48rem well, which left the band
   enormous and the sheet floating with no relationship to the text. */
.marketing-page .report-output-grid {
  display: grid;
  width: 100%;
  gap: var(--sp-3);
  align-items: center;
}

@media (width >= 64rem) {
  .marketing-page .report-output-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 26rem);
    gap: 4.25rem;
  }
}

/* ---- The report deck: three PDFs stacked, cycled with pure CSS ---- */
.marketing-page .report-deck-wrap {
  width: 100%;
  max-width: 26rem;
  margin-inline: auto;
}

.marketing-page .report-deck-radio {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The deck reserves its own height from the front card's aspect ratio; the
   cards are absolutely positioned so they truly overlap instead of flowing.
   The extra top/right room is where the two back cards peek out. */
.marketing-page .report-deck {
  position: relative;
  aspect-ratio: 1200 / 1218;
  /* Reserves the top/right room the back cards translate into (12% of the
     card, matching the deepest offset below). */
  margin: var(--sp-4) var(--sp-4) 0 0;
}

/* Offsets are percentages of the card's own box and the origin is its centre,
   so the peek is always (translate - (1 - scale) / 2) and stays proportional
   at every deck width. Scaling from a corner instead ate the whole offset and
   hid the back cards completely behind the front one. */
.marketing-page .report-card {
  position: absolute;
  inset: 0;
  margin: 0;
  transform-origin: center;
  transition:
    transform 260ms cubic-bezier(0.2, 0.7, 0.3, 1),
    opacity 260ms ease,
    filter 260ms ease;
}

.marketing-page .report-card picture {
  display: block;
  height: 100%;
  background: #fff;
  box-shadow: 0 1.3125rem 3.4375rem -1.3125rem rgb(0 0 0 / 0.75);
}

.marketing-page .report-card img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

/* Full-card click target. Only the front card gets pointer events (below), so
   this is the "advance one" affordance and never fires from a buried card. */
.marketing-page .report-card-hit {
  position: absolute;
  inset: 0;
  z-index: 1;
  cursor: pointer;
}

/* Depth states. The front card is the readable document; the two behind it are
   pushed up and right, shrunk, and dimmed so the stack reads as a pile of
   paper rather than three competing screenshots. This block is the back-most
   default, so the deck still looks like a deck if no radio is checked. */
.marketing-page .report-card {
  z-index: 1;
  transform: translate(12%, -12%) scale(0.92);
  opacity: 0.5;
  filter: brightness(0.62);
  pointer-events: none;
}

/* Radio N brings card N to the front and rotates the other two behind it.
   Nine rules, one per (checked radio, card) pair — the price of doing this
   without JavaScript. */
#report-deck-1:checked ~ .report-deck .report-card.is-1,
#report-deck-2:checked ~ .report-deck .report-card.is-2,
#report-deck-3:checked ~ .report-deck .report-card.is-3 {
  z-index: 3;
  transform: none;
  opacity: 1;
  filter: none;
  pointer-events: auto;
}

#report-deck-1:checked ~ .report-deck .report-card.is-2,
#report-deck-2:checked ~ .report-deck .report-card.is-3,
#report-deck-3:checked ~ .report-deck .report-card.is-1 {
  z-index: 2;
  transform: translate(6%, -6%) scale(0.96);
  opacity: 0.78;
  filter: brightness(0.82);
}

#report-deck-1:checked ~ .report-deck .report-card.is-3,
#report-deck-2:checked ~ .report-deck .report-card.is-1,
#report-deck-3:checked ~ .report-deck .report-card.is-2 {
  z-index: 1;
  transform: translate(12%, -12%) scale(0.92);
  opacity: 0.5;
  filter: brightness(0.62);
  pointer-events: none;
}

.marketing-page .report-deck-controls {
  display: flex;
  justify-content: center;
  gap: 0.25rem;
  margin-top: var(--sp-1);
}

/* The visible mark is a 3px bar, but a 3px-tall hit area is unclickable. The
   label carries the target (44px tall, WCAG 2.5.5 AAA) and draws the bar in a
   pseudo-element, so the control grows without the bar getting heavier. The
   negative gap compensation keeps the bars the same distance apart as before. */
.marketing-page .report-deck-dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 2.75rem;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.marketing-page .report-deck-dot::before {
  content: "";
  display: block;
  width: 2.125rem;
  height: 3px;
  background: rgb(255 255 255 / 0.18);
  transition:
    background 160ms ease,
    height 160ms ease;
}

.marketing-page .report-deck-dot:hover::before {
  height: 5px;
  background: rgb(255 255 255 / 0.34);
}

#report-deck-1:checked ~ .report-deck-controls .report-deck-dot:nth-child(1)::before,
#report-deck-2:checked ~ .report-deck-controls .report-deck-dot:nth-child(2)::before,
#report-deck-3:checked ~ .report-deck-controls .report-deck-dot:nth-child(3)::before {
  background: var(--marketing-accent);
}

/* Keyboard users move through the group with arrow keys; show them where
   they are, since the dots are the only visible control. */
.marketing-page .report-deck-radio:focus-visible ~ .report-deck-controls .report-deck-dot::before {
  outline: 1px solid var(--marketing-accent);
  outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
  .marketing-page .report-card {
    transition: none;
  }
}

/* ---- Explore: a visual product tour, not a stack of documentation rows. ---- */
.explore-page .landing-anchor-target {
  scroll-margin-top: 8rem;
}

.explore-page-hero {
  padding-bottom: var(--sp-3);
}

.explore-hero-layout {
  display: grid;
  gap: var(--sp-3);
  align-items: center;
}

.explore-hero-copy {
  max-width: var(--measure);
}

.explore-hero-product {
  min-width: 0;
  margin: 0;
}

.explore-hero-device.hero-device-stage,
.landing-hero-media .hero-device-stage {
  width: 100%;
  max-width: none;
}

.explore-jump-list {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  overflow-x: auto;
}

.explore-jump-nav {
  position: sticky;
  top: 3.75rem;
  z-index: 30;
  padding-block: 0.5rem;
  border-bottom: 1px solid var(--marketing-divider);
  background: color-mix(in srgb, var(--marketing-header) 97%, transparent);
  box-shadow: 0 0.8125rem 2.125rem -2.125rem rgb(0 0 0 / 0.9);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  backdrop-filter: blur(14px) saturate(1.2);
}

.explore-tour-section {
  padding-block: var(--sp-4);
}

.explore-page .landing-availability {
  max-width: var(--measure-caption);
  margin-top: var(--sp-2);
  padding: 0.625rem 0 0.625rem var(--sp-1);
  border-left: 2px solid color-mix(in srgb, var(--marketing-accent) 45%, transparent);
}

.explore-page .landing-availability-label {
  margin-bottom: 0.3125rem;
  color: rgb(255 255 255 / 0.5);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  line-height: 1.3;
  text-transform: uppercase;
}

.explore-page .landing-availability > p:not(.landing-availability-label) {
  color: rgb(255 255 255 / 0.68);
  font-size: var(--fs-caption);
  line-height: 1.5;
}

.explore-page .landing-availability > p + p {
  margin-top: 0.1875rem;
}

@media (width >= 40rem) {
  .explore-page-hero {
    padding-bottom: var(--sp-4);
  }

}

@media (width >= 64rem) {
  .explore-page-hero {
    padding-bottom: 4rem;
  }

  .explore-hero-layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.618fr);
    gap: var(--sp-4);
  }

  .explore-tour-section {
    padding-block: var(--sp-5);
  }

}

@media (prefers-reduced-motion: reduce) {
  .explore-jump-nav {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* These rules intentionally live after the public button system. Earlier
   versions hid the monthly links before `.landing-btn-wrap` and
   `.landing-cta-text` later reintroduced `display`, rendering duplicate CTAs. */
.marketing-page #pricing .pricing-period-navigation .pricing-period-monthly,
.marketing-page .pricing-final-period-links .pricing-period-monthly {
  display: none;
}

.marketing-page #pricing-toggle:checked ~ .pricing-period-navigation .pricing-period-annual,
.marketing-page #site-main:has(#pricing-toggle:checked) .pricing-final-period-links .pricing-period-annual {
  display: none;
}

.marketing-page #pricing-toggle:checked ~ .pricing-period-navigation .pricing-period-monthly,
.marketing-page #site-main:has(#pricing-toggle:checked) .pricing-final-period-links .pricing-period-monthly {
  display: inline-flex;
}
