/*
 * Shared stylesheet for the public site (landing + secondary content pages).
 * Served verbatim by Caddy — all comments must stay in English.
 *
 * Sections: reset, tokens, fonts, base type, focus states, nav, buttons,
 * cards, hero, "how it works" cards, pricing grid, footer, consent banner,
 * generic content-page layout (for /privacy, /terms, /dpa, /cookies,
 * /contact), responsive breakpoints.
 */

/* ---------- Reset ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
}

img,
svg {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

ul {
  list-style: none;
}

/* ---------- Tokens ---------- */
:root {
  /* Light "crystal glass" theme. The artwork (assets/*.webp) has a true
     alpha channel with baked soft shadows, so it sits on any of these
     light backgrounds without seams. */
  --bg: #eef0f9;
  --surface: rgba(255, 255, 255, 0.62);
  --border: rgba(79, 70, 229, 0.14);
  --indigo: #6366f1;
  --violet: #8b5cf6;
  --lavender: #c4b5fd;
  --accent: #6366f1;
  /* Accent for TEXT on the light background. #6366f1 measures ~4.4:1 — just
     under the 4.5:1 required below large-text size (the same reasoning as
     .logo-ai). Decorative accents (borders, glows, gradients) keep --accent;
     anything that must be read uses this. */
  --accent-text: #4f46e5;
  --text: #3a4161;
  --text-strong: #1c2247;
  --muted: #5b6285;
  --faint: #8b91b0;
  --grad-accent: linear-gradient(92deg, #6366f1, #8b5cf6 45%, #a855f7);
  --radius-card: 20px;
  --radius-btn: 14px;
  --container: 1120px;
  /* Shared by .site-header and the .hero height math: the header is sticky,
     so a 100svh hero would push its own bottom edge below the fold by exactly
     this much. */
  --header-h: 64px;
  /* Vertical rhythm. A .section pays half of it top and bottom, so the gap
     between two sections is 2×, and a separator dropped between them lands
     dead centre. Change it here, not per-section. --divider-gap is the step
     below, for a break INSIDE a section; keeping it ~2/3 is what stops a
     sub-division from reading as a section break. */
  --section-gap: 96px;
  --divider-gap: 64px;
  --font-display: "Sora", system-ui, -apple-system, sans-serif;
  --font-body: system-ui, -apple-system, sans-serif;
}

/* ---------- Fonts ---------- */
@font-face {
  font-family: "Sora";
  src: url("/assets/fonts/sora-var-latin.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}

/* ---------- Base ---------- */
body {
  /* Soft pastel washes over the base — gives the glass cards something to
     refract and keeps the page from reading as flat gray. */
  background:
    radial-gradient(900px 600px at 85% 8%, rgba(139, 92, 246, 0.1), transparent 60%),
    radial-gradient(800px 600px at 8% 92%, rgba(99, 102, 241, 0.08), transparent 60%),
    linear-gradient(180deg, #f3f4fb 0%, #edeff8 55%, #eaecf6 100%);
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.5;
  min-height: 100vh;
  overflow-x: hidden;
}

h1,
h2,
h3,
.font-display {
  font-family: var(--font-display);
  color: var(--text-strong);
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}

/* Keyboard users' first tab stop: invisible until focused, then a small card
   pinned under the header. */
.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 200;
}

.skip-link:focus-visible {
  position: fixed;
  left: 16px;
  top: 12px;
  background: #ffffff;
  color: var(--text-strong);
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
  padding: 10px 16px;
  border-radius: 10px;
  box-shadow: 0 8px 30px rgba(28, 34, 71, 0.18);
}

/* Visible focus state for keyboard navigation, everywhere on the site. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---------- Nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--header-h);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  background: rgba(244, 245, 251, 0.75);
  border-bottom: 1px solid rgba(28, 34, 71, 0.08);
}

.nav {
  height: 100%;
}

.nav-inner {
  max-width: var(--container);
  margin: 0 auto;
  height: 100%;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  color: var(--text-strong);
  text-decoration: none;
  white-space: nowrap;
}

/* The mark is an <img>, so it must not be squeezed by the flex row when the
   wordmark needs space (narrow viewports). */
.logo-mark {
  display: block;
  flex: none;
}

/* One flex item, so .logo's 8px gap stays between the mark and the wordmark
   instead of splitting "AskMyWebsite" from "[AI]" — a bare text node next to
   a <span> would become two items. */
.logo-name {
  display: inline;
}

/* Echoes the dashboard rail, which sets the name as AMW [AI]
   (apps/dashboard/src/main.tsx). The brackets are literal characters, not
   borders, so they track the font weight and never drift from the text.
   #4f46e5 rather than --accent (#6366f1): at 15px the wordmark is not "large
   text", so it needs 4.5:1 — see the contrast notes elsewhere in this file. */
.logo-ai {
  color: #4f46e5;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 28px;
  font-size: 14.5px;
}

.nav-links a {
  text-decoration: none;
  color: var(--muted);
  transition: color 0.15s ease;
}

.nav-links a:hover {
  color: var(--text);
}

.nav-right {
  display: flex;
  align-items: center;
  gap: 16px;
}

/* Hidden until the link row collapses into a panel — see the 680px block. */
.nav-toggle {
  display: none;
  padding: 8px;
  border-radius: 10px;
  color: var(--text);
}

/* Lives in the panel markup but belongs to the narrow layout only. */
.nav-login-mobile {
  display: none;
}

.nav-toggle-box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 18px;
  height: 13px;
}

.nav-toggle-bar {
  display: block;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.2s ease, opacity 0.2s ease;
}

/* Open state: the outer bars meet in the middle as an X, the middle one goes.
   6px is (box height - bar height) / 2 — the distance from an outer bar to the
   centre line. */
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .nav-toggle-bar {
    transition: none;
  }
}

@media (max-width: 680px) {
  .nav-toggle {
    display: inline-flex;
  }

  /* Logo + login button + toggle do not fit on one bar even at 360px, so the
     login moves into the panel — below this breakpoint the panel is the only
     login entry (the hero's own CTA is account creation, not login). */
  .nav-right .btn-ghost {
    display: none;
  }

  /* .nav-links a below is (0,1,1) and would win over a bare .nav-login-mobile,
     repainting the login the same grey as the rest. */
  .nav-links .nav-login-mobile {
    display: block;
    font-weight: 700;
    color: var(--accent-text);
  }

  /* The same three links as on desktop, restyled — not a second copy of the
     list, so the two cannot drift apart. Anchored to the header rather than
     pushing it: the header is sticky, and a taller sticky bar would eat screen
     for the whole scroll, not just while the menu is open. */
  .nav-links {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px 24px 16px;
    /* Opaque, not the header's translucent glass: the hero headline sits right
       under the panel and read straight through it. */
    background: #f4f5fb;
    border-bottom: 1px solid rgba(28, 34, 71, 0.08);
    box-shadow: 0 12px 28px rgba(28, 34, 71, 0.08);
  }

  .nav[data-menu="open"] .nav-links {
    display: flex;
  }

  .nav-links a {
    padding: 13px 0;
    font-size: 16px;
    color: var(--text);
  }

  .nav-links a + a {
    border-top: 1px solid rgba(28, 34, 71, 0.07);
  }
}

/* ---------- Buttons ---------- */
.btn-primary,
.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  text-decoration: none;
  padding: 13px 26px;
  border-radius: var(--radius-btn);
  transition: filter 0.15s ease, transform 0.15s ease, background 0.15s ease,
    border-color 0.15s ease;
  white-space: nowrap;
}

.btn-primary {
  background: var(--grad-accent);
  color: #ffffff;
  box-shadow: 0 8px 24px rgba(99, 102, 241, 0.35);
  border: 1px solid transparent;
}

.btn-primary:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

.btn-ghost {
  border: 1px solid rgba(28, 34, 71, 0.18);
  color: var(--text);
  background: transparent;
}

.btn-ghost:hover {
  background: rgba(28, 34, 71, 0.05);
}

.btn-sm {
  padding: 9px 18px;
  font-size: 13.5px;
}

/* ---------- Cards ---------- */
/* Glass look WITHOUT backdrop-filter: translucent white + white border +
   soft indigo shadow. Real blur at this size intermittently blanks the
   frame in Chromium compositing (the bug the old translateZ/will-change
   hacks chased) and is imperceptible over our nearly-flat background. */
.card {
  background: rgba(255, 255, 255, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.85);
  border-radius: var(--radius-card);
  padding: 28px;
  box-shadow: 0 18px 44px rgba(79, 70, 229, 0.1);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.card:hover {
  border-color: rgba(99, 102, 241, 0.3);
  box-shadow: 0 22px 52px rgba(79, 70, 229, 0.16);
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  /* Not a bare 100svh: the sticky header already spent --header-h of the
     viewport, so the full value pushed the crystal's base below the fold. */
  min-height: calc(100svh - var(--header-h));
  display: flex;
  align-items: center;
  overflow: hidden;
  padding: 14px 0 48px;
}

/* Soft ambient glow behind the crystal cluster. */
.hero::before {
  content: "";
  position: absolute;
  top: -10%;
  right: -10%;
  width: 720px;
  height: 720px;
  background: radial-gradient(
    circle,
    rgba(139, 92, 246, 0.14) 0%,
    rgba(99, 102, 241, 0.06) 45%,
    transparent 70%
  );
  filter: blur(10px);
  pointer-events: none;
  z-index: 0;
}

.hero-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}

.hero-content {
  max-width: 580px;
  position: relative;
  z-index: 2;
}

.eyebrow {
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-text);
  font-weight: 600;
}

.hero h1 {
  margin-top: 18px;
  font-weight: 800;
  font-size: clamp(38px, 5.2vw, 58px);
}

.hero h1 .grad {
  background: var(--grad-accent);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero .tag {
  margin-top: 18px;
  font-size: clamp(15px, 2.2vw, 18px);
  color: var(--muted);
  max-width: 520px;
  line-height: 1.6;
}

.hero .cta {
  margin-top: 36px;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.hero .sub-cta {
  margin-top: 20px;
  font-size: 12.5px;
  /* --faint fails 4.5:1 at this size — --muted keeps the "quiet" look and passes. */
  color: var(--muted);
  letter-spacing: 0.03em;
}

.hero .sub-cta a {
  color: #4f46e5;
  font-weight: 700;
  text-decoration: none;
}

.hero-media {
  position: absolute;
  right: -40px;
  bottom: 0;
  height: 100%;
  /* Wider than the old 52%: that cap was tuned against the stretched render,
     so once the aspect was honoured the crystal collapsed to half the hero.
     At this width the artwork is height-bound on wide screens and width-bound
     on narrow ones, staying large either way. */
  width: 68%;
  z-index: 1;
  pointer-events: none;
}

/* object-fit rather than height:100% + width:auto. The latter asks for a width
   the global `img { max-width: 100% }` then clamps to the box, while the height
   stays 100% — which stretched the crystal ~46% narrower than its 726×768 on
   every viewport under ~1635px, i.e. all of them. contain scales to whichever
   axis binds and never distorts; the box is transparent, so the slack it leaves
   is invisible. */
.hero-media img {
  height: 100%;
  width: 100%;
  object-fit: contain;
  object-position: bottom right;
  display: block;
  /* The artwork has a true alpha channel (shadow baked in) — no masks needed. */
}


@media (max-width: 900px) {
  .hero {
    flex-direction: column;
    /* Stacked, the text and the capped-320px artwork no longer fill a screen,
       so a forced 100svh would leave dead air under the image — invisible
       before, obvious now that a line sits below it. */
    min-height: auto;
    /* No bottom padding: the separator below already owns that gap, and the
       two would stack into a lopsided space above the line. */
    padding: 88px 0 0;
    text-align: left;
  }

  .hero-inner {
    order: 1;
  }

  .hero-media {
    position: static;
    width: 100%;
    max-width: 320px;
    height: auto;
    margin: 32px auto 0;
    order: 2;
  }

  .hero-media img {
    width: 100%;
    height: auto;
  }
}

/* ---------- Sections ---------- */
.section {
  padding: var(--section-gap) 0;
}

/* 96px of air twice over eats a quarter of a phone screen. Retuning the tokens
   keeps every gap and separator in proportion without touching them — both
   scale together, so the section/sub-section contrast survives. */
@media (max-width: 640px) {
  :root {
    --section-gap: 68px;
    --divider-gap: 44px;
  }
}

/* Sits BETWEEN two .section blocks, so the 96px padding each side already
   contributes puts the line exactly in the middle of the gap. It must own no
   margin of its own, and the sections must not add trailing margins — see the
   note on .how-demo. */
.section-separator {
  height: 1px;
  background: var(--border);
}

/* The hero is the one exception: its artwork is absolutely positioned to the
   bottom edge, so the hero contributes no padding above the line the way a
   .section does. Restate the 96px explicitly, or the line sits glued to the
   crystal. */
.hero + .container .section-separator {
  margin-top: var(--section-gap);
}

.section h2 {
  font-size: clamp(28px, 3.6vw, 38px);
  font-weight: 800;
  text-align: center;
}

/* A hard break tuned for a wide, two-line headline. On a phone the text already
   wraps on its own, and the extra break pushed it to four ragged centred lines
   with a one-word orphan. Let the browser do the wrapping down there. */
@media (max-width: 640px) {
  .br-wide {
    display: none;
  }
}

.section .section-sub {
  margin-top: 12px;
  text-align: center;
  color: var(--muted);
  font-size: 16px;
  max-width: 620px;
  margin-left: auto;
  margin-right: auto;
}

/* Product video: the frame carries the crystal-card look; the <video> itself
   stays bare so the native controls sit flush with the rounded corners. */
.demo-video {
  margin: 44px auto 0;
  max-width: 960px;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid var(--border);
  box-shadow: 0 18px 44px rgba(79, 70, 229, 0.1);
  background: #eef0f9;
}

.demo-video video {
  display: block;
  width: 100%;
  height: auto;
}

/* ---------- How it works ---------- */
.how-grid {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
}

.how-card {
  text-align: center;
  padding: 32px 20px;
}

/* The icon tile carries the only saturated colour in the card, so the glow
   below it is part of the mark, not a hover state — it keeps the tile from
   reading as a flat sticker on the translucent card. */
.how-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 16px;
  background: linear-gradient(150deg, var(--indigo), var(--violet));
  color: #fff;
  box-shadow: 0 10px 24px rgba(99, 102, 241, 0.42);
  margin-bottom: 20px;
}

.how-icon svg {
  width: 26px;
  height: 26px;
}

.how-card h3 {
  font-size: 20px;
  font-weight: 800;
  font-family: var(--font-display);
  color: var(--text-strong);
  margin-top: 0;
}

.how-card p {
  margin-top: 8px;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.5;
}

/* Same line, one step down the scale, so a sub-division never reads as a
   section break. */
.how-divider {
  margin: var(--divider-gap) 0;
  height: 1px;
  background: var(--border);
}

.how-subheading {
  font-size: 22px;
  font-weight: 700;
  text-align: center;
  color: var(--text-strong);
}

/* Near-opaque instead of backdrop-filter: a blur surface this large
   (1000×600+) intermittently blanks the whole frame in Chromium
   compositing — the small cards keep the real glass, the page background
   is almost flat here, so the visual difference is nil. */
/* No margin-bottom: it is the last block in the section, so the section's own
   96px padding owns the gap down to the separator. A trailing margin here
   would push that separator off-centre. */
.how-demo {
  margin-top: 48px;
  background: rgba(252, 252, 255, 0.88);
  border: 1px solid rgba(255, 255, 255, 0.75);
  border-radius: var(--radius-card);
  overflow: hidden;
  box-shadow: 0 18px 44px rgba(79, 70, 229, 0.1);
}

.how-demo-tabs {
  display: flex;
  border-bottom: 1px solid var(--border);
  background: rgba(79, 70, 229, 0.02);
}

.how-demo-tab {
  flex: 1;
  padding: 16px 20px;
  font-size: 15px;
  font-weight: 600;
  color: var(--muted);
  border: none;
  background: none;
  cursor: pointer;
  transition: color 0.2s ease;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  min-width: 0;
}

.how-demo-tab:hover {
  color: var(--text);
}

.how-demo-tab.active {
  /* Text must be read (--accent-text); the 2px underline is decorative and
     keeps the brighter accent. */
  color: var(--accent-text);
  border-bottom-color: var(--accent);
}

.how-demo-content {
  padding: 24px 28px 26px;
}

/* Each pane is a single 16:9 "film frame" (the .hd-stage below), styled after
   the product video, with the takeaway pill underneath. */
.how-demo-tab-content {
  display: none;
  animation: fadeIn 0.3s ease;
}

.how-demo-tab-content.active {
  display: block;
}

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

@media (prefers-reduced-motion: reduce) {
  .how-demo-tab-content { animation: none; }
  /* Every element below animates from opacity 0 with a delay — without this
     override they would simply never appear for reduced-motion visitors. */
  .hd-msg,
  .hd-ring,
  .hd-here,
  .hd-reveal,
  .hd-overlay,
  .hd-modal { animation: none !important; opacity: 1 !important; }
  /* The pulsing halo runs hdRingPulse infinitely — animation:none on .hd-ring
     does not reach its pseudo-element, and a frozen halo would just read as a
     second border, so it goes entirely. The 3px ring above still marks the spot. */
  .hd-ring::after { display: none; }
  .hd-ring.hd-gone,
  .hd-dots,
  .hd-cursor { display: none; }
}

/* ---------- The "film frame" demos (hd-*) ----------
   A miniature of the product video, rebuilt in CSS: each pane is a fixed
   960x540 stage designed in absolute pixels like a video frame, then scaled
   to the card's width (--s is set by the small script at the bottom of
   index.html). All motion is CSS keyframes with per-element delays passed
   through the --d / --dgone custom properties, so a tab replays from the
   start every time it becomes visible. */

.hd-stage-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 14px;
}

.hd-stage {
  position: absolute;
  top: 0;
  left: 0;
  width: 960px;
  height: 540px;
  transform: scale(var(--s, 1));
  transform-origin: 0 0;
  /* the video's crystal backdrop, toned down */
  background:
    radial-gradient(620px 320px at 18% 0%, rgba(99, 102, 241, 0.12), transparent 60%),
    radial-gradient(560px 320px at 85% 100%, rgba(168, 85, 247, 0.12), transparent 60%),
    #eef0f9;
}

/* Shared beats: elements start invisible and enter at --d; hdOut retires
   something that handed over to the next step. */
@keyframes hdIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes hdOut {
  to { opacity: 0; }
}

@keyframes hdFade {
  to { opacity: 1; }
}

/* ----- browser window, after the video's BrowserFrame ----- */
.hd-browser {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 920px;
  height: 500px;
  background: #fff;
  border: 1px solid rgba(28, 34, 71, 0.08);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(28, 34, 71, 0.2), 0 5px 18px rgba(28, 34, 71, 0.1);
}

.hd-bar {
  height: 36px;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 14px;
  background: #f1f2f7;
  border-bottom: 1px solid rgba(28, 34, 71, 0.08);
}

.hd-light {
  width: 11px;
  height: 11px;
  border-radius: 50%;
}

.hd-url {
  margin-left: 10px;
  height: 24px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  border-radius: 7px;
  background: #fff;
  border: 1px solid rgba(28, 34, 71, 0.08);
  font-size: 11.5px;
  color: #5b6285;
}

.hd-body {
  position: relative;
  height: 463px;
  overflow: hidden;
}

/* ----- Nordholm, the fictional furniture shop (warm tones, as in the video,
   so the indigo widget stands out) ----- */
.hd-nordholm {
  background: #faf8f4;
  color: #2a2622;
}

.hd-nord-nav {
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 30px;
  border-bottom: 1px solid rgba(42, 38, 34, 0.08);
}

.hd-nord-logo {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.12em;
}

.hd-nord-links {
  display: flex;
  gap: 20px;
  font-size: 12px;
  color: #8a8177;
}

.hd-nord-cart {
  font-size: 12px;
  color: #8a8177;
}

.hd-nord-kicker {
  padding: 18px 30px 4px;
  font-size: 11px;
  letter-spacing: 0.2em;
  font-weight: 600;
  color: #b08968;
}

.hd-nord-heading {
  padding: 0 30px;
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.hd-nord-products {
  display: flex;
  gap: 20px;
  padding: 16px 30px 0;
}

.hd-nord-card {
  flex: 1;
  position: relative;
}

.hd-nord-img {
  height: 168px;
  border-radius: 12px;
  position: relative;
}

.hd-nord-name {
  margin-top: 10px;
  font-size: 13.5px;
  font-weight: 600;
}

.hd-nord-price {
  margin-top: 2px;
  font-size: 12.5px;
  color: #8a8177;
}

.hd-nord-cta {
  position: relative;
  display: inline-block;
  margin-top: 8px;
  padding: 7px 14px;
  border-radius: 7px;
  background: #2a2622;
  color: #fff;
  font-size: 11.5px;
  font-weight: 600;
}

/* The live-context cue: the assistant knows exactly which product the visitor
   is looking at right now. */
.hd-here {
  position: absolute;
  top: 10px;
  left: 10px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  color: #4f46e5;
  font-size: 11px;
  font-weight: 700;
  box-shadow: 0 4px 12px rgba(28, 34, 71, 0.18);
  opacity: 0;
  animation: hdIn 0.4s ease var(--d, 0s) forwards;
}

.hd-here::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #4f46e5;
}

/* ----- generic SaaS app chrome for the Orbit / Lumen demos ----- */
.hd-app {
  background: #f7f8fc;
  color: #1c2247;
}

.hd-app-nav {
  height: 42px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  background: #fff;
  border-bottom: 1px solid rgba(28, 34, 71, 0.08);
}

.hd-app-logo {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
}

.hd-app-logo i {
  width: 16px;
  height: 16px;
  border-radius: 5px;
  background: linear-gradient(140deg, #6366f1, #a855f7);
}

.hd-app-user {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: linear-gradient(140deg, #cdd2f1, #aab1e8);
}

.hd-app-page {
  padding: 20px 26px;
}

.hd-app-title {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 700;
}

.hd-btn {
  position: relative;
  display: inline-block;
  margin-top: 12px;
  padding: 8px 16px;
  background: #fff;
  border: 1px solid rgba(28, 34, 71, 0.14);
  border-radius: 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: #1c2247;
  cursor: default;
}

.hd-reveal {
  opacity: 0;
  animation: hdIn 0.35s ease var(--d, 0s) forwards;
}

.hd-filters {
  display: flex;
  gap: 12px;
  margin-top: 12px;
  padding: 12px;
  background: #fff;
  border: 1px solid rgba(28, 34, 71, 0.1);
  border-radius: 10px;
  max-width: 440px;
}

.hd-field {
  position: relative;
  flex: 1;
  padding: 8px 12px;
  background: #f7f8fc;
  border: 1px solid rgba(28, 34, 71, 0.12);
  border-radius: 7px;
  font-size: 12px;
  color: #5b6285;
}

.hd-table {
  margin-top: 14px;
  max-width: 560px;
  font-size: 12px;
  color: #5b6285;
}

.hd-tr {
  display: flex;
  padding: 8px 2px;
  border-bottom: 1px solid rgba(28, 34, 71, 0.08);
}

.hd-tr span:nth-child(1) { flex: 1.2; }
.hd-tr span:nth-child(2) { flex: 1.4; }
.hd-tr span:nth-child(3) { flex: 0.8; text-align: right; }

.hd-th {
  font-weight: 700;
  color: #1c2247;
  border-bottom-width: 2px;
}

.hd-plan {
  margin-top: 14px;
  padding: 14px 16px;
  background: #fff;
  border: 1px solid rgba(28, 34, 71, 0.1);
  border-radius: 10px;
  font-size: 13px;
  font-weight: 700;
  max-width: 380px;
}

.hd-plan-sub {
  margin-top: 3px;
  font-size: 12px;
  font-weight: 500;
  color: #5b6285;
}

/* ----- the indigo guide ring — the SDK's on-page highlight, straight from
   the video: 3px indigo border plus a pulsing halo that says "click here".
   The pulse used to animate box-shadow (spread 5px→14px) directly on this
   element — Lighthouse flags that as non-composited, since a changing
   box-shadow forces a main-thread repaint every frame. The outer glow is
   the same in both keyframes, so it's just a static shadow here; the part
   that actually pulses moved to ::after, animating transform/opacity only
   (GPU-composited, same "expanding ring" look, no repaint cost). */
.hd-ring {
  position: absolute;
  inset: -8px;
  border: 3px solid #4f46e5;
  border-radius: 12px;
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 0 30px rgba(79, 70, 229, 0.25);
  animation: hdIn 0.3s ease var(--d, 0s) forwards;
}

/* A ring that hands over to the next step (the visitor clicked it). */
.hd-ring.hd-gone {
  animation:
    hdIn 0.3s ease var(--d, 0s) forwards,
    hdOut 0.3s ease var(--dgone, 10s) forwards;
}

.hd-ring::after {
  content: "";
  position: absolute;
  inset: -5px;
  border: 5px solid rgba(79, 70, 229, 0.35);
  border-radius: inherit;
  animation: hdRingPulse 1.3s ease-in-out var(--d, 0s) infinite;
}

@keyframes hdRingPulse {
  0%, 100% { transform: scale(1); opacity: 0.6; }
  50% { transform: scale(1.14); opacity: 0; }
}

/* Step-number chip pinned to the ring's corner. */
.hd-ring i {
  position: absolute;
  top: -10px;
  right: -10px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #4f46e5;
  color: #fff;
  font-style: normal;
  font-size: 11.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 10px rgba(79, 70, 229, 0.4);
}

/* ----- modal + dimmed page, after the video's finish-picker scene ----- */
.hd-overlay {
  position: absolute;
  inset: 0;
  z-index: 3;
  background: rgba(20, 18, 14, 0.32);
  opacity: 0;
  animation: hdFade 0.35s ease var(--d, 0s) forwards;
}

.hd-modal {
  position: absolute;
  z-index: 4;
  top: 50%;
  left: 50%;
  width: 320px;
  padding: 22px 24px;
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 30px 80px rgba(20, 18, 14, 0.35);
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.92);
  animation: hdModalIn 0.4s cubic-bezier(0.34, 1.4, 0.64, 1) var(--d, 0s) forwards;
}

@keyframes hdModalIn {
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

.hd-modal-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  color: #1c2247;
}

.hd-opt {
  position: relative;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 10px;
  padding: 10px 12px;
  border: 1px solid rgba(28, 34, 71, 0.14);
  border-radius: 9px;
  font-size: 12.5px;
  font-weight: 600;
  color: #1c2247;
}

.hd-opt span {
  color: #5b6285;
  font-weight: 500;
}

.hd-opt .hd-ring {
  inset: -6px;
  border-radius: 11px;
}

/* The confirm button is deliberately never ringed — that click belongs to
   the visitor, which is the whole point of this tab. */
.hd-confirm {
  display: block;
  text-align: center;
  margin-top: 14px;
  padding: 10px 0;
  border-radius: 9px;
  background: #1c2247;
  color: #fff;
  font-size: 12.5px;
  font-weight: 700;
  cursor: default;
}

/* ----- the visitor's cursor: enters, travels to the ringed control, dips on
   click, then fades — the agent shows, the visitor acts. Translate lives on
   the wrapper and the click-dip scale on the inner svg, so the two transforms
   never fight. ----- */
.hd-cursor {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 6;
  width: 22px;
  height: 22px;
  opacity: 0;
  pointer-events: none;
}

.hd-cursor svg {
  display: block;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.35));
  animation: hdClick 0.3s ease var(--dclick, 0s);
}

@keyframes hdClick {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(0.82); }
}

.hd-cursor-steps {
  animation:
    hdCursorSteps 0.9s cubic-bezier(0.4, 0, 0.2, 1) var(--dmove, 0s) forwards,
    hdOut 0.35s ease var(--dfade, 0s) forwards;
}

@keyframes hdCursorSteps {
  0% { opacity: 0; transform: translate(600px, 330px); }
  18% { opacity: 1; }
  100% { opacity: 1; transform: translate(58px, 106px); }
}

.hd-cursor-ctrl {
  animation:
    hdCursorCtrl 0.9s cubic-bezier(0.4, 0, 0.2, 1) var(--dmove, 0s) forwards,
    hdOut 0.35s ease var(--dfade, 0s) forwards;
}

@keyframes hdCursorCtrl {
  0% { opacity: 0; transform: translate(600px, 330px); }
  18% { opacity: 1; }
  100% { opacity: 1; transform: translate(60px, 190px); }
}

/* ----- the chat widget, a faithful miniature of the real SDK widget:
   indigo #4f46e5 header, white panel, typing dots, rounded input ----- */
.hd-widget {
  position: absolute;
  right: 16px;
  bottom: 14px;
  z-index: 5;
  width: 252px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.hd-panel {
  width: 100%;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
  overflow: hidden;
  margin-bottom: 10px;
}

.hd-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px 8px 12px;
  background: #4f46e5;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
}

.hd-panel-head span {
  width: 20px;
  height: 20px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.16);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
}

.hd-msgs {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
}

.hd-msg {
  max-width: 88%;
  padding: 7px 10px;
  border-radius: 10px;
  font-size: 11.5px;
  line-height: 1.45;
  opacity: 0;
  animation: hdIn 0.45s cubic-bezier(0.34, 1.3, 0.64, 1) var(--d, 0s) forwards;
}

.hd-user {
  align-self: flex-end;
  background: #4f46e5;
  color: #fff;
  border-bottom-right-radius: 3px;
}

.hd-agent {
  align-self: flex-start;
  background: #f1f5f9;
  color: #111;
  border-bottom-left-radius: 3px;
}

/* Typing dots: in at --d, out (and collapsed, so the answer lands in the same
   spot) at --dgone. */
.hd-dots {
  align-self: flex-start;
  display: flex;
  gap: 4px;
  padding: 9px 11px;
  border-radius: 10px;
  background: #f1f5f9;
  opacity: 0;
  animation:
    hdIn 0.25s ease var(--d, 0s) forwards,
    hdDotsOut 0.25s ease var(--dgone, 10s) forwards;
}

@keyframes hdDotsOut {
  to { opacity: 0; margin-bottom: -31px; }
}

.hd-dots span {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #94a3b8;
  animation: hdDotBlink 1s ease-in-out infinite;
}

.hd-dots span:nth-child(2) { animation-delay: 0.18s; }
.hd-dots span:nth-child(3) { animation-delay: 0.36s; }

@keyframes hdDotBlink {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 1; }
}

.hd-input {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 10px 10px;
  padding: 7px 10px;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  font-size: 11.5px;
  color: #94a3b8;
}

.hd-input svg {
  color: #cbd5e1;
  flex: none;
}

.hd-bubble {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #4f46e5;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}

/* The takeaway line, styled like the video's caption pill. */
.how-demo-caption {
  display: table;
  margin: 18px auto 0;
  padding: 12px 26px;
  border-radius: 999px;
  background: rgba(28, 34, 71, 0.9);
  color: #fff;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  text-align: center;
  box-shadow: 0 10px 28px rgba(28, 34, 71, 0.25);
}

@media (max-width: 640px) {
  .how-demo {
    margin-top: 40px;
  }

  /* Was a horizontal scroller, which cut the third tab off at the card edge
     with nothing but a grey scrollbar to hint at it — a tab you cannot see is
     a tab nobody presses. Three labels wrap onto two rows and all stay visible. */
  .how-demo-tabs {
    flex-wrap: wrap;
  }

  .how-demo-tab {
    padding: 12px 14px;
    font-size: 13px;
    flex: 1 1 auto;
    white-space: normal;
  }

  .how-demo-content {
    padding: 12px 12px 18px;
  }

  /* The stage scales with the card, so the miniature just gets smaller — the
     pill below it carries the message at readable size. */
  .how-demo-caption {
    margin-top: 14px;
    padding: 10px 18px;
    font-size: 13px;
  }
}

@media (max-width: 900px) {
  /* Four short cards pair up cleanly two-by-two; dropping straight to one
     column here would make the section far taller than it needs to be. */
  .how-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Below this a pair of feature cards is narrow enough that every title wraps
   to two lines, so the two-column saving stops being one. */
@media (max-width: 470px) {
  .how-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Pricing ---------- */
.pricing-grid {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  /* Default stretch keeps all four cards the same height. */
}

.plan-card {
  position: relative;
  display: flex;
  flex-direction: column;
  text-align: left;
}

.plan-icon {
  display: block;
  width: 136px;
  height: 136px;
  margin: 0 auto;
  /* True-alpha artwork with a baked soft shadow — no masks, no CSS glow. */
}

/* Card header: plan name on the left, price on the right — the price reads
   as a quiet but primary note instead of a headline number. */
.plan-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.plan-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  color: var(--text-strong);
}

.plan-price .amount {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  /* 18px bold is still under the 18.66px "large text" bar, so 4.5:1 applies. */
  color: var(--accent-text);
}

.plan-price .period {
  font-size: 13px;
  color: var(--muted);
}

.plan-tagline {
  margin-top: 12px;
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.55;
  min-height: 44px;
  /* Left like the rest of the card — only the icon stays centred, so one
     centred accent reads as intentional instead of two systems fighting. */
  text-align: left;
  /* Never longer than two lines, so every card keeps the same rhythm. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.plan-highlights {
  margin-top: 14px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  flex-grow: 1;
  margin-bottom: 14px;
}

.plan-highlights li {
  position: relative;
  padding-left: 20px;
  margin-top: 10px;
  font-size: 14px;
  color: var(--text);
  line-height: 1.5;
}

.plan-highlights li::before {
  content: "\2726";
  position: absolute;
  left: 0;
  color: var(--accent);
  font-size: 12px;
}

.plan-cta {
  /* Pushed to the card bottom so all four CTAs sit on the same line. */
  margin-top: auto;
  width: 100%;
  text-align: center;
}

.plan-card.popular {
  border-color: rgba(165, 180, 252, 0.45);
  box-shadow: 0 20px 50px rgba(99, 102, 241, 0.25);
}

.plan-badge {
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  /* Solid, not --grad-accent: white 12px text on the gradient's light end
     (#a855f7) measures ~3.1:1. Solid indigo keeps the brand and passes. */
  background: #4f46e5;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 5px 14px;
  border-radius: 999px;
}

@media (max-width: 1080px) {
  .pricing-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  .pricing-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Founding offer (injected by offer.js) ----------
   Everything below is dormant CSS: it only takes effect once offer.js adds
   these classes at runtime, so a "none" response or a down API leaves the
   pricing section pixel-identical to the page without this file. */

/* Accent-colored bold spans inside the offer sub-headline copy. */
.section-sub.offer-sub b {
  color: var(--accent-text);
  font-weight: 700;
}

/* Ribbon pill for priced cards — same slot and shape as .plan-badge, which
   it replaces on the popular card (the two pills don't both fit). */
.offer-ribbon {
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  /* Solid for the same reason as .plan-badge: 12px white on the gradient's
     light end fails 4.5:1. */
  background: #4f46e5;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 5px 14px;
  border-radius: 999px;
  z-index: 1;
}

/* "Almost gone": warm gradient carries the urgency, not new copy tone.
   Darkened from #f59e0b→#ef4444 (white text measured ~2.4:1 on the amber end);
   these ends keep white ≥4.5:1 without losing the heat. */
.offer-ribbon-hot {
  background: linear-gradient(92deg, #b45309, #dc2626);
}

/* Old price, struck through and de-emphasized, ahead of the discounted one. */
.offer-was {
  text-decoration: line-through;
  /* --faint fails 4.5:1 at this size — --muted keeps the "quiet" look and passes. */
  color: var(--muted);
  font-size: 14px;
  font-weight: 600;
  margin-right: 6px;
}

/* Discounted price picks up the brand gradient as text fill so it reads as
   the "deal" price at a glance. --accent is the fallback where
   background-clip: text isn't supported. */
.offer-now {
  background: var(--grad-accent);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--accent);
  font-weight: 700;
}

/* Small right-aligned note under the price row, e.g. "first 3 months, then €19". */
.offer-note {
  margin-top: 2px;
  text-align: right;
  font-size: 12px;
  /* Billing-relevant text — --faint (~3.1:1) has no business here. */
  color: var(--muted);
}

/* Claimed-state notice under the pricing grid — cards stay untouched. */
.offer-claimed {
  margin-top: 20px;
  text-align: center;
  font-size: 14px;
  color: var(--muted);
}

.offer-claimed-check {
  color: #16a34a;
  font-weight: 700;
}

/* ---------- Live demos (#demos) ----------
   Last section on the page: the demos sit behind a free account, so the
   section doubles as the register pitch — product frames first, the two demo
   cards after, and the account note closing the page. */

/* Two frames from the product video, shown as a pair. */
.demo-shots {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}

.demo-shot img {
  width: 100%;
  height: auto;
  border-radius: 14px;
  border: 1px solid var(--border);
  box-shadow: 0 18px 44px rgba(79, 70, 229, 0.1);
}

.demo-shot figcaption {
  margin-top: 10px;
  text-align: center;
  font-size: 13.5px;
  color: var(--muted);
}

/* Two cards, not four: these are the only two demo sites, and a two-column
   grid keeps each one wide enough to read the sample question on one line. */
.demo-grid {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}

.demo-card {
  display: flex;
  flex-direction: column;
  text-align: left;
}

.demo-card h3 {
  margin: 10px 0 0;
  font-size: 24px;
}

.demo-tagline {
  margin: 12px 0 0;
  color: var(--muted);
}

.demo-try {
  margin: 16px 0 24px;
  font-size: 15px;
  color: var(--muted);
}

/* margin-top: auto pins the CTA to the card's foot, so both buttons align even
   when one tagline wraps to an extra line. The gap above it belongs to
   .demo-try, not here — auto would swallow a margin of its own. */
.demo-cta {
  margin-top: auto;
  align-self: flex-start;
}

/* The register nudge that closes the section (and the page). */
.demo-note {
  margin-top: 28px;
  text-align: center;
  font-size: 15px;
  color: var(--muted);
}

.demo-note a {
  color: #4f46e5;
  font-weight: 700;
  text-decoration: none;
}

@media (max-width: 640px) {
  .demo-shots,
  .demo-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--border);
  padding: 26px 0;
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 32px;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  font-size: 13px;
}

.footer-links a {
  color: var(--muted);
  text-decoration: none;
  transition: color .15s;
}

.footer-links a:hover {
  color: var(--text);
}

.footer-copy {
  font-size: 13px;
  /* --faint fails 4.5:1 at this size — --muted keeps the "quiet" look and passes. */
  color: var(--muted);
}

.footer-social {
  display: flex;
  align-items: center;
  gap: 18px;
}

.footer-social a {
  display: inline-flex;
  color: var(--muted);
  transition: color .15s;
}

.footer-social a:hover {
  color: var(--text);
}

.footer-social svg {
  width: 18px;
  height: 18px;
  display: block;
}

/* ---------- Consent banner ---------- */
#consent {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  max-width: 850px;
  margin: 0 auto;
  background: #ffffff;
  border: 1px solid rgba(28, 34, 71, 0.12);
  border-radius: 14px;
  padding: 16px 18px;
  font-size: 13.5px;
  color: var(--text);
  text-align: left;
  display: none;
  box-shadow: 0 8px 30px rgba(28, 34, 71, 0.18);
  z-index: 100;
}

#consent .consent-row {
  display: flex;
  align-content: center;
  align-items: center;
}

#consent p {
  line-height: 1.5;
  color: var(--muted);
}

#consent a {
  color: #4f46e5;
  font-weight: 700;
  text-decoration: none;
}

#consent .btns {
  display: flex;
  flex-direction: row-reverse;
  align-content: center;
  gap: 8px;
}

#consent button {
  font-size: 13px;
  cursor: pointer;
  padding: 8px 16px;
}

/* ---------- Generic content page (privacy, terms, dpa, cookies, contact) ---------- */
.page {
  max-width: 760px;
  margin: 0 auto;
  padding: 64px 24px 96px;
}

.page h1 {
  font-size: clamp(28px, 4vw, 38px);
  font-weight: 800;
}

.page h2 {
  margin-top: 40px;
  font-size: 22px;
  font-weight: 700;
}

.page h3 {
  margin-top: 24px;
  font-size: 17px;
  font-weight: 700;
}

.page p {
  margin-top: 14px;
  color: var(--text);
  line-height: 1.65;
  font-size: 15.5px;
}

.page ul {
  margin-top: 14px;
  padding-left: 4px;
}

.page ul li {
  position: relative;
  padding-left: 20px;
  margin-top: 8px;
  font-size: 15.5px;
  line-height: 1.6;
}

.page ul li::before {
  content: "\2013";
  position: absolute;
  left: 0;
  color: var(--faint);
}

.page a {
  color: var(--accent-text);
}

/* A four-column table has a min-content width no phone can hold: cookies.html
   measured 516px, so the whole document scrolled sideways, not just the table.
   The wrapper takes the scrolling instead. It is a real element rather than
   `display: block` on the <table> itself, because that flattening costs the
   table its semantics for screen readers — not a trade worth making in a legal
   document. tabindex makes the scroll box reachable by keyboard. */
.table-scroll {
  margin-top: 18px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

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

.page table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.page table th,
.page table td {
  border: 1px solid var(--border);
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
}

.page table th {
  color: var(--text-strong);
  background: var(--surface);
}

.page code {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 0.9em;
}

.page .updated {
  margin-top: 8px;
  /* --faint fails 4.5:1 at this size — --muted keeps the "quiet" look and passes. */
  color: var(--muted);
  font-size: 13px;
}

/* Tighter cells on phones: the wrapper above means an oversized table scrolls
   rather than breaking the page, but scrolling is still a cost. Trimming the
   padding and a half point of type keeps most of these tables inside the
   viewport, so the scroll is there for the widest one, not for all of them. */
@media (max-width: 640px) {
  .page {
    padding: 48px 18px 72px;
  }

  .page table {
    font-size: 13.5px;
  }

  .page table th,
  .page table td {
    padding: 8px 9px;
  }

  /* Four columns squeezed into ~357px turns the prose column into a ribbon one
     word wide and the row twenty lines tall. Given the wrapper scrolls anyway,
     a floor that keeps the text column readable is the better trade. Only the
     four-column tables (cookies.html) take it — the two- and three-column ones
     still fit, and making them scroll for consistency would be a loss.
     Without :has() support the rule simply does not apply and the layout falls
     back to the narrow-but-readable version. */
  .page table:has(tr > th:nth-child(4)) {
    min-width: 540px;
  }
}

/* ============================================================
   Content hub (News / Research / Blog) — index + article pages
   ============================================================ */

/* ---------- Index page ---------- */
.section-header h1 {
  margin-top: 14px;
  font-size: clamp(28px, 4vw, 38px);
  font-weight: 800;
}

.posts-grid {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

/* The thumbnail sits flush, like .demo-video's frame, so the .card padding
   moves to .post-card-body instead. */
.post-card {
  padding: 0;
  overflow: hidden;
  display: flex;
}

.post-card-link {
  display: flex;
  flex-direction: column;
  flex: 1;
  color: inherit;
  text-decoration: none;
}

.post-card-thumb {
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #eef0f9;
  border-bottom: 1px solid var(--border);
}

.post-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.post-card:hover .post-card-thumb img {
  transform: scale(1.03);
}

/* No hero image: the 16:9 slot stays so a mixed grid keeps one card shape,
   filled with a decorative wash instead of an empty rectangle. */
.post-card.no-thumb .post-card-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(280px 160px at 80% 0%, rgba(139, 92, 246, 0.14), transparent 65%),
    radial-gradient(280px 160px at 10% 100%, rgba(99, 102, 241, 0.12), transparent 65%),
    #eef0f9;
}

.post-card.no-thumb .post-card-thumb::before {
  content: "\2726";
  font-size: 30px;
  color: var(--lavender);
}

.post-card-body {
  padding: 20px 24px 24px;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.post-title {
  font-size: 19px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--text-strong);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color 0.15s ease;
}

.post-card:hover .post-title {
  color: var(--accent-text);
}

.post-excerpt {
  margin-top: 8px;
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.55;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.post-meta {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 8px;
  font-size: 13px;
  color: var(--muted);
}

.pagination {
  margin-top: 48px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.pagination-current {
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
}

/* "Explore more" — cross-links to the other live sections. */
.cross-links {
  margin-top: 48px;
}

.cross-links h2 {
  font-size: 20px;
  font-weight: 700;
}

.cross-links-list {
  margin-top: 18px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}

.cross-link {
  display: block;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: 14px;
  text-decoration: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.cross-link:hover {
  border-color: rgba(99, 102, 241, 0.3);
  background: rgba(255, 255, 255, 0.5);
}

.cross-link-label {
  display: block;
  font-weight: 700;
  color: var(--text-strong);
}

.cross-link-desc {
  display: block;
  margin-top: 4px;
  font-size: 13.5px;
  color: var(--muted);
}

/* The "Read" dropdown in the header, shown only with 2+ live sections. */
.nav-sections {
  position: relative;
}

.nav-sections summary {
  cursor: pointer;
  list-style: none;
}

.nav-sections summary::-webkit-details-marker {
  display: none;
}

.nav-sections-panel {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 140px;
  padding: 8px;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 18px 44px rgba(79, 70, 229, 0.14);
}

.nav-sections-panel a {
  padding: 8px 10px;
  border-radius: 8px;
}

.nav-sections-panel a:hover {
  background: var(--bg);
}

@media (max-width: 900px) {
  .posts-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .posts-grid { grid-template-columns: 1fr; }
  .cross-links-list { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .post-card-thumb img { transition: none; }
  .post-card:hover .post-card-thumb img { transform: none; }
}

/* ---------- Article page ---------- */

/* Header text narrows to a 760px reading measure — same as .page — even
   though the element also carries .container (1120px): this rule is later
   in the cascade and wins at equal specificity. */
.article-header {
  max-width: 760px;
  padding-top: 40px;
}

.article-header h1 {
  margin-top: 14px;
  font-size: clamp(28px, 4vw, 38px);
  font-weight: 800;
}

.article-dek {
  margin-top: 16px;
  font-size: 18px;
  line-height: 1.6;
  color: var(--muted);
}

.article-meta {
  margin-top: 20px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 14px;
  color: var(--muted);
}

.article-byline {
  color: var(--text);
  font-weight: 600;
}

/* Wide media column (960px), narrower than .container's 1120px. */
.article-hero {
  max-width: 960px;
  margin: 24px auto 0;
  padding: 0 24px;
  border-radius: var(--radius-card);
  overflow: hidden;
  border: 1px solid var(--border);
  box-shadow: 0 18px 44px rgba(79, 70, 229, 0.1);
}

.article-hero img {
  display: block;
  width: 100%;
  aspect-ratio: 21 / 9;
  object-fit: cover;
}

.article-layout {
  max-width: 760px;
  margin: 0 auto;
  padding: 0 24px;
}

/* Prose: .page's rules, half a step up for long-form reading. */
.article-body {
  margin-top: 32px;
  font-size: 16.5px;
  line-height: 1.75;
}

.article-body > * + * {
  margin-top: 20px;
}

.article-body h2 { margin-top: 48px; font-size: 24px; font-weight: 700; }
.article-body h3 { margin-top: 32px; font-size: 18px; font-weight: 700; }

.article-body a {
  color: var(--accent-text);
}

.article-body ul { padding-left: 4px; }

.article-body ul li {
  position: relative;
  padding-left: 20px;
  margin-top: 10px;
}

.article-body ul li::before {
  content: "\2013";
  position: absolute;
  left: 0;
  color: var(--faint);
}

.article-body ol { padding-left: 22px; }
.article-body ol li { margin-top: 10px; }

.article-body blockquote {
  padding: 2px 0 2px 20px;
  border-left: 2px solid var(--lavender);
  color: var(--muted);
  font-size: 18px;
  line-height: 1.6;
}

.article-body code {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 0.9em;
}

.article-body pre {
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow-x: auto;
  font-size: 14px;
  line-height: 1.6;
}

.article-body pre code {
  background: none;
  border: none;
  padding: 0;
}

.article-body img {
  border-radius: 14px;
  border: 1px solid var(--border);
  box-shadow: 0 18px 44px rgba(79, 70, 229, 0.1);
}

.article-body hr {
  margin: 48px 0;
  border: none;
  height: 1px;
  background: var(--border);
}

.preview-banner {
  max-width: 760px;
  margin: 24px auto 0;
  padding: 10px 16px;
  background: rgba(217, 119, 6, 0.12);
  color: #92400e;
  border-radius: 10px;
  font-size: 13.5px;
  font-weight: 600;
}

/* CTA card: the hero's ambient washes, on a reading-width column. */
.article-cta {
  max-width: 760px;
  margin: var(--divider-gap) auto 0;
  padding: 0 24px;
}

.article-cta .card {
  padding: 48px 28px;
  text-align: center;
  background:
    radial-gradient(420px 240px at 85% 0%, rgba(139, 92, 246, 0.12), transparent 60%),
    radial-gradient(420px 240px at 8% 100%, rgba(99, 102, 241, 0.1), transparent 60%),
    rgba(255, 255, 255, 0.78);
}

.article-cta h2 {
  font-size: clamp(24px, 3vw, 30px);
  font-weight: 800;
}

.article-cta p {
  margin: 12px auto 0;
  max-width: 520px;
  color: var(--muted);
  font-size: 15.5px;
}

.article-cta .btn-primary {
  margin-top: 24px;
}

.share-row {
  margin-top: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}

.share-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}

.share-link {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--accent-text);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-decoration: none;
}

.share-link:hover {
  text-decoration: underline;
}

.related-articles {
  margin-top: var(--divider-gap);
}

.related-articles h2 {
  font-size: 22px;
  font-weight: 700;
}

.related-grid {
  margin-top: 24px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.related-card h3 {
  font-size: 17px;
  font-weight: 700;
  line-height: 1.35;
}

.related-card h3 a {
  color: var(--text-strong);
  text-decoration: none;
  transition: color 0.15s ease;
}

.related-card:hover h3 a {
  color: var(--accent-text);
}

.related-card p {
  margin-top: 10px;
  font-size: 14px;
  color: var(--muted);
  line-height: 1.55;
}

@media (max-width: 640px) {
  .article-header,
  .article-hero,
  .article-layout,
  .article-cta,
  .preview-banner { padding-left: 18px; padding-right: 18px; }

  .article-hero img { aspect-ratio: 16 / 9; }
  .article-body { font-size: 16px; }
  .related-grid { grid-template-columns: 1fr; }
  .article-cta .card { padding: 36px 20px; }
}

@media (max-width: 900px) {
  .related-grid { grid-template-columns: 1fr; }
}
