/* TenderScope — public landing page styles.
 * Extracted from templates/landing.html (Batch 7).
 *
 * PR FI-1 (superseded by PR SF) — this file used to @import
 * tokens.css, which serialized the two stylesheet fetches (the
 * browser can't discover the @import URL until landing.css itself
 * has downloaded). PR SF replaced it with a <link> to tokens.css
 * placed BEFORE the <link> to this file in templates/landing.html,
 * so both fetch in parallel. Cascade order is preserved by that
 * <link> ordering: tokens.css's `:root` loads first, so the
 * page-specific `--bg: #FFFFFF`, `--r-lg: 14px`, `--dur: 200ms`
 * overrides below still win, same as before. */

* { box-sizing: border-box; margin: 0; padding: 0; }

/* PR BY: skip-link — see static/index.css for the longer note. */
.skip-link {
  position: absolute;
  top: -100px; left: 8px;
  background: var(--accent, #1E40AF);
  color: #ffffff;
  padding: 10px 16px; border-radius: 6px;
  z-index: 100; font-weight: 600;
  text-decoration: none;
  font-family: 'Noto Sans Georgian', sans-serif;
}
.skip-link:focus { top: 8px; outline: 2px solid #ffffff; outline-offset: 2px; }

:root {
  /* PR BY: native form controls + scrollbars + date picker honor the
     active theme. See static/index.css for the longer note. */
  color-scheme: light dark;
  /* PR CI: explicit transition list — see static/index.css for note. */
  --transition-base: background-color var(--dur, 180ms) var(--ease, ease),
                     border-color     var(--dur, 180ms) var(--ease, ease),
                     color            var(--dur, 180ms) var(--ease, ease),
                     box-shadow       var(--dur, 180ms) var(--ease, ease),
                     transform        var(--dur, 180ms) var(--ease, ease);

  /* PR FQ — ink/paper/line/accent/green/amber consolidated to
   * tokens.css. Page-specific tokens remain below. */
  --bg: #FFFFFF;
  --paper-strong: #F1F5F9;
  --shadow-sm: 0 1px 3px rgba(11, 18, 32, 0.05), 0 1px 2px rgba(11, 18, 32, 0.04);
  --shadow-md: 0 4px 12px rgba(11, 18, 32, 0.08), 0 2px 4px rgba(11, 18, 32, 0.04);
  --shadow-lg: 0 12px 32px rgba(11, 18, 32, 0.12), 0 4px 8px rgba(11, 18, 32, 0.06);
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 14px;
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --dur: 200ms;
  /* PR SQ — Control Room motion vocabulary. --ease-out for all
     entrances/reveals (expo-out: fast, then settles), --ease-spring
     for pops/stamps (≤6% overshoot). Micro-hovers keep --ease. */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

[data-theme="dark"] {
  /* PR FQ — dark color tokens consolidated to tokens.css. */
  --bg: #0B1220;
  --paper-strong: #0A1322;
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  font-family: 'Noto Sans Georgian', sans-serif;
  color: var(--ink); background: var(--bg);
  line-height: 1.5; -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

.icon { width: 1em; height: 1em; flex-shrink: 0; vertical-align: -0.125em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ============ Nav (PR FM mega-menu) ============ */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
  padding: 14px 28px;
  display: flex; align-items: center; justify-content: space-between;
  transition: background var(--dur), border-color var(--dur),
              padding var(--dur), box-shadow var(--dur);
}
[data-theme="dark"] .nav { background: rgba(19, 28, 46, 0.85); }

/* Scroll-shrink — JS toggles `.is-scrolled` once scrollY > 50px.
   Tighter padding + more opaque bg + soft shadow give the floating
   "navbar landed on the page" feel without changing layout height
   so much that CLS becomes a problem. */
.nav.is-scrolled {
  padding: 8px 28px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 2px 12px rgba(11, 18, 32, 0.06);
}
[data-theme="dark"] .nav.is-scrolled {
  background: rgba(19, 28, 46, 0.96);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}

.brand { display: flex; align-items: center; gap: 12px; }
.brand-logo {
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--accent-strong), var(--accent));
  color: white; border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}
[data-theme="dark"] .brand-logo { background: linear-gradient(135deg, #1E3A8A, #3B82F6); }
.brand-text { display: flex; flex-direction: column; gap: 1px; line-height: 1.1; }
.brand-mark {
  font-family: 'Noto Serif Georgian', serif;
  font-weight: 700; font-size: 19px; letter-spacing: -0.015em;
  color: var(--ink);
}
.brand-tag {
  font-size: 10.5px; color: var(--ink-muted);
  text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600;
}

.nav-actions { display: flex; align-items: center; gap: 10px; }
.nav-link {
  font-size: 13.5px; font-weight: 600; color: var(--ink-soft);
  padding: 8px 14px; border-radius: var(--r-sm);
  transition: var(--transition-base);
}
.nav-link:hover { color: var(--accent); background: var(--accent-soft); }
.nav-cta {
  font-size: 13.5px; font-weight: 600;
  background: linear-gradient(180deg, var(--accent), var(--accent-hover));
  color: white; padding: 9px 16px; border-radius: var(--r-sm);
  box-shadow: var(--shadow-sm), inset 0 1px 0 rgba(255, 255, 255, 0.15);
  transition: var(--transition-base);
}
[data-theme="dark"] .nav-cta { color: #0B1220; font-weight: 700; }
.nav-cta:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); }
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  background: var(--paper-soft); border: 1px solid var(--line);
  border-radius: var(--r-sm); color: var(--ink-soft);
  cursor: pointer; transition: var(--transition-base);
}
.theme-toggle:hover { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
/* PR KC — visible keyboard focus on the primary nav controls + CTAs/buttons
   that previously relied on the UA default outline (low-contrast on the
   filled/gradient buttons). Outline is forced-colors/HCM-safe. */
.nav-link:focus-visible,
.nav-cta:focus-visible,
.mega-trigger:focus-visible,
.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.plan-cta:focus-visible,
.feature-block-link:focus-visible,
.theme-toggle:focus-visible,
.nav-hamburger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.theme-toggle .icon-sun  { display: none; }
[data-theme="dark"] .theme-toggle .icon-sun  { display: inline-block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* ============ Mega-menu (PR FM) ============
   Each `.mega` wraps a trigger + an absolutely-positioned panel. The
   panel is hidden via `[hidden]` until JS removes the attribute on
   hover/click. Explicit `.mega-panel[hidden] { display: none }` rule
   below is mandatory — without it the UA stylesheet's
   `[hidden] { display: none }` ties on specificity with the author
   `display: grid` rule, source order wins, and the panel renders
   open on every page load (CLAUDE.md §5.7).
============================================== */
.mega { position: relative; display: inline-flex; }

.mega-trigger {
  /* Inherit .nav-link visual, but it's a <button> so reset some defaults. */
  display: inline-flex; align-items: center; gap: 4px;
  background: transparent; border: none; cursor: pointer;
  font-family: inherit;
}
.mega-trigger[aria-expanded="true"] {
  color: var(--accent); background: var(--accent-soft);
}
.mega-caret {
  width: 11px; height: 11px;
  transition: transform var(--dur);
  opacity: 0.7;
}
.mega-trigger[aria-expanded="true"] .mega-caret {
  transform: rotate(180deg);
  opacity: 1;
}

/* Panel — anchored to its `.mega` parent. Width auto-sizes to fit
   content up to a sensible max so a single trigger doesn't blow up
   to viewport width on a 5-item product menu. */
.mega-panel {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  min-width: 320px;
  max-width: 460px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md, 10px);
  box-shadow: 0 14px 40px rgba(11, 18, 32, 0.12);
  padding: 10px;
  display: flex; flex-direction: column; gap: 2px;
  z-index: 60;  /* above sticky nav children, below modals */
  animation: mega-panel-in 140ms ease-out;
}

/* Hover-bridge — the 10px visual gap between trigger and panel used
   to break the hover chain: cursor crossing the gap fired
   `mouseleave` on .mega and closed the panel before the user could
   reach an item. This transparent ::before extends the panel's
   hit-target up to the trigger, eliminating the dead zone without
   changing the visual. */
.mega-panel::before {
  content: "";
  position: absolute;
  top: -12px;  /* slightly more than the 10px visual gap */
  left: 0;
  right: 0;
  height: 12px;
}
[data-theme="dark"] .mega-panel {
  background: var(--paper);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
}

/* The §5.7 override — specificity (0,2,0) beats UA [hidden] (0,1,0). */
.mega-panel[hidden] { display: none; }

@keyframes mega-panel-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.mega-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; border-radius: 8px;
  text-decoration: none; color: var(--ink);
  transition: background var(--dur);
  cursor: pointer;
}
.mega-item:hover, .mega-item:focus-visible {
  background: var(--paper-soft);
  outline: none;
}
.mega-item:focus-visible {
  box-shadow: 0 0 0 2px var(--accent);
}
.mega-item-icon {
  width: 18px; height: 18px;
  flex-shrink: 0; margin-top: 2px;
  color: var(--accent);
}
.mega-item-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mega-item-title {
  font-size: 13.5px; font-weight: 600; color: var(--ink);
  line-height: 1.3;
}
.mega-item-desc {
  font-size: 12px; color: var(--ink-muted);
  line-height: 1.4;
}

/* ============ Hamburger + mobile drawer (PR FM) ============ */
.nav-hamburger {
  display: none;  /* shown only on narrow viewports below */
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  width: 40px; height: 40px;
  flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
  cursor: pointer;
  padding: 0;
  transition: var(--transition-base);
}
.nav-hamburger:hover {
  background: var(--accent-soft); border-color: var(--accent);
}
.hamburger-bar {
  display: block;
  width: 18px; height: 2px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform var(--dur), opacity var(--dur);
}
/* Open state: morph into an X. JS toggles aria-expanded. */
.nav-hamburger[aria-expanded="true"] .hamburger-bar:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}
.nav-hamburger[aria-expanded="true"] .hamburger-bar:nth-child(2) {
  opacity: 0;
}
.nav-hamburger[aria-expanded="true"] .hamburger-bar:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

.mobile-drawer {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: var(--paper);
  z-index: 100;  /* above sticky nav */
  overflow-y: auto;
  padding: 80px 20px 32px;  /* leave room for fixed nav at top */
  animation: drawer-in 200ms ease-out;
}
[data-theme="dark"] .mobile-drawer { background: var(--paper); }
.mobile-drawer[hidden] { display: none; }  /* §5.7 override */

@keyframes drawer-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.mobile-drawer-inner {
  max-width: 600px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 8px;
}
.md-section {
  border-bottom: 1px solid var(--line);
  padding: 4px 0 12px;
}
.md-section:last-of-type { border-bottom: none; }
.md-section-title {
  cursor: pointer; list-style: none;
  padding: 14px 4px;
  font-size: 15.5px; font-weight: 700; color: var(--ink);
  font-family: 'Noto Serif Georgian', serif;
  display: flex; justify-content: space-between; align-items: center;
}
.md-section-title::-webkit-details-marker { display: none; }
.md-section-title::after {
  content: "+";
  font-size: 20px; color: var(--ink-muted);
  font-weight: 300; line-height: 1;
  transition: transform var(--dur);
}
.md-section[open] .md-section-title::after { content: "−"; }

.md-item {
  display: block;
  padding: 11px 8px;
  font-size: 14px;
  color: var(--ink-soft);
  text-decoration: none;
  border-radius: 6px;
  transition: background var(--dur);
}
.md-item:hover, .md-item:focus-visible {
  background: var(--paper-soft);
  color: var(--accent);
  outline: none;
}
.md-item-top {
  margin-top: 6px;
  font-weight: 600;
  font-size: 15px;
  color: var(--ink);
}
.md-cta {
  display: block;
  margin-top: 16px;
  padding: 14px 20px;
  text-align: center;
  font-size: 15px; font-weight: 700;
  background: linear-gradient(180deg, var(--accent), var(--accent-hover));
  color: white;
  border-radius: var(--r-sm);
  text-decoration: none;
  box-shadow: var(--shadow-sm), inset 0 1px 0 rgba(255,255,255,0.15);
}
[data-theme="dark"] .md-cta { color: #0B1220; }

/* Body scroll-lock when drawer is open — JS adds `.nav-drawer-open`. */
body.nav-drawer-open { overflow: hidden; }

/* ============ Mobile breakpoint ============
   PR VB — deleted. This unscoped copy said 900px while the rule that
   actually governs the header (#siteNav-scoped, static/public-chrome.css)
   moved to 1360px, so it was a second and wrong source of truth for the
   site's highest-traffic public page. It never won the cascade — (1,1,0)
   beats (0,1,0), and public-chrome.css loads later — so removing it is a
   no-op; tests/test_public_chrome_vb.py pins that neither stylesheet may
   grow a 900px nav breakpoint again. The base .nav-hamburger
   { display: none } above stays: the scoped rule turns it on. */

@media (max-width: 640px) {
  .nav { padding: 12px 16px; }
  .nav.is-scrolled { padding: 8px 16px; }
  .brand-tag { display: none; }
}

/* Reduced-motion users get instant state changes — no slide-in. */
@media (prefers-reduced-motion: reduce) {
  .mega-panel, .mobile-drawer { animation: none; }
  .mega-caret, .nav, .hamburger-bar { transition: none; }
}

/* ============ Hero ============ */
.hero {
  position: relative;
  overflow: hidden;
  padding: 80px 28px 70px;
  text-align: center;
  background: var(--bg);
  background-image:
    radial-gradient(circle at 50% 0%, rgba(30, 64, 175, 0.10), transparent 60%),
    radial-gradient(circle at 0% 100%, rgba(11, 37, 69, 0.05), transparent 50%),
    radial-gradient(circle at 100% 100%, rgba(30, 64, 175, 0.06), transparent 50%);
}
[data-theme="dark"] .hero {
  background-image:
    radial-gradient(circle at 50% 0%, rgba(96, 165, 250, 0.13), transparent 60%),
    radial-gradient(circle at 0% 100%, rgba(30, 64, 175, 0.08), transparent 50%),
    radial-gradient(circle at 100% 100%, rgba(96, 165, 250, 0.08), transparent 50%);
}
/* PR SQ — "Control Room" backdrop. Layer 2: blueprint grid, masked so
   it dissolves before the fold (procurement schematic, not graph
   paper). Layer 3: SVG feTurbulence noise (data: URI — CSP img-src
   allows data:) kills flat-gradient banding. Browsers without
   color-mix simply skip the grid — graceful. */
.hero::before {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, color-mix(in srgb, var(--accent) 7%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--accent) 7%, transparent) 1px, transparent 1px);
  background-size: 48px 48px;
  -webkit-mask-image: radial-gradient(ellipse 85% 75% at 50% 0%, #000 25%, transparent 72%);
  mask-image: radial-gradient(ellipse 85% 75% at 50% 0%, #000 25%, transparent 72%);
}
[data-theme="dark"] .hero::before {
  background-image:
    linear-gradient(to right, color-mix(in srgb, var(--accent) 9%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--accent) 9%, transparent) 1px, transparent 1px);
}
.hero::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.025;
  mix-blend-mode: overlay;
}
[data-theme="dark"] .hero::after { opacity: 0.04; }
/* Content above the backdrop layers. */
.hero > * { position: relative; z-index: 1; }

.hero-kicker {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 11px; color: var(--accent);
  text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700;
  background: var(--accent-soft);
  padding: 6px 14px; border-radius: 100px;
  margin-bottom: 24px;
}
.hero-kicker::before {
  content: ""; width: 6px; height: 6px;
  background: var(--accent); border-radius: 50%;
  animation: pulse 2s var(--ease) infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }

/* PR FI-2 CR-accept (Gemini): merged with the previously-duplicate
   `.hero h1` block in the FI-2 footer section. Now consumes FI-1
   type-scale primitives directly here instead of relying on
   cascade order from a second declaration further down. */
.hero h1 {
  font-family: var(--display-font);
  font-size: var(--text-h1);
  font-weight: 800;
  line-height: var(--line-height-display);
  letter-spacing: var(--tracking-display);
  max-width: 920px; margin: 0 auto 20px;
  color: var(--ink);
}
/* PR SQ — marker-underline sweeps in under the <em> at the end of the
   hero load choreography (see the motion section at the bottom). */
.hero h1 em {
  font-style: normal; color: var(--accent);
  position: relative; display: inline-block;
}
.hero h1 em::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0.04em;
  height: 0.14em; border-radius: 3px;
  background: var(--accent-soft);
  z-index: -1;
  transform: scaleX(0); transform-origin: left;
  animation: sq-underline 600ms var(--ease-out) 900ms both;
}
[data-theme="dark"] .hero h1 em::after {
  background: color-mix(in srgb, var(--accent) 30%, transparent);
}

.hero p {
  font-size: clamp(15px, 1.5vw, 19px);
  color: var(--ink-soft);
  max-width: 660px; margin: 0 auto 36px;
  line-height: 1.6;
}

.hero-ctas {
  display: flex; gap: 12px; justify-content: center; align-items: center;
  flex-wrap: wrap; margin-bottom: 40px;
}
.btn-primary, .btn-secondary {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 14px 26px; border-radius: var(--r-md);
  font-size: 15px; font-weight: 700; letter-spacing: 0.01em;
  border: none; cursor: pointer;
  transition: var(--transition-base);
  font-family: inherit;
}
.btn-primary {
  background: linear-gradient(180deg, var(--accent), var(--accent-hover));
  color: white;
  box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255, 255, 255, 0.15);
}
[data-theme="dark"] .btn-primary { color: #0B1220; }
.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, 0.15);
}
.btn-secondary {
  background: var(--paper); color: var(--ink); border: 1px solid var(--line);
}
.btn-secondary:hover {
  border-color: var(--accent); color: var(--accent); transform: translateY(-2px);
}

.hero-stats {
  display: flex; gap: 28px; justify-content: center; align-items: center;
  flex-wrap: wrap; margin-top: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px; color: var(--ink-muted);
}
.hero-stats .stat strong {
  display: block; font-size: 24px; font-weight: 700;
  color: var(--accent); letter-spacing: -0.02em; line-height: 1;
}
.hero-stats .stat-divider {
  width: 1px; height: 32px; background: var(--line);
}
@media (max-width: 640px) {
  .hero-stats .stat-divider { display: none; }
}

/* ============ Hero trust strip (PR OB) ============ */
/* Anonymity + low-friction accents directly under the primary CTA. */
.hero-trust-strip {
  display: flex; flex-wrap: wrap; gap: 10px;
  justify-content: center; align-items: center;
  margin: 0 auto 28px; max-width: 760px;
}
.hts-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 14px; border-radius: 100px;
  background: var(--accent-soft); border: 1px solid var(--accent);
  color: var(--accent); font-size: 12.5px; font-weight: 600; line-height: 1;
}
.hts-chip .icon { width: 14px; height: 14px; }

/* PR OF — the .platform-stats / .ps-* block (landing user-activity stats:
   tenders/exports/users/hours-saved) was removed from landing.html; its rules
   are deleted here so no orphaned CSS remains. */

/* ============ Sections ============ */
.section {
  padding: 80px 28px;
  border-top: 1px solid var(--line);
}
.section-alt {
  background: var(--paper-soft);
}
.section-narrow { max-width: 1180px; margin: 0 auto; }
.section-header { text-align: center; margin-bottom: 56px; }
.section-eyebrow {
  display: inline-block;
  font-size: var(--text-micro, 12px); font-weight: 700; letter-spacing: 0.12em;  /* PR VB — 12px floor */
  text-transform: uppercase; color: var(--accent);
  margin-bottom: 14px;
}
.section-header h2 {
  font-family: 'Noto Serif Georgian', serif;
  font-size: clamp(26px, 3.5vw, 38px);
  font-weight: 700; letter-spacing: -0.02em;
  line-height: 1.15;
  margin-bottom: 14px; max-width: 720px;
  margin-left: auto; margin-right: auto;
  color: var(--ink);
}
.section-header p {
  font-size: 16px; color: var(--ink-soft);
  max-width: 580px; margin: 0 auto; line-height: 1.55;
}

/* ============ Feature blocks (PR FN — alternating image + text) ============
   Replaced the old 3-col `.features` grid (6 small icon cards) with 5
   big 2-col blocks that alternate sides. Pattern surfaced by the
   ui-ux-pro-max skill's "Product Demo + Features" landing template —
   skill noted "embedded product demo increases engagement" (Result 6
   in the landing-domain search).

   `data-side` switches CSS grid column order so the image lands on
   left or right per block. Mobile (<800px) collapses to a single
   column with the image always rendered above the text (visual
   lead-in is stronger than text-first on narrow screens). */
.feature-blocks {
  display: flex; flex-direction: column;
  gap: 96px;
}
.feature-block {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* `start` aligns the top of the text well with the top of the
     image card. `center` (the previous value) centered each column
     within the taller one's height — visually fine when both sides
     were similar height, but when the text was much shorter than
     the mockup the eyebrow chip floated halfway down the row and
     left a big empty band above the text (reported on prod). */
  align-items: start;
  /* Was a flat 64px. Now scales 32→64px between 640px and 1280px
     viewport (5vw hits the 32px floor at 640 and the 64px cap at
     1280 — both bounds are exact, not approximate). Keeps columns
     from crowding at smaller laptop widths where the side-by-side
     layout still applies. */
  gap: clamp(32px, 5vw, 64px);
  /* PR KK follow-up (gemini #348) — the mega-menu + mobile drawer now
     deep-link to individual feature blocks (#feat-brief …). The sticky
     `.nav` header (~64px, ~52px once `.is-scrolled`) would otherwise sit
     over the eyebrow + heading when an anchor lands. Inset the scroll
     snap position so the block starts clear of the header with a little
     breathing room above the eyebrow. */
  scroll-margin-top: 88px;
}
/* Image-right (default): text in col 1, image in col 2.
   `grid-row: 1` is explicit on every child because the sparse
   auto-placement algorithm advances the cursor forward across
   column-start of a definite-column item, then bumps the row down
   when the next item's column-start is *behind* the cursor (CSS Grid
   §8.5 step 3.1.1). For data-side="left" the text (DOM-first, col 2)
   leaves the cursor at col 3, so the image (DOM-second, col 1)
   silently lands in row 2 — visually pushing the mockup card to the
   bottom of the row, with empty space above. Pinning both to row 1
   keeps the side-by-side layout identical across both sides. */
.feature-block[data-side="right"] .feature-block-text  { grid-column: 1; grid-row: 1; }
.feature-block[data-side="right"] .feature-block-image { grid-column: 2; grid-row: 1; }
/* Image-left: swap columns. */
.feature-block[data-side="left"]  .feature-block-text  { grid-column: 2; grid-row: 1; }
.feature-block[data-side="left"]  .feature-block-image { grid-column: 1; grid-row: 1; }

.feature-block-eyebrow {
  display: inline-block;
  font-size: var(--text-micro, 12px); font-weight: 700;  /* PR VB — 12px floor */
  color: var(--amber);
  background: var(--amber-soft);
  padding: 5px 12px; border-radius: 100px;
  text-transform: uppercase; letter-spacing: 0.12em;
  margin-bottom: 18px;
}
.feature-block-text h3 {
  font-family: 'Noto Serif Georgian', serif;
  font-size: 26px; font-weight: 700;
  line-height: 1.25; letter-spacing: -0.01em;
  color: var(--ink);
  margin-bottom: 14px;
}
.feature-block-text > p {
  font-size: 15px; color: var(--ink-soft);
  line-height: 1.65;
  margin-bottom: 22px;
  /* skill rule: line-length 65-75 char optimum for body. */
  max-width: 65ch;
}
.feature-block-bullets {
  list-style: none; padding: 0; margin: 0 0 26px;
  display: flex; flex-direction: column; gap: 10px;
}
.feature-block-bullets li {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 14px; color: var(--ink-soft);
  line-height: 1.55;
}
.feature-block-bullets .icon {
  width: 16px; height: 16px;
  color: var(--accent);
  margin-top: 3px; flex-shrink: 0;
}
.feature-block-link {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 14px; font-weight: 700;
  color: var(--accent);
  padding: 6px 0;
  /* PR VB — 44px tap target (was 35px). The hover underline moved from a
     border on the box (which would now float 12px under the text) to a
     text-decoration that keeps hugging the label. */
  min-height: 44px;
  text-decoration: underline; text-decoration-thickness: 2px;
  text-underline-offset: 4px; text-decoration-color: transparent;
  transition: var(--transition-base);
}
.feature-block-link:hover {
  text-decoration-color: var(--accent);
}
.feature-block-link .icon {
  transition: transform var(--dur) var(--ease);
}
.feature-block-link:hover .icon {
  transform: translateX(3px);
}

/* The image well — rounded card with subtle border + shadow. The
   inline SVG inside scales to fill. The wrapper is `aria-hidden`
   because the mockups are illustrative; the surrounding eyebrow +
   h3 + paragraph + bullets describe each feature for AT. (Note:
   aria-hidden cascades, so any role/aria-label on child SVGs would
   be ignored — we deliberately omit them.) */
.feature-block-image {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  padding: 0;
  overflow: hidden;
  transition: var(--transition-base);
}
.feature-block-image:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
  border-color: var(--accent);
}
.feature-block-image svg {
  display: block;
  width: 100%;
  height: auto;
}

/* ---- Tablet / mobile stack ----
   Lowered from 800px → 640px. The previous breakpoint was too
   eager: at common laptop widths (e.g. half-screen Brave windows
   around 720–800px) it collapsed the side-by-side layout into a
   single column, leaving the photo stacked below the text. Users
   reported this on prod; keep side-by-side until the columns are
   genuinely cramped. */
@media (max-width: 640px) {
  .feature-blocks { gap: 64px; }
  .feature-block {
    grid-template-columns: 1fr;
    gap: 28px;
  }
  /* On stacked layout the image always comes first regardless of
     `data-side` — visual lead-in is stronger than text-first.
     Attribute-presence selector matches both "left" and "right"
     with identical specificity (0,0,1,0). */
  .feature-block[data-side] .feature-block-text  { grid-column: 1; grid-row: 2; }
  .feature-block[data-side] .feature-block-image { grid-column: 1; grid-row: 1; }
  .feature-block-text h3 { font-size: 22px; }
  .feature-block-text > p { font-size: 14.5px; }
}

@media (max-width: 480px) {
  .feature-block-text h3 { font-size: 20px; }
  .feature-blocks { gap: 48px; }
}

/* Reduced-motion: kill the hover translate. */
@media (prefers-reduced-motion: reduce) {
  .feature-block-image, .feature-block-link .icon { transition: none; }
  .feature-block-image:hover { transform: none; }
  .feature-block-link:hover .icon { transform: none; }
}

/* ============ How it works ============ */
.steps {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px;
  position: relative;
}
@media (max-width: 800px) { .steps { grid-template-columns: 1fr; gap: 20px; } }
.step {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 28px 24px;
  position: relative;
}
.step-num {
  position: absolute; top: -16px; left: 24px;
  width: 36px; height: 36px;
  background: linear-gradient(135deg, var(--accent-strong), var(--accent));
  color: white;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700; font-size: 14px;
  box-shadow: var(--shadow-md);
}
[data-theme="dark"] .step-num { background: linear-gradient(135deg, #1E3A8A, #3B82F6); }
.step h3 {
  font-family: 'Noto Sans Georgian', sans-serif;
  font-size: 16px; font-weight: 700;
  margin: 14px 0 8px; color: var(--ink);
}
.step p { font-size: 13.5px; color: var(--ink-soft); line-height: 1.55; }

/* ============ Pricing ============ */
.pricing {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 20px; max-width: 1100px; margin: 0 auto;
}
@media (max-width: 900px) { .pricing { grid-template-columns: 1fr; max-width: 480px; } }
.plan {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 32px 28px;
  display: flex; flex-direction: column;
  position: relative;
  transition: var(--transition-base);
}
.plan.featured {
  border-color: var(--accent);
  border-width: 2px;
  box-shadow: 0 0 0 4px var(--accent-soft);
  transform: scale(1.02);
}
.plan-name {
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink-muted);
  margin-bottom: 14px;
}
.plan.featured .plan-name { color: var(--accent); }
.plan-price {
  display: flex; align-items: baseline; gap: 4px;
  margin-bottom: 6px;
}
.plan-price strong {
  font-family: 'Noto Serif Georgian', serif;
  font-size: 40px; font-weight: 800; color: var(--ink);
  letter-spacing: -0.02em; line-height: 1;
}
.plan-price span { font-size: 14px; color: var(--ink-muted); }
.plan-desc { font-size: 13.5px; color: var(--ink-muted); margin-bottom: 20px; min-height: 36px; }
.plan-features {
  list-style: none; padding: 0; margin: 0 0 24px;
  flex: 1;
}
.plan-features li {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 8px 0; font-size: 14px; color: var(--ink-soft);
  border-bottom: 1px solid var(--line-soft);
}
.plan-features li:last-child { border-bottom: none; }
.plan-features li .check {
  width: 16px; height: 16px; flex-shrink: 0;
  color: var(--green); margin-top: 2px;
}
.plan-cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 20px; border-radius: var(--r-md);
  font-family: inherit; font-size: 14px; font-weight: 700;
  border: 1px solid var(--line); background: var(--paper);
  color: var(--ink-soft); cursor: pointer;
  transition: var(--transition-base);
  text-align: center;
}
.plan.featured .plan-cta {
  background: linear-gradient(180deg, var(--accent), var(--accent-hover));
  color: white; border-color: var(--accent);
  box-shadow: var(--shadow-sm), inset 0 1px 0 rgba(255, 255, 255, 0.15);
}
[data-theme="dark"] .plan.featured .plan-cta { color: #0B1220; }
.plan-cta:hover { transform: translateY(-1px); }
.plan-cta.disabled {
  background: var(--paper-soft); color: var(--ink-muted);
  cursor: not-allowed; pointer-events: none;
}
.badge-soon {
  position: absolute; top: 16px; right: 16px;
  background: var(--amber-soft); color: var(--amber);
  font-size: 10px; font-weight: 700; letter-spacing: 0.06em;
  padding: 4px 10px; border-radius: 100px;
  text-transform: uppercase;
}

/* ============ Final CTA ============ */
.final-cta {
  background: linear-gradient(135deg, var(--accent-strong) 0%, var(--accent) 100%);
  color: white;
  padding: 64px 28px;
  text-align: center;
}
[data-theme="dark"] .final-cta {
  background: linear-gradient(135deg, #1E3A8A 0%, #3B82F6 100%);
}
.final-cta h2 {
  font-family: 'Noto Serif Georgian', serif;
  font-size: clamp(24px, 3.5vw, 36px);
  font-weight: 700; letter-spacing: -0.02em;
  margin-bottom: 14px; color: white;
}
.final-cta p {
  font-size: 15px; opacity: 0.92;
  max-width: 480px; margin: 0 auto 28px;
}
.final-cta .btn-cta {
  display: inline-flex; align-items: center; gap: 10px;
  background: white; color: var(--accent-strong);
  padding: 14px 28px; border-radius: var(--r-md);
  font-weight: 700; font-size: 15px;
  box-shadow: var(--shadow-lg);
  transition: var(--transition-base);
}
.final-cta .btn-cta:hover { transform: translateY(-2px); }

/* ============ Footer ============ */
/* ============ PR FI-2 — Stripe/Linear-inspired refinement ============
 * Replaces the old single-column footer with a structured 3+1 grid
 * (brand + 3 link columns). Uses FI-1 design tokens for typography
 * scale, container width, section gap, and elevated shadow. Hero
 * typography also tightened — H1 now uses --text-h1 (clamp 36-56px)
 * + --display-font + --line-height-display + --tracking-display for
 * the Stripe/Linear "tight serif display" feel.
 *
 * Old `footer { ... }` + `footer p` + `footer a` + `footer .footer-meta`
 * rules deleted (covered by .site-footer below).
 * ============================================================ */

/* Hero H1 token routing — DEDUPED in CR-accept commit. The `.hero h1`
 * block is now declared ONCE, up at line ~205, with all properties
 * (color + em-coloring + max-width + margin + FI-1 tokens) in a
 * single rule. This dropped a duplicate selector that was relying
 * on cascade order. */

/* === Structured footer === */
.site-footer {
  background: var(--paper);
  border-top: 1px solid var(--line);
  padding: 64px 28px 28px;
  color: var(--ink-muted);
  font-size: var(--text-small);
}

/* PR FK follow-up — footer layout hardening.
 * Was: `display: grid; grid-template-columns: 1.4fr repeat(3, 1fr)`
 * with `var(--container)` + `var(--gap-block)`. Production reports
 * the footer rendering as a vertical stack on desktop. Possible
 * causes: tokens.css import failure (var() falls back to nothing
 * → max-width unset, but grid SHOULD still apply), CSS cache
 * issues, or specificity collision we can't reproduce locally.
 *
 * Fix posture: replace `display: grid` with `display: flex` +
 * `flex-wrap: wrap` so each child is its own flex item with an
 * explicit `flex-basis`. Flex is more permissive than grid when
 * any single declaration in the rule fails. Also drop var()
 * dependencies for the layout-critical properties — use literal
 * px values (with a var() fallback declared second so a working
 * tokens.css still wins via cascade). */
.footer-grid {
  max-width: 1180px;
  max-width: var(--container, 1180px);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  gap: var(--gap-block, 32px);
  align-items: flex-start;
}
.footer-brand {
  flex: 1 1 240px;
  min-width: 200px;
}
.footer-col {
  flex: 1 1 160px;
  min-width: 140px;
}

@media (max-width: 560px) {
  .footer-grid {
    flex-direction: column;
    gap: 28px;
  }
  .footer-brand,
  .footer-col {
    flex: 1 1 100%;
  }
}

.footer-brand .footer-mark {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 12px;
}
.footer-mark-logo {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  background: linear-gradient(135deg, var(--accent-strong), var(--accent));
  color: #ffffff;
  font-family: var(--mono-font);
  font-size: 12px; font-weight: 700;
  border-radius: var(--r-sm);
  letter-spacing: 0;
}
/* PR FI-2 CR-accept (Gemini): align dark-mode gradient with the
   nav `.brand-logo` (line ~118 above). In dark mode the accent-
   strong / accent tokens resolve to lighter values (#1E40AF /
   #60A5FA), which made the nav + footer logos visually divergent.
   Matching the nav's hardcoded dark gradient keeps the brand
   consistent across both surfaces. */
[data-theme="dark"] .footer-mark-logo {
  background: linear-gradient(135deg, #1E3A8A, #3B82F6);
}
.footer-mark-text {
  font-family: var(--display-font);
  font-size: 18px; font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.015em;
}
.footer-tagline {
  font-family: var(--mono-font);
  font-size: 11px;
  color: var(--ink-muted);
  margin-bottom: 14px;
  letter-spacing: 0;
}
.footer-contact {
  font-size: 13px;
  line-height: 1.7;
  color: var(--ink-soft);
}
/* PR TN — 44px tap targets (the mailto / tel / LinkedIn / Facebook links
   measured 19px). Same treatment as .footer-links a below. */
.footer-contact a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  transition: var(--transition-base);
  display: inline-block;
  padding: 8px 4px;
  min-height: 44px;
  line-height: 28px;
  vertical-align: middle;
}
.footer-contact a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.footer-col-title {
  font-family: var(--ui-font);
  font-size: var(--text-micro, 12px);  /* PR VB — 12px floor */
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  color: var(--ink-muted);
  margin-bottom: 14px;
}
.footer-links {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  /* PR TN — the rows themselves now carry the vertical rhythm (44px tap
     targets below), so the list gap shrinks from 10px. It does NOT fully
     offset them: the footer is measurably taller (landing 1214 -> 1690px at
     390px), which is the accepted cost of 44px targets on every anchor. */
  gap: 2px;
}
/* PR TN — 44px minimum tap target. The links were ~19px tall stacked
   10px apart: on a phone the whole footer was a minefield of near-misses. */
.footer-links a {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 13.5px;
  display: inline-block;
  padding: 8px 4px;
  min-height: 44px;
  line-height: 28px;
  transition: var(--transition-base);
}
.footer-links a:hover {
  color: var(--accent);
}

/* Disclaimer row — sits between the link grid and the meta row so
 * the legal warning has its own breathing space. */
.footer-disclaimer-row {
  max-width: var(--container);
  margin: 48px auto 0;
  padding-top: 24px;
  border-top: 1px solid var(--line-soft);
}
.footer-disclaimer {
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--ink-muted);
  max-width: 720px;
  margin: 0;
}
/* PR TN — 44px tap targets (both disclaimer links measured 15px). These
   two sit inside a prose paragraph, so the taller inline-block boxes do
   widen the leading of the lines that contain them — accepted as the cost
   of a reachable target, since AC-3 admits no inline exception. */
.footer-disclaimer a {
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px dotted var(--ink-faint);
  transition: var(--transition-base);
  display: inline-block;
  padding: 8px 4px;
  min-height: 44px;
  line-height: 28px;
  vertical-align: middle;
}
.footer-disclaimer a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* Meta row — monospace copyright + "Built by" attribution.
 * Stripe/Linear pattern: low chrome, tight typography, separation
 * from the grid above via a hairline. */
.footer-meta-row {
  max-width: var(--container);
  margin: 24px auto 0;
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-family: var(--mono-font);
  font-size: 11px;
  color: var(--ink-faint);
  letter-spacing: 0;
}
/* PR TN — 44px tap target (measured 15px at the 11px meta-row size). */
.footer-built-by a {
  color: var(--ink-muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: var(--transition-base);
  display: inline-block;
  padding: 8px 4px;
  min-height: 44px;
  line-height: 28px;
  vertical-align: middle;
}
.footer-built-by a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

@media (max-width: 560px) {
  .footer-meta-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
}

/* ============ end PR FI-2 ============ */


/* ============ Problem → Solution (PR LC) ============
   Replaces the removed comparison strip. A 3-card pain grid
   (clock / file / eye) sits above a highlighted solution band
   whose three cards deep-link to the matching feature blocks
   below. Reuses .section / .section-header; only these classes
   are new. */
.problem-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-bottom: 44px;
}
@media (max-width: 800px) { .problem-grid { grid-template-columns: 1fr; gap: 16px; } }

.problem-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 28px 24px;
  text-align: left;
}
.problem-card-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border-radius: var(--r-md);
  background: var(--red-soft);
  color: var(--red);
  margin-bottom: 16px;
}
.problem-card-icon .icon { width: 20px; height: 20px; }
.problem-card h3 {
  font-family: 'Noto Sans Georgian', sans-serif;
  font-size: 16px; font-weight: 700;
  color: var(--ink);
  margin-bottom: 8px; line-height: 1.3;
}
.problem-card p {
  font-size: 14px; color: var(--ink-soft); line-height: 1.55;
}

/* ============ Privacy / anonymity section (PR OB) ============ */
/* Mirrors the problem-card layout but with the accent (trust) color
   instead of red, since these are reassurances, not pain points. */
.privacy-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;
}
@media (max-width: 800px) { .privacy-grid { grid-template-columns: 1fr; gap: 16px; } }
.privacy-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 28px 24px;
  text-align: left;
}
.privacy-card-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border-radius: var(--r-md);
  background: var(--accent-soft);
  color: var(--accent);
  margin-bottom: 16px;
}
.privacy-card-icon .icon { width: 20px; height: 20px; }
.privacy-card h3 {
  font-family: 'Noto Sans Georgian', sans-serif;
  font-size: 16px; font-weight: 700;
  color: var(--ink);
  margin-bottom: 8px; line-height: 1.3;
}
.privacy-card p {
  font-size: 14px; color: var(--ink-soft); line-height: 1.55;
}
.privacy-card p a { color: var(--accent); text-decoration: none; font-weight: 600; }
.privacy-card p a:hover { text-decoration: underline; }
/* PR OB review (CodeRabbit): keyboard users get the same affordance as
   hover. Matches the house focus ring (outline 2px accent + offset). */
.privacy-card p a:focus-visible {
  text-decoration: underline;
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.problem-solution {
  border: 1px solid var(--accent);
  background: linear-gradient(135deg, var(--accent-soft), transparent);
  border-radius: var(--r-lg);
  padding: 28px 24px;
}
.problem-solution-title {
  font-family: 'Noto Serif Georgian', serif;
  font-size: clamp(18px, 2.2vw, 22px); font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-align: center;
  margin-bottom: 22px;
}
.problem-solve-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px;
}
@media (max-width: 800px) { .problem-solve-grid { grid-template-columns: 1fr; } }
.problem-solve {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 16px;
  border-radius: var(--r-md);
  background: var(--paper);
  border: 1px solid var(--line);
  text-decoration: none; color: inherit;
  transition: var(--transition-base);
}
.problem-solve:hover { transform: translateY(-2px); border-color: var(--accent); }
.problem-solve .icon {
  width: 20px; height: 20px; flex-shrink: 0; margin-top: 2px;
  color: var(--accent);
}
.problem-solve-text strong {
  display: block;
  font-size: 14px; font-weight: 700; color: var(--ink);
  margin-bottom: 4px;
}
.problem-solve-text span {
  font-size: 13px; color: var(--ink-muted); line-height: 1.5;
}
@media (prefers-reduced-motion: reduce) {
  .problem-solve:hover { transform: none; }
}


/* ============ FAQ accordion (PR FO) ============
   Native <details><summary> — zero JS. Each .faq-item carries the
   open/closed state in its `open` attribute, with `<summary>` as
   the toggle. Chevron rotates 180° via CSS when [open] is set. */
.faq-section {
  background: var(--paper);
}

.faq-list {
  display: flex; flex-direction: column;
  gap: 12px;
  max-width: 820px;
  margin: 24px auto 0;
}

.faq-item {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--paper-soft);
  transition: var(--transition-base);
}
.faq-item[open] {
  border-color: var(--accent);
  background: var(--paper);
  box-shadow: var(--shadow-sm);
}

.faq-summary {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px;
  padding: 18px 22px;
  cursor: pointer;
  list-style: none;
  font-family: 'Noto Sans Georgian', sans-serif;
  font-size: 15px; font-weight: 600;
  color: var(--ink);
  line-height: 1.4;
}
.faq-summary::-webkit-details-marker { display: none; }
.faq-summary:hover { color: var(--accent); }
.faq-summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-md);
}

.faq-summary-text { flex: 1; }

.faq-chevron {
  width: 16px; height: 16px;
  color: var(--ink-muted);
  flex-shrink: 0;
  transition: transform var(--dur) var(--ease);
}
.faq-item[open] .faq-chevron {
  transform: rotate(180deg);
  color: var(--accent);
}

.faq-body {
  padding: 0 22px 20px;
  font-size: 14.5px;
  color: var(--ink-soft);
  line-height: 1.65;
}
.faq-body p { margin: 0; max-width: 68ch; }
.faq-body a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.faq-body a:hover {
  text-decoration-thickness: 2px;
}

/* Reduced-motion: kill the chevron rotation animation. */
@media (prefers-reduced-motion: reduce) {
  .faq-chevron { transition: none; }
}

/* Mobile FAQ tightening. */
@media (max-width: 600px) {
  .faq-summary { padding: 16px; font-size: 14px; }
  .faq-body { padding: 0 16px 16px; font-size: 13.5px; }
}

/* ============ PR SQ — "Control Room" motion system ============
 *
 * Three layers, all gated so content is NEVER trapped hidden:
 *  1. Hero load choreography — pure CSS `animation … both` (no JS
 *     dependency; the global reduced-motion kill at the top of this
 *     file snaps it to end-state).
 *  2. Scroll reveals — hidden pre-states apply ONLY under
 *     `html.js-reveal` (added by static/landing-motion.js) AND
 *     `prefers-reduced-motion: no-preference`. No JS → static page.
 *  3. Mockup boot-up demos — sequenced SVG keyframes fired by the
 *     `.demo` class landing on .feature-block-image.
 * Keyframes are prefixed sq- ; animated SVG node classes lm[bacwe]-*.
 * transform/opacity only (compositor-friendly); no `transition: all`.
 */

@keyframes sq-hero-in { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: translateY(0); } }
/* PR TN — transform-only twin of sq-hero-in for the LCP text (h1, lede,
 * CTAs). sq-hero-in starts at `opacity: 0`, and because the choreography
 * is pure CSS (NOT gated on html.js-reveal) the hero H1 — the LCP
 * element — was invisible for its 90ms delay + 650ms fade on every load,
 * JS or no JS. Keeping opacity at 1 throughout means the text paints on
 * the first frame (so it counts as LCP immediately) while the 18px rise
 * preserves the load rhythm. */
@keyframes sq-hero-rise { from { transform: translateY(18px); } to { transform: translateY(0); } }
@keyframes sq-underline { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes sq-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes sq-stamp {
  0% { opacity: 0; transform: scale(1.45) rotate(-3deg); }
  60% { opacity: 1; }
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
}
@keyframes sq-pop { from { opacity: 0; transform: scale(0.6); } to { opacity: 1; transform: scale(1); } }
@keyframes sq-slide { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: translateX(0); } }
@keyframes sq-grow { from { opacity: 0; transform: scaleY(0.05); } to { opacity: 1; transform: scaleY(1); } }
@keyframes sq-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes sq-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes sq-sweep {
  0% { transform: translateX(0); opacity: 0; }
  15% { opacity: 0.08; }
  85% { opacity: 0.08; }
  100% { transform: translateX(440px); opacity: 0; }
}
@keyframes sq-ping { 0%, 8%, 100% { transform: scale(1); } 4% { transform: scale(1.08); } }
@keyframes sq-sheen { to { transform: translateX(220%) skewX(-18deg); } }

@media (prefers-reduced-motion: no-preference) {
  /* ---- 1. Hero load choreography (kicker → h1 → p → CTAs →
     trust strip → stats; 90ms rhythm, uniform 18px rise). ----
     PR TN: the h1 / lede / CTAs use the transform-only sq-hero-rise so
     they are opaque on the first painted frame — the H1 is the LCP
     element and the fade delayed it by up to 740ms. The decorative
     kicker / trust strip / stats keep the opacity fade. */
  .hero-kicker      { animation: sq-hero-in   650ms var(--ease-out) both; }
  .hero h1          { animation: sq-hero-rise 650ms var(--ease-out)  90ms both; }
  .hero > p         { animation: sq-hero-rise 650ms var(--ease-out) 180ms both; }
  .hero-ctas        { animation: sq-hero-rise 650ms var(--ease-out) 270ms both; }
  .hero-trust-strip { animation: sq-hero-in   650ms var(--ease-out) 350ms both; }
  .hero-stats       { animation: sq-hero-in   650ms var(--ease-out) 430ms both; }

  /* ---- 2. Scroll reveals (one-shot, staggered per container). ----
     .feature-block-text/-image and .faq-item are reveal targets by
     CLASS (not data-reveal) — their exact opening tags are pinned by
     test_landing_feature_blocks_fn / test_landing_fo_comparison_faq;
     landing-motion.js observes the same class list. */
  html.js-reveal [data-reveal],
  html.js-reveal .feature-block-text,
  html.js-reveal .feature-block-image,
  html.js-reveal .faq-item {
    opacity: 0;
    transform: translateY(20px);
    /* Keeps matching after .in lands (no :not(.in) — the stagger
       delays must be present the moment .in flips), so it REPLACES
       --transition-base: carry the base border-color/box-shadow/color
       pairs along or card hovers snap instead of easing. */
    transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out),
                border-color var(--dur, 180ms) var(--ease, ease),
                box-shadow var(--dur, 180ms) var(--ease, ease),
                color var(--dur, 180ms) var(--ease, ease);
  }
  /* Feature blocks slide in from their own side; image trails 100ms. */
  html.js-reveal .feature-block[data-side="right"] .feature-block-text  { transform: translate(-24px, 12px); }
  html.js-reveal .feature-block[data-side="right"] .feature-block-image { transform: translate(24px, 12px); transition-delay: 100ms; }
  html.js-reveal .feature-block[data-side="left"] .feature-block-text   { transform: translate(24px, 12px); }
  html.js-reveal .feature-block[data-side="left"] .feature-block-image  { transform: translate(-24px, 12px); transition-delay: 100ms; }
  /* Featured plan drops from higher — emphasis — and must KEEP its
     scale(1.02) at rest (base .plan.featured rule above). */
  html.js-reveal .plan.featured[data-reveal] { transform: translateY(28px) scale(1.02); }

  /* Sibling stagger inside grids. */
  html.js-reveal .problem-grid       [data-reveal]:nth-child(2) { transition-delay: 80ms; }
  html.js-reveal .problem-grid       [data-reveal]:nth-child(3) { transition-delay: 160ms; }
  html.js-reveal .problem-solve-grid [data-reveal]:nth-child(2) { transition-delay: 60ms; }
  html.js-reveal .problem-solve-grid [data-reveal]:nth-child(3) { transition-delay: 120ms; }
  html.js-reveal .problem-solve-grid [data-reveal]:nth-child(4) { transition-delay: 180ms; }
  html.js-reveal .privacy-grid       [data-reveal]:nth-child(2) { transition-delay: 80ms; }
  html.js-reveal .privacy-grid       [data-reveal]:nth-child(3) { transition-delay: 160ms; }
  html.js-reveal .steps              [data-reveal]:nth-child(2) { transition-delay: 100ms; }
  html.js-reveal .steps              [data-reveal]:nth-child(3) { transition-delay: 200ms; }
  html.js-reveal .pricing            [data-reveal]:nth-child(2) { transition-delay: 90ms; }
  html.js-reveal .pricing            [data-reveal]:nth-child(3) { transition-delay: 180ms; }
  html.js-reveal .faq-list           .faq-item:nth-child(2) { transition-delay: 50ms; }
  html.js-reveal .faq-list           .faq-item:nth-child(3) { transition-delay: 100ms; }
  html.js-reveal .faq-list           .faq-item:nth-child(4) { transition-delay: 150ms; }
  html.js-reveal .faq-list           .faq-item:nth-child(5) { transition-delay: 200ms; }

  /* End states — placed after (and outspecifying) every initial rule. */
  html.js-reveal [data-reveal].in,
  html.js-reveal .feature-block-text.in,
  html.js-reveal .feature-block-image.in,
  html.js-reveal .faq-item.in { opacity: 1; transform: none; }
  html.js-reveal .feature-block[data-side] :is(.feature-block-text, .feature-block-image).in { transform: none; }
  html.js-reveal .plan.featured[data-reveal].in { transform: scale(1.02); }
  /* Reveal end-state outspecifies the base :hover rules — restate
     every hover-lift a revealed element carries. */
  html.js-reveal .feature-block[data-side] .feature-block-image.in:hover { transform: translateY(-4px) scale(1.01); }
  html.js-reveal .problem-solve[data-reveal].in:hover { transform: translateY(-2px); }
  html.js-reveal :is(.problem-card, .privacy-card)[data-reveal].in:hover { transform: translateY(-3px); }

  /* Accent lids draw across card tops as the card reveals. */
  html.js-reveal .problem-card[data-reveal]:not(.in)::before,
  html.js-reveal .privacy-card[data-reveal]:not(.in)::before { transform: scaleX(0); }
  /* Step numbers spring in after their card lands. */
  html.js-reveal .step[data-reveal]:not(.in) .step-num { transform: scale(0.5); opacity: 0; }

  /* ---- 3. Mockup boot-up demos. ----
     Waiting state: sequenced nodes hidden until `.demo` arrives. */
  html.js-reveal .feature-block-image:not(.demo) :is(.lmb-verdict, .lmb-chip, .lmb-cell, .lmb-date, .lmb-flag, .lmb-ptw, .lma-chip, .lma-row, .lmc-fresh, .lmc-tile, .lmc-bar, .lmc-donut, .lmw-bell, .lmw-row, .lmw-notif, .lme-line, .lme-cursor) { opacity: 0; }

  /* AI brief — Core 7 rises, then the verdict STAMPS, dates rule in,
     flag slides, Price-to-Win lands. */
  .feature-block-image.demo .lmb-cell { animation: sq-rise 300ms var(--ease-out) both; }
  .feature-block-image.demo g.lmb-cell:nth-of-type(4) { animation-delay: 60ms; }
  .feature-block-image.demo g.lmb-cell:nth-of-type(5) { animation-delay: 120ms; }
  .feature-block-image.demo g.lmb-cell:nth-of-type(6) { animation-delay: 180ms; }
  .feature-block-image.demo .lmb-verdict { animation: sq-stamp 380ms var(--ease-spring) 500ms both; }
  .feature-block-image.demo .lmb-chip { animation: sq-pop 250ms var(--ease-spring) 680ms both; }
  .feature-block-image.demo .lmb-date { animation: sq-rise 300ms var(--ease-out) 780ms both; }
  .feature-block-image.demo g.lmb-date:nth-of-type(8) { animation-delay: 850ms; }
  .feature-block-image.demo g.lmb-date:nth-of-type(9) { animation-delay: 920ms; }
  .feature-block-image.demo .lmb-flag { animation: sq-slide 320ms var(--ease-out) 1000ms both; }
  .feature-block-image.demo .lmb-ptw { animation: sq-rise 320ms var(--ease-out) 1120ms both; }

  /* Archive — filter chips pop, result rows pour in, a highlight
     sweep crosses the top row, one live status dot keeps pulsing. */
  .feature-block-image.demo .lma-chip { animation: sq-pop 200ms var(--ease-spring) both; }
  .feature-block-image.demo g.lma-chip:nth-of-type(2) { animation-delay: 70ms; }
  .feature-block-image.demo g.lma-chip:nth-of-type(3) { animation-delay: 140ms; }
  .feature-block-image.demo .lma-row { animation: sq-rise 250ms var(--ease-out) 250ms both; }
  .feature-block-image.demo g.lma-row:nth-of-type(5) { animation-delay: 305ms; }
  .feature-block-image.demo g.lma-row:nth-of-type(6) { animation-delay: 360ms; }
  .feature-block-image.demo g.lma-row:nth-of-type(7) { animation-delay: 415ms; }
  .feature-block-image.demo .lma-sweep { animation: sq-sweep 700ms var(--ease) 900ms 1; }
  .feature-block-image.demo .lma-live { animation: pulse 2s var(--ease) 1s infinite; }

  /* Company profile — tiles rise, the wins chart GROWS bar by bar,
     the CPV doughnut fades in last. */
  .feature-block-image.demo .lmc-fresh { animation: sq-pop 220ms var(--ease-spring) 200ms both; }
  .feature-block-image.demo .lmc-tile { animation: sq-rise 280ms var(--ease-out) both; }
  .feature-block-image.demo g.lmc-tile:nth-of-type(3) { animation-delay: 70ms; }
  .feature-block-image.demo g.lmc-tile:nth-of-type(4) { animation-delay: 140ms; }
  .feature-block-image.demo .lmc-bar { animation: sq-grow 500ms var(--ease-out) both; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(1)  { animation-delay: 300ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(2)  { animation-delay: 345ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(3)  { animation-delay: 390ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(4)  { animation-delay: 435ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(5)  { animation-delay: 480ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(6)  { animation-delay: 525ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(7)  { animation-delay: 570ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(8)  { animation-delay: 615ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(9)  { animation-delay: 660ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(10) { animation-delay: 705ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(11) { animation-delay: 750ms; }
  .feature-block-image.demo rect.lmc-bar:nth-of-type(12) { animation-delay: 795ms; }
  .feature-block-image.demo .lmc-donut { animation: sq-fade 500ms var(--ease-out) 850ms both; }

  /* Saved searches — rows slide in, "+N ახალი" pills pop AFTER rows
     settle (notifications landing), first pill re-pings every 6s. */
  .feature-block-image.demo .lmw-bell { animation: sq-pop 220ms var(--ease-spring) 100ms both; }
  .feature-block-image.demo .lmw-row { animation: sq-slide 280ms var(--ease-out) both; }
  .feature-block-image.demo g.lmw-row:nth-of-type(3) { animation-delay: 90ms; }
  .feature-block-image.demo g.lmw-row:nth-of-type(4) { animation-delay: 180ms; }
  .feature-block-image.demo .lmw-pill { animation: sq-pop 220ms var(--ease-spring) 600ms both; }
  .feature-block-image.demo g.lmw-row:nth-of-type(3) .lmw-pill { animation-delay: 720ms; }
  .feature-block-image.demo g.lmw-row:nth-of-type(4) .lmw-pill { animation-delay: 840ms; }
  .feature-block-image.demo g.lmw-row:nth-of-type(2) .lmw-pill {
    animation: sq-pop 220ms var(--ease-spring) 600ms both,
               sq-ping 6s var(--ease) 3.6s infinite;
  }
  .feature-block-image.demo .lmw-notif { animation: sq-rise 300ms var(--ease-out) 1000ms both; }

  /* Export — terminal lines TYPE in sequence (instant-on, real
     terminals don't fade), cursor blinks forever, status dot pulses. */
  .feature-block-image.demo .lme-line { animation: sq-fade 120ms linear 200ms both; }
  .feature-block-image.demo text.lme-line:nth-of-type(2) { animation-delay: 520ms; }
  .feature-block-image.demo text.lme-line:nth-of-type(3) { animation-delay: 840ms; }
  .feature-block-image.demo text.lme-line:nth-of-type(4) { animation-delay: 1160ms; }
  .feature-block-image.demo text.lme-line:nth-of-type(5) { animation-delay: 1480ms; }
  .feature-block-image.demo text.lme-line:nth-of-type(6) { animation-delay: 1800ms; }
  .feature-block-image.demo text.lme-line:nth-of-type(7) { animation-delay: 2120ms; }
  .feature-block-image.demo .lme-cursor { animation: sq-fade 1ms linear 2400ms both, sq-blink 1s steps(1) 2400ms infinite; }
  .feature-block-image.demo .lme-live { animation: pulse 2s var(--ease) infinite; }
}

/* SVG transform plumbing: scale/rotate around each node's own box.
   Applied only to sq-animated classes — never to nodes carrying an
   attribute transform (e.g. the doughnut's rotate), which CSS
   animation would override. */
.lmb-verdict, .lmb-chip, .lma-chip, .lmc-fresh, .lmw-bell, .lmw-pill {
  transform-box: fill-box; transform-origin: center;
}
.lmc-bar { transform-box: fill-box; transform-origin: center bottom; }

/* ---- Card treatment upgrades (static, motion-independent). ---- */
.problem-card, .privacy-card { position: relative; transition: var(--transition-base); }
.problem-card::before, .privacy-card::before {
  content: "";
  position: absolute; top: 0; left: 14px; right: 14px; height: 2px;
  border-radius: 0 0 2px 2px;
  transform-origin: left;
  transition: transform 400ms var(--ease-out) 200ms;
}
.problem-card::before { background: var(--amber); }
.privacy-card::before { background: var(--green); }
.problem-card:hover, .privacy-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: var(--accent);
}
.step-num {
  transition: transform 350ms var(--ease-spring) 250ms,
              opacity 250ms var(--ease-out) 250ms;
}
[data-theme="dark"] .plan.featured {
  box-shadow: 0 0 0 4px var(--accent-soft),
              0 0 40px -12px color-mix(in srgb, var(--accent) 35%, transparent);
}

/* ---- Hero CTA polish. ---- */
.hero-stats .stat strong { font-variant-numeric: tabular-nums; }
.hero .btn-primary {
  box-shadow: var(--shadow-md),
              0 4px 14px -4px color-mix(in srgb, var(--accent) 45%, transparent),
              inset 0 1px 0 rgba(255, 255, 255, 0.15);
}
.btn-primary { position: relative; overflow: hidden; }
.btn-primary::before {
  content: "";
  position: absolute; inset: 0;
  transform: translateX(-120%) skewX(-18deg);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.18), transparent);
  pointer-events: none;
}
@media (hover: hover) {
  .btn-primary:hover::before { animation: sq-sheen 600ms var(--ease) forwards; }
}
.btn-primary:active, .btn-secondary:active, .plan-cta:active, .final-cta .btn-cta:active {
  transform: translateY(0) scale(0.98);
}

/* ---- Section rhythm: the feature blocks hang off a faint spine;
   the final CTA bookends the hero's blueprint grid. ---- */
@media (min-width: 960px) {
  .feature-blocks {
    background: linear-gradient(to bottom, var(--line-soft), transparent) 50% 0 / 1px 100% no-repeat;
  }
}
.final-cta { position: relative; overflow: hidden; }
.final-cta::before {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 48px 48px;
  -webkit-mask-image: radial-gradient(ellipse 80% 90% at 50% 50%, #000 30%, transparent 75%);
  mask-image: radial-gradient(ellipse 80% 90% at 50% 50%, #000 30%, transparent 75%);
}
.final-cta > * { position: relative; z-index: 1; }

/* ---- Reduced motion: static end-states, zero sequencing. The
   hidden pre-states above only exist under `no-preference`, so
   nothing here can be trapped invisible; this block additionally
   pins decorative loops and the hero underline to their finished
   look. (.feature-block hover rules: see the PR FN block above.) ---- */
@media (prefers-reduced-motion: reduce) {
  .hero h1 em::after { animation: none; transform: scaleX(1); }
  .lma-live, .lme-live, .lme-cursor { animation: none; }
  .problem-card:hover, .privacy-card:hover { transform: none; }
  .problem-card::before, .privacy-card::before, .step-num { transition: none; }
  .btn-primary:hover::before { animation: none; }
}
