/* CBWatch — "radar console" site-wide visual layer.
 *
 * Linked from every page (after theme.css + interface.css). It does not
 * replace either of those — theme.css still supplies the base tokens/
 * components (.panel, .btn-*, .grade-badge, .finding, modals, .site-nav
 * fallback, etc. — all still used verbatim wherever a page renders them
 * dynamically, e.g. index.html's real scan-result JS) and interface.css
 * still supplies the k-card/k-btn-primary/step-trail motion layer used
 * site-wide since the previous round. radar.css adds a deeper visual
 * language on top — an ambient animated radar/scan backdrop, a corner
 * hamburger button opening a side `.nav-panel` (shared nav component), a kinetic homepage
 * hero plus a lighter `.hero-inner` for every content page, a bento value
 * grid, and glass restyling of every existing card-like surface via the
 * `.panel`/`.k-card`/`.note-box` selectors below (those classes were
 * already used site-wide by the previous motion-layer round, so this
 * mostly "just works" without per-page markup changes to those cards).
 * No functional markup, IDs, or any page's own <script> block were
 * touched to build this.
 */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,340..900;1,9..144,340..900&display=swap');

:root {
  /* A deeper register of the same navy/teal identity as theme.css's own
     --bg/--accent (kept as the exact same hex where they overlap — --teal
     below equals theme.css's --accent). New names so nothing already using
     theme.css's tokens (the dynamically-rendered scorecard/findings) has
     to change. */
  --void: #060a13;
  --void-2: #0b1220;
  --void-3: #0e1728;
  --glass: rgba(20, 31, 51, 0.52);
  --stroke: rgba(148, 178, 222, 0.14);
  --stroke-hi: rgba(148, 178, 222, 0.28);
  /* Was #5E7093 — measured 3.76:1 against --void-2 (#0B1220), under WCAG
     AA's 4.5:1 floor for text this small (the eyebrow tags/footer link row
     site-wide, 11.5px — too small to qualify for the 3:1 "large text"
     exception). Lightened to a value in the same blue-grey family that
     clears AA with real margin (5.9:1 against #0B1220, computed via the
     WCAG relative-luminance formula) — flagged in the Sept a11y audit,
     fixed 26 Sept. */
  --ink-faint: #7B93AF;
  --teal: #4FD1C5;
  --teal-2: #8FF2E6;
  --indigo: #5B7CFA;
  --amber: #E0B84C;
  --serif: 'Fraunces', Georgia, serif;
}

@media (prefers-reduced-motion: reduce) {
  body.radar-skin * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Site-wide page-shell overrides — content needs to sit above the fixed
   radar field, and (since .brand/.nav-open-btn are both fixed-position
   corner pills, not part of the document flow the way the old .nav-dock
   sticky bar was) padding-top here is what clears them instead. A static
   value is enough: unlike the old sticky nav-dock, these fixed pills don't
   reserve flow space that needs to shrink again on scroll — they just
   float over whatever has already scrolled past underneath. */
body.radar-skin.page-shell { padding-top: 96px; position: relative; }
body.radar-skin .wrap,
body.radar-skin footer { position: relative; z-index: 1; }

body.radar-skin .wrap-hero { max-width: 1120px; }

body.radar-skin em {
  font-style: italic;
  font-weight: 400;
  background: linear-gradient(100deg, var(--teal-2), var(--teal) 60%, var(--indigo));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  background-size: 200% 100%;
  /* Continuous gradient-shift animation (em-shift) removed on request
     (25 Sept, laptop-lag fix) — gradient text still renders, just static. */
}

/* -------------------------------------------------------------------------
   Film grain + cursor glow orb
------------------------------------------------------------------------- */
/* This is almost certainly the single biggest lag contributor on the site:
   a FULL-VIEWPORT fixed layer, on every page, sitting near the top of the
   stacking order, using mix-blend-mode (which forces the browser to keep
   recompositing it against whatever's rendered beneath it — one of the
   more expensive things a browser can be asked to do continuously) — and
   it was animating its position 4 times a second, forever, via a real
   Chrome performance trace confirming "Rendering" (style recalc + layout)
   as the dominant main-thread cost. transform is normally compositor-only
   and cheap to animate, but combined with mix-blend-mode on a layer this
   large, forcing a re-blend every ~125ms adds up across every single page
   view. Film grain reads the same to the eye whether it's crawling or
   static — removed the animation entirely rather than just throttling it,
   since a static grain texture costs nothing after its first paint. */
.grain {
  position: fixed; inset: -40px; z-index: 80; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.05; mix-blend-mode: overlay;
}

.orb {
  position: fixed; top: 0; left: 0; width: 420px; height: 420px; border-radius: 50%;
  background: radial-gradient(circle, rgba(79, 209, 197, 0.16), transparent 70%);
  pointer-events: none; z-index: 1; opacity: 0; transition: opacity 0.4s;
  transform: translate(-50%, -50%); will-change: transform;
}
.orb.on { opacity: 1; }
@media (hover: none) { .orb { display: none; } }

/* -------------------------------------------------------------------------
   Ambient radar field (fixed backdrop, behind everything)
------------------------------------------------------------------------- */
.radar-field { position: fixed; inset: 0; z-index: 0; overflow: hidden; background: var(--void); }
.aurora { position: absolute; border-radius: 50%; filter: blur(90px); opacity: 0.5; will-change: transform; }
.aurora.a { width: 60vw; height: 60vw; left: -18vw; top: -22vw; background: radial-gradient(circle, rgba(79, 209, 197, 0.35), transparent 65%); }
.aurora.b { width: 50vw; height: 50vw; right: -16vw; top: 6vw; background: radial-gradient(circle, rgba(91, 124, 250, 0.30), transparent 65%); }
.vignette { position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 0%, transparent 40%, var(--void) 92%); }
#radar { position: absolute; inset: 0; width: 100%; height: 100%; }

/* -------------------------------------------------------------------------
   Nav — was a floating glass pill with inline links; replaced (25 Sept)
   after adding the Newsletter link made that bar wrap awkwardly at some
   widths (9 links + a CTA no longer reliably fit on one line, and the
   old mobile-only collapse didn't kick in until 760px). Now it's just a
   single hamburger button (top-right, mirrors .brand's glass-pill styling
   top-left) that opens a right-hand side panel — see .nav-panel below,
   styled to match the dashboard's .sidebar/.nav-link (same mono font,
   glass panel, hover/active colours) per Connor's ask that logged-out and
   logged-in navigation look like the same product. A single button can't
   wrap regardless of viewport width, so this also just structurally can't
   have the old bug again.
------------------------------------------------------------------------- */
.nav-open-btn {
  position: fixed; top: 18px; right: 24px; z-index: 41;
  width: 50px; height: 50px; border-radius: 999px; border: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  background: var(--glass); border: 1px solid var(--stroke); cursor: pointer;
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.6);
  transition: background 0.3s, box-shadow 0.3s, border-color 0.3s, top 0.25s cubic-bezier(.22,1,.36,1), width 0.25s cubic-bezier(.22,1,.36,1), height 0.25s cubic-bezier(.22,1,.36,1);
}
.nav-open-btn span { width: 17px; height: 1.5px; background: var(--ink-dim); transition: transform 0.2s, opacity 0.2s; }
/* Same shrink-on-scroll treatment as .brand.scrolled, toggled by the same
   radar.js scroll listener/threshold so the two fixed corner pills stay
   visually paired at every scroll position. */
.nav-open-btn.scrolled { top: 10px; width: 40px; height: 40px; }
@media (max-width: 760px) {
  .nav-open-btn { top: 14px; right: 16px; width: 44px; height: 44px; }
  .nav-open-btn.scrolled { top: 8px; right: 12px; width: 38px; height: 38px; }
}
.nav-open-btn.menu-open span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.nav-open-btn.menu-open span:nth-child(2) { opacity: 0; }
.nav-open-btn.menu-open span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }
.brand {
  position: fixed;
  top: 18px;
  left: 24px;
  z-index: 41;
  display: flex; align-items: center; gap: 11px;
  font-family: var(--mono); font-weight: 700; font-size: 21px; letter-spacing: 0.02em;
  text-decoration: none; color: var(--ink);
  padding: 13px 22px;
  border-radius: 999px;
  background: var(--glass);
  border: 1px solid var(--stroke);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.6);
  transition: background 0.3s, box-shadow 0.3s, border-color 0.3s, top 0.25s cubic-bezier(.22,1,.36,1), padding 0.25s cubic-bezier(.22,1,.36,1), font-size 0.25s cubic-bezier(.22,1,.36,1);
}
/* Shrinks once scrolled, paired with .nav-open-btn.scrolled above — same
   scrollY threshold, toggled by radar.js, so the two fixed corner pills
   compact together instead of one staying full-size next to the other. */
.brand.scrolled { top: 10px; padding: 8px 16px; font-size: 15px; gap: 8px; }
.brand.scrolled .brand-mark { width: 14px; height: 15.5px; }
@media (max-width: 760px) { .brand.scrolled { top: 8px; left: 12px; padding: 6px 12px; font-size: 13px; gap: 6px; } }

/* Brand mark (26 Sept) — replaces the old plain glowing dot (`.blip`) with
   a small shield-check glyph that deliberately echoes the browser-tab
   favicon (also a teal shield+checkmark), so the in-page mark and the tab
   icon read as the same identity instead of two unrelated marks. Paired
   with a two-tone wordmark (bright "CB" + dimmer "WATCH") for a bit of
   typographic hierarchy instead of one flat block of bold text. Applied
   identically to the off-canvas panel's .nav-panel-brand below, just
   smaller. Connor felt the old dot+flat-text version didn't "compliment"
   the rest of the glass-panel aesthetic (25 Sept) — three options were
   mocked up and screenshotted for him (dot→shield swap only, wordmark-only
   two-tone, and this combined version); he picked the combined one. */
.brand-mark {
  width: 18px; height: 20px; flex-shrink: 0;
  color: var(--teal);
  filter: drop-shadow(0 0 5px rgba(79, 209, 197, 0.45));
}
.brand-cb { color: var(--teal-2); }
.brand-watch { color: var(--ink); font-weight: 600; }
.nav-panel-brand .brand-mark { width: 14px; height: 15.5px; }

/* .nav-panel — the off-canvas side panel .nav-open-btn opens. Deliberately
   matches webapp/static/dashboard.html's .sidebar/.nav-link almost
   property-for-property (same --mono font, same glass-panel gradient, same
   hover/active recipe) rather than inventing a second nav language — see
   the comment above .nav-open-btn for why this replaced the old pill bar. */
.nav-panel-backdrop {
  position: fixed; inset: 0; z-index: 49; background: rgba(0, 0, 0, 0.5);
  opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
}
.nav-panel-backdrop.open { opacity: 1; pointer-events: auto; }

.nav-panel {
  position: fixed; top: 0; right: 0; z-index: 50;
  width: 280px; max-width: 84vw; height: 100vh; overflow-y: auto;
  background: linear-gradient(160deg, rgba(20, 31, 51, 0.94), rgba(12, 20, 36, 0.94));
  border-left: 1px solid var(--stroke-hi);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow: -20px 0 44px rgba(0, 0, 0, 0.45);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.22s ease;
}
.nav-panel.open { transform: translateX(0); }

.nav-panel-top { display: flex; align-items: center; justify-content: space-between; padding: 20px 18px 8px; flex-shrink: 0; }
.nav-panel-brand {
  font-family: var(--mono); font-weight: 700; font-size: 16px; letter-spacing: 0.02em;
  color: var(--ink); text-decoration: none; display: flex; align-items: center; gap: 9px;
}
.nav-panel-close-btn {
  background: none; border: none; color: var(--ink-dim); font-size: 24px; line-height: 1;
  cursor: pointer; padding: 4px;
}
.nav-panel-close-btn:hover { color: var(--ink); }

.nav-panel-links { flex: 1; padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; }
.nav-link {
  display: block; padding: 10px 12px; border-radius: 8px;
  color: var(--ink-dim); text-decoration: none;
  font-family: var(--mono); font-size: 13.5px; font-weight: 500; letter-spacing: 0.02em;
  transition: background 0.12s, color 0.12s;
}
.nav-link:hover { background: rgba(255, 255, 255, 0.045); color: var(--ink); }
.nav-link.active { background: var(--accent-dim); color: var(--accent); font-weight: 600; }

.nav-panel-bottom { padding: 14px 18px 22px; border-top: 1px solid var(--panel-border); flex-shrink: 0; }
.nav-panel-bottom .nav-cta {
  display: block; text-align: center;
  font-family: var(--mono); font-size: 12.5px; font-weight: 600;
  /* Sept a11y/design audit finding #8 (26 Sept): this was a 999px full
     pill, the only fully-rounded CTA on the site — .btn (theme.css, every
     pricing/dashboard/login button), .nav-link right above in this same
     panel, and .scan-dock button below all use an 8px corner. Matched to
     8px here so the "Log in" CTA reads as the same button language as
     everywhere else instead of a one-off shape. */
  padding: 11px 18px; border-radius: 8px; text-decoration: none; color: #06231F;
  background: linear-gradient(135deg, var(--teal-2), var(--teal));
  box-shadow: 0 8px 24px -8px rgba(79, 209, 197, 0.55);
  transition: box-shadow 0.2s;
}
.nav-panel-bottom .nav-cta:hover { box-shadow: 0 10px 30px -6px rgba(79, 209, 197, 0.75); }

@media (max-width: 760px) {
  body.radar-skin.page-shell { padding-top: 78px; }
  .brand { top: 14px; left: 16px; padding: 10px 16px; font-size: 17px; gap: 8px; }
  .brand .brand-mark { width: 15px; height: 17px; }
}

/* -------------------------------------------------------------------------
   Hero
------------------------------------------------------------------------- */
.hero { position: relative; z-index: 2; padding: 56px 0 40px; }
.hero-grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 40px; align-items: center; }
@media (max-width: 900px) { .hero-grid { grid-template-columns: 1fr; gap: 30px; } }

.eyebrow {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-faint); display: flex; align-items: center; gap: 8px; margin-bottom: 18px;
}
.eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--teal); box-shadow: 0 0 10px var(--teal); }

.hero h1 {
  font-family: var(--serif); font-weight: 600; margin: 0 0 20px;
  font-size: clamp(34px, 5.4vw, 62px); line-height: 1.04; letter-spacing: -0.01em;
}
.hline { display: block; overflow: hidden; }
.hline span { display: inline-block; opacity: 0; transform: translateY(100%) rotate(2deg); filter: blur(6px); animation: hline-in 1s cubic-bezier(.22,1,.36,1) forwards; }
@keyframes hline-in { to { opacity: 1; transform: translateY(0) rotate(0); filter: blur(0); } }

.hero .lede {
  font-size: 16px; line-height: 1.65; color: var(--ink-dim); max-width: 460px; margin: 0 0 28px;
  opacity: 0; animation: fade-up 0.8s cubic-bezier(.22,1,.36,1) forwards; animation-delay: 0.55s;
}
@keyframes fade-up { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }

.scan-dock {
  display: flex; gap: 8px; padding: 8px; width: 100%; max-width: 480px;
  background: var(--glass); border: 1px solid var(--stroke); border-radius: 16px;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  position: relative; margin: 0;
  opacity: 0; animation: fade-up 0.8s cubic-bezier(.22,1,.36,1) forwards; animation-delay: 0.68s;
}
/* .scan-dock::before used to be a spinning conic-gradient border sweep
   around the scan input. Removed on request — before the spin-slow fix
   above it was effectively static (an unregistered custom property
   doesn't interpolate, so it never visibly rotated), and once fixed to
   actually rotate smoothly it read as an odd, out-of-place effect rather
   than a nice touch. Plain glass border only now. */
.scan-dock input {
  flex: 1; background: transparent; border: none; outline: none; color: var(--ink);
  font-family: var(--mono); font-size: 14.5px; padding: 12px 14px; position: relative; z-index: 1;
  min-width: 0;
}
.scan-dock input::placeholder { color: var(--ink-faint); }
/* Sept a11y audit (critical #2): .scan-dock input — the homepage's single
   most important field — had `outline: none` above with no replacement
   focus style anywhere, a WCAG 2.4.7 failure on the site's primary
   conversion element. Fixed here, plus a defensive site-wide rule right
   below covering every other `outline: none` found across the codebase
   (contact.html, dashboard.html's two text inputs, index.html, login.html)
   in one place, since radar.css loads on all of them. */
.scan-dock input:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
  border-radius: 4px;
}
body.radar-skin a:focus-visible,
body.radar-skin button:focus-visible,
body.radar-skin input:focus-visible,
body.radar-skin select:focus-visible,
body.radar-skin textarea:focus-visible,
body.radar-skin [tabindex]:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}
.scan-dock button {
  font-family: var(--sans); font-weight: 600; font-size: 14px;
  /* Same teal glow as .nav-cta below — the gradient fill was already
     identical between the two (confirmed: identical computed
     background-image), but this button had no box-shadow at all while the
     nav "Log in" pill glows, so the two read as different intensities of
     teal side by side. Added on request (25 Sept) so both CTAs feel like
     the same colour, not just the same gradient stops.
     Corner radius was 10px, .nav-cta's was 999px — Sept audit finding #8.
     Dropped to 8px (26 Sept) to match .btn/.nav-link/.nav-cta rather than
     the other way around: this button nests inside .scan-dock's 16px
     container with 8px of padding on every side, and 8px is the radius
     that actually nests cleanly there (outer 16px − 8px padding = 8px),
     so it was already the better-fitting number, not just the more
     consistent one. */
  border: none; border-radius: 8px; padding: 0 22px; cursor: pointer; color: #06231F;
  background: linear-gradient(135deg, var(--teal-2), var(--teal));
  box-shadow: 0 8px 24px -8px rgba(79, 209, 197, 0.55);
  transition: filter 0.15s, transform 0.08s, box-shadow 0.2s; will-change: transform; position: relative; z-index: 1;
}
.scan-dock button:hover:not(:disabled) { filter: brightness(1.08); box-shadow: 0 10px 30px -6px rgba(79, 209, 197, 0.75); }
.scan-dock button:disabled { opacity: 0.6; cursor: not-allowed; box-shadow: none; }

.hero .hint {
  margin-top: 12px; font-size: 11.5px; letter-spacing: 0.04em; color: var(--ink-faint); font-family: var(--mono);
  opacity: 0; animation: fade-up 0.8s cubic-bezier(.22,1,.36,1) forwards; animation-delay: 0.8s;
}
.hero .hint a { color: var(--teal-2); }

.tilt-wrap { perspective: 1200px; position: relative; }

.telemetry {
  position: relative; border-radius: 22px; padding: 26px;
  background: linear-gradient(160deg, rgba(20, 31, 51, 0.75), rgba(12, 20, 36, 0.55));
  border: 1px solid var(--stroke-hi);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  overflow: hidden; transform-style: preserve-3d;
  transition: transform 0.4s cubic-bezier(.22,1,.36,1);
  opacity: 0; animation: panel-in 0.9s cubic-bezier(.22,1,.36,1) forwards; animation-delay: 0.4s;
}
@keyframes panel-in { from { opacity: 0; transform: translateY(26px) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } }
/* .telemetry::after used to be a continuous scanline sweep (see git
   history) — removed entirely on request (25 Sept, laptop-lag fix),
   same reasoning as the film-grain removal above: it sat inside a
   backdrop-filter panel on screen almost permanently (the homepage hero
   card), so it was a genuine ongoing cost, not just a one-off. */
.telemetry-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 18px; position: relative; gap: 14px; }
.telemetry-domain { font-family: var(--mono); font-size: 12px; letter-spacing: 0.08em; color: var(--ink-dim); }
.telemetry-num {
  font-family: var(--serif); font-weight: 600; font-size: 44px; line-height: 1;
  color: var(--teal-2); text-shadow: 0 0 30px rgba(79, 209, 197, 0.5);
  /* Pulsing glow (grade-glow, infinite) removed on request (25 Sept,
     laptop-lag fix) — the glow itself stays, steady rather than pulsing. */
  display: flex; align-items: baseline; gap: 6px;
}
.telemetry-num small { font-family: var(--mono); font-size: 12px; font-weight: 500; color: var(--ink-dim); text-shadow: none; }
.telemetry-rows { display: flex; flex-direction: column; gap: 9px; position: relative; }
.trow {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  font-family: var(--mono); font-size: 12px; color: var(--ink-dim);
  padding: 8px 10px; border-radius: 9px; background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--stroke);
  opacity: 0; transform: translateX(-10px);
  animation: row-in 0.6s cubic-bezier(.22,1,.36,1) forwards;
}
.trow:nth-child(1) { animation-delay: 0.85s; } .trow:nth-child(2) { animation-delay: 0.96s; }
.trow:nth-child(3) { animation-delay: 1.07s; } .trow:nth-child(4) { animation-delay: 1.18s; }
.trow:nth-child(5) { animation-delay: 1.29s; } .trow:nth-child(6) { animation-delay: 1.40s; }
.trow:nth-child(7) { animation-delay: 1.51s; } .trow:nth-child(8) { animation-delay: 1.62s; }
.trow:nth-child(9) { animation-delay: 1.73s; }
@keyframes row-in { to { opacity: 1; transform: translateX(0); } }
.trow b { color: var(--ink); font-weight: 500; text-align: right; white-space: nowrap; }

.chip {
  position: absolute; font-family: var(--mono); font-size: 11px; font-weight: 500;
  padding: 8px 13px; border-radius: 999px;
  background: var(--glass); border: 1px solid var(--stroke-hi);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 14px 30px -14px rgba(0, 0, 0, 0.6);
  display: flex; align-items: center; gap: 7px;
  animation: chip-in 0.7s cubic-bezier(.22,1,.36,1) forwards;
  opacity: 0; z-index: 3; white-space: nowrap;
}
/* chip-in (one-time entrance) kept; drift (infinite float, ~7s loop) and
   the chip dot's blip pulse removed below on request (25 Sept,
   laptop-lag fix) — chips still fade/scale in once, then sit still. */
@keyframes chip-in { from { opacity: 0; transform: scale(0.7) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } }
.chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--teal); box-shadow: 0 0 8px var(--teal); }
.chip.c1 { top: -18px; left: -10px; animation-delay: 1.4s; }
.chip.c3 { bottom: -16px; right: 18px; animation-delay: 1.6s; }
@media (max-width: 900px) { .chip { display: none; } }

/* -------------------------------------------------------------------------
   Every existing card-like surface, site-wide. `.panel`/`.k-card` are
   already on virtually every card across the whole site (value-card,
   note-box, contact-panel, uptime-panel, plan-card, screenshot-card,
   guide-card, scorecard, finding, lead-capture, trial-popup-box, modal-box
   — all carry .k-card from the previous motion-layer round), so this one
   rule glass-skins the entire site's cards without per-page markup edits.
   `.note-box` is listed explicitly too since a few instances predate the
   k-card rollout and don't carry it.
------------------------------------------------------------------------- */
.result-zone { position: relative; z-index: 2; padding-top: 8px; }

body.radar-skin .panel,
body.radar-skin .k-card,
body.radar-skin .note-box {
  background: linear-gradient(160deg, rgba(20, 31, 51, 0.7), rgba(12, 20, 36, 0.5));
  border-color: var(--stroke-hi);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
body.radar-skin .trial-popup-box,
body.radar-skin .modal-box {
  background: linear-gradient(160deg, rgba(22, 33, 54, 0.92), rgba(12, 20, 36, 0.92));
  border-color: var(--stroke-hi);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}
body.radar-skin .step-trail { font-family: var(--mono); }

/* -------------------------------------------------------------------------
   Content-page hero — the lighter header used by every non-homepage page
   (About, Methodology, Privacy, Terms, Contact, Status, Pricing, Guides,
   guide articles). Reuses each page's existing .mark/h1/.sub markup
   unchanged (.mark already renders in the same teal as --teal via
   theme.css's --accent token, so it needs no markup change to fit) — this
   just adds spacing, stacking context above the fixed backdrop, and a
   fade-up entrance to the heading/sub.
------------------------------------------------------------------------- */
/* Top padding gives the "← CBWatch" .mark link (and its ::before dot,
   theme.css) real breathing room below the fixed .brand/.nav-open-btn
   corner pills (cleared by .page-shell's own padding-top above) instead
   of sitting right underneath them — same gap on every content page since
   they all share this one rule. */
.hero-inner { position: relative; z-index: 2; padding: 32px 0 8px; }
.hero-inner h1 {
  opacity: 0; animation: fade-up 0.8s cubic-bezier(.22,1,.36,1) forwards; animation-delay: 0.08s;
}
.hero-inner .sub {
  opacity: 0; animation: fade-up 0.8s cubic-bezier(.22,1,.36,1) forwards; animation-delay: 0.22s;
}
.hero-inner .mark {
  opacity: 0; animation: fade-up 0.6s cubic-bezier(.22,1,.36,1) forwards;
}

/* -------------------------------------------------------------------------
   Reveal-on-scroll (below-the-fold sections only — hero animates on load)
------------------------------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.8s cubic-bezier(.22,1,.36,1), transform 0.8s cubic-bezier(.22,1,.36,1); }
.reveal.in { opacity: 1; transform: translateY(0); }
.reveal-stagger .stagger-item { opacity: 0; transform: translateY(22px); transition: opacity 0.6s cubic-bezier(.22,1,.36,1), transform 0.6s cubic-bezier(.22,1,.36,1); }
.reveal-stagger.in .stagger-item { opacity: 1; transform: translateY(0); }
.stagger-item:nth-child(1) { transition-delay: 0.02s; } .stagger-item:nth-child(2) { transition-delay: 0.09s; }
.stagger-item:nth-child(3) { transition-delay: 0.16s; } .stagger-item:nth-child(4) { transition-delay: 0.23s; }

/* -------------------------------------------------------------------------
   Section shell + eyebrow heads (Why CBWatch / proof / FAQ)
------------------------------------------------------------------------- */
.rsection { position: relative; z-index: 2; padding: 64px 0; }
.rsection-head { max-width: 620px; margin-bottom: 30px; }
.rsection-head h2 { font-family: var(--serif); font-weight: 600; font-size: clamp(24px, 3.2vw, 34px); margin: 8px 0 10px; }
.rsection-head p { color: var(--ink-dim); font-size: 14.5px; line-height: 1.6; margin: 0; }

/* -------------------------------------------------------------------------
   Bento value grid ("Why CBWatch")
------------------------------------------------------------------------- */
.bento { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: auto; gap: 14px; }
.bento-card {
  border-radius: 18px; padding: 24px;
  background: linear-gradient(165deg, rgba(22, 33, 54, 0.7), rgba(13, 21, 37, 0.55));
  border: 1px solid var(--stroke);
  position: relative; overflow: hidden;
  transform-style: preserve-3d;
  transition: transform 0.35s cubic-bezier(.22,1,.36,1), border-color 0.3s, box-shadow 0.35s;
}
.bento-card:hover { border-color: var(--stroke-hi); box-shadow: 0 26px 60px -24px rgba(0, 0, 0, 0.6); }
.bento-card::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 0%), rgba(79, 209, 197, 0.14), transparent 65%);
  opacity: 0; transition: opacity 0.3s; pointer-events: none;
}
.bento-card:hover::before { opacity: 1; }
.bento-card.big {
  grid-column: span 2; grid-row: span 2; display: flex; flex-direction: column; justify-content: flex-end; min-height: 280px;
  background-image:
    radial-gradient(circle at 80% 20%, rgba(79, 209, 197, 0.16), transparent 32%),
    radial-gradient(circle at 80% 20%, transparent 12%, rgba(79, 209, 197, 0.09) 13%, transparent 14%),
    radial-gradient(circle at 80% 20%, transparent 20%, rgba(79, 209, 197, 0.07) 21%, transparent 22%),
    linear-gradient(165deg, rgba(22, 33, 54, 0.7), rgba(13, 21, 37, 0.55));
}
.bento-card h3 { font-family: var(--serif); font-weight: 600; font-size: 19px; margin: 0 0 10px; }
.bento-card p { color: var(--ink-dim); font-size: 13.5px; line-height: 1.6; margin: 0; }
/* Flags a "Why CBWatch" card as describing a paid-monitoring feature, not
   part of the free scan — added so free-tier expectations match what the
   free scan actually returns (see the P0 review item this came from). */
.bento-tag {
  display: inline-block; vertical-align: middle; margin-left: 8px; position: relative; top: -2px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--teal-2); background: rgba(79, 209, 197, 0.12); border: 1px solid rgba(79, 209, 197, 0.3);
  border-radius: 999px; padding: 3px 8px;
}
.bento-card .glyph { font-family: var(--mono); font-size: 11.5px; color: var(--teal-2); letter-spacing: 0.08em; margin-bottom: 12px; position: relative; }
@media (max-width: 820px) {
  .bento { grid-template-columns: 1fr; }
  .bento-card.big, .bento-card.wide { grid-column: span 1; grid-row: span 1; min-height: auto; }
  .bento-card { transform: none !important; }
}
@media (min-width: 821px) { .bento-card.wide { grid-column: span 2; } }

/* -------------------------------------------------------------------------
   Proof panel ("We use it on ourselves")
------------------------------------------------------------------------- */
.proof {
  max-width: 620px; margin: 0 auto; border-radius: 24px; padding: 44px;
  text-align: center; box-sizing: border-box;
  background: linear-gradient(180deg, rgba(22, 33, 54, 0.65), rgba(11, 18, 32, 0.55));
  border: 1px solid var(--stroke-hi);
  position: relative; overflow: hidden;
}
.proof-seal {
  position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 14px;
  padding: 14px 22px 14px 14px; border-radius: 16px; background: var(--void-3);
  font-family: var(--mono); margin-bottom: 20px;
  max-width: 100%; box-sizing: border-box; flex-wrap: wrap; justify-content: center;
}
.proof-seal::before {
  content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit; padding: 1px;
  background: conic-gradient(from 0deg, var(--teal), transparent 30%, transparent 70%, var(--indigo));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  /* Continuous rotation (spin-slow2, infinite) removed on request (25
     Sept, laptop-lag fix) — same treatment as .scan-dock's spin-slow
     border above (see that comment), a static gradient ring instead. */
}
.proof-seal img { display: block; height: auto; width: auto; max-width: 200px; max-height: 40px; border-radius: 6px; }
.proof-seal .s { text-align: left; font-size: 12px; color: var(--ink-dim); }
.proof-seal .s b { display: block; color: var(--ink); font-size: 13.5px; font-family: var(--sans); }
.proof p { color: var(--ink-dim); font-size: 14.5px; max-width: 440px; margin: 0 auto; position: relative; line-height: 1.6; }
.proof a { color: var(--teal-2); text-decoration: none; font-weight: 500; }
@media (max-width: 480px) { .proof { padding: 30px 22px; } }

/* -------------------------------------------------------------------------
   FAQ — same content/structure as before, folded into the glass language
------------------------------------------------------------------------- */
body.radar-skin .faq-item {
  background: linear-gradient(160deg, rgba(20, 31, 51, 0.55), rgba(12, 20, 36, 0.4));
  border: 1px solid var(--stroke);
  border-radius: 14px;
  padding: 18px 20px;
}
body.radar-skin .faq-item h3 { font-family: var(--serif); font-weight: 600; font-size: 16px; }

body.radar-skin footer { color: var(--ink-faint); }

/* -------------------------------------------------------------------------
   contact.html's real form + status.html's uptime bars/history grid —
   left in their own page-specific colours (already theme-consistent),
   just folded into the glass language for the outer container (handled
   generically above via .k-card / .panel) and a couple of small
   necessary tweaks so inputs read correctly on the void backdrop.
------------------------------------------------------------------------- */
body.radar-skin input,
body.radar-skin textarea,
body.radar-skin select {
  background: rgba(255, 255, 255, 0.03);
}
