/* Shared styles for the static marketing pages (/about, /data) and the
   contact modal. Kept entirely under contact-* / mkt-* prefixes so loading
   this file from a static page never collides with the app's own CSS. */

:root {
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

body.mkt {
  margin: 0;
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: #0b1220;
  color: #e5e7eb;
  line-height: 1.6;
}

body.mkt a {
  color: #34d399;
}

body.mkt img {
  max-width: 100%;
  height: auto;
  display: block;
}

.mkt .wrap {
  max-width: 980px;
  margin: 0 auto;
  padding: 0 24px;
}

/* Top nav */
.mkt nav.top {
  position: sticky;
  top: 0;
  z-index: 10;
  background: rgba(11, 18, 32, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid #1f2937;
}

.mkt nav.top .wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 60px;
}

.mkt .brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 700;
  font-size: 16px;
  color: #e5e7eb;
  text-decoration: none;
  margin-right: auto;
}

.mkt .brand img {
  width: 24px;
  height: 24px;
}

.mkt nav.top a.nav-link {
  color: #9ca3af;
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
}

.mkt nav.top a.nav-link:hover {
  color: #e5e7eb;
}

.mkt nav.top a.nav-cta {
  color: #052e22;
  background: #10b981;
  border-radius: 8px;
  padding: 7px 14px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}

/* Hero */
.mkt header.hero {
  position: relative;
  overflow: hidden;
  padding: 64px 0 48px;
  background: #0b1220;
  border-bottom: 1px solid #1f2937;
}

/* Animated colour blobs — the only background colour. Three radial gradients
   in the brand palette (green/red/amber) that drift and breathe slowly via
   a single transform on this pseudo-element. GPU-friendly: transform is the
   cheapest thing to animate. */
.mkt header.hero::before {
  content: "";
  position: absolute;
  inset: -25%;
  background:
    radial-gradient(circle at 22% 28%, rgba(16, 185, 129, 0.18), transparent 38%),
    radial-gradient(circle at 78% 72%, rgba(239, 68, 68, 0.12), transparent 40%),
    radial-gradient(circle at 60% 18%, rgba(245, 158, 11, 0.10), transparent 36%),
    radial-gradient(circle at 12% 82%, rgba(99, 102, 241, 0.08), transparent 40%);
  animation: heroBlobDrift 26s ease-in-out infinite alternate;
  filter: blur(8px);
  z-index: 0;
  pointer-events: none;
}

/* Dot grid — evokes the map's neighbourhood lattice. Shifts slowly so the
   hero never feels frozen, without distracting from the text. */
.mkt header.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 26px 26px;
  animation: heroGridShift 90s linear infinite;
  mask-image: radial-gradient(ellipse at center, #000 30%, transparent 80%);
  -webkit-mask-image: radial-gradient(ellipse at center, #000 30%, transparent 80%);
  z-index: 0;
  pointer-events: none;
}

/* Hero content sits above both pseudo-elements. */
.mkt header.hero > .wrap,
.mkt header.hero .stats {
  position: relative;
  z-index: 1;
}

/* Pulsing "incident pins" scattered in the hero background. Purely decorative
   — aria-hidden in the markup. Each pin pulses on its own period so they
   don't sync; positions chosen to avoid the text columns. */
.mkt .hero-pins {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.mkt .hero-pins span {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  box-shadow: 0 0 0 0 currentColor;
  animation: heroPinPulse 3.6s ease-out infinite;
}

.mkt .hero-pins .pin-green { color: #10b981; background: #10b981; }
.mkt .hero-pins .pin-amber { color: #f59e0b; background: #f59e0b; }
.mkt .hero-pins .pin-red   { color: #ef4444; background: #ef4444; }

.mkt .hero-pins .pin-1 { top: 18%; left: 6%;  animation-delay: 0s; }
.mkt .hero-pins .pin-2 { top: 28%; left: 49%; animation-delay: 0.8s; }
.mkt .hero-pins .pin-3 { top: 62%; left: 9%;  animation-delay: 1.6s; }
.mkt .hero-pins .pin-4 { top: 74%; left: 47%; animation-delay: 2.4s; }
.mkt .hero-pins .pin-5 { top: 12%; left: 88%; animation-delay: 1.2s; }
.mkt .hero-pins .pin-6 { top: 82%; left: 91%; animation-delay: 2.0s; }

@keyframes heroBlobDrift {
  0%   { transform: translate(0, 0) scale(1); }
  50%  { transform: translate(2.5%, -1.5%) scale(1.06); }
  100% { transform: translate(-1.5%, 2.5%) scale(1.02); }
}

@keyframes heroGridShift {
  0%   { background-position: 0 0; }
  100% { background-position: 52px 52px; }
}

@keyframes heroPinPulse {
  0%   { box-shadow: 0 0 0 0 currentColor; opacity: 0.85; }
  70%  { box-shadow: 0 0 0 14px transparent; opacity: 0.6; }
  100% { box-shadow: 0 0 0 0 transparent; opacity: 0.85; }
}

/* Accessibility: honour reduced-motion by freezing every hero animation.
   Static gradients still give the hero its colour, just without movement. */
@media (prefers-reduced-motion: reduce) {
  .mkt header.hero::before,
  .mkt header.hero::after,
  .mkt .hero-pins span {
    animation: none;
  }
}

.mkt .hero-grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 40px;
  align-items: center;
}

.mkt .hero h1 {
  margin: 0 0 14px;
  font-size: clamp(30px, 5.4vw, 52px);
  line-height: 1.08;
  letter-spacing: -0.025em;
  max-width: 720px;
}

.mkt .hero h1 em {
  font-style: normal;
  color: #34d399;
}

.mkt .hero p.lede {
  margin: 0 0 20px;
  max-width: 580px;
  font-size: 18px;
  color: #9ca3af;
}

.mkt .cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 24px;
}

.mkt .btn {
  display: inline-block;
  padding: 9px 20px;
  border-radius: 8px;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid #374151;
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
}

.mkt .btn-primary {
  background: #10b981;
  border-color: #10b981;
  color: #052e22;
}

.mkt .btn-primary:hover {
  background: #059669;
}

.mkt .btn-ghost {
  color: #e5e7eb;
  background: transparent;
}

.mkt .hero-art {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid #1f2937;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
  background: #0b1220;
}

.mkt .hero-art img {
  width: 100%;
  height: auto;
  display: block;
}

/* A standalone marketing image used outside .hero-art (e.g. the endpoints
   sample). Inline height:auto on a viewBox-only SVG collapses in some
   browsers, so force a block with a sane max width and intrinsic ratio. */
.mkt img[src^="/marketing/"] {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Stat strip */
.mkt .stats {
  display: flex;
  flex-wrap: wrap;
  border: 1px solid #1f2937;
  border-radius: 12px;
  background: rgba(17, 24, 39, 0.7);
  overflow: hidden;
}

.mkt .stat {
  flex: 1 1 140px;
  padding: 18px 22px;
  border-right: 1px solid #1f2937;
}

.mkt .stat:last-child {
  border-right: none;
}

.mkt .stat b {
  display: block;
  font-size: 24px;
  letter-spacing: -0.02em;
  color: #f9fafb;
}

.mkt .stat span {
  font-size: 12px;
  color: #9ca3af;
}

/* Sections */
.mkt section {
  padding: 44px 0;
  border-bottom: 1px solid #1f2937;
}

.mkt h2 {
  margin: 0 0 16px;
  font-size: 28px;
  letter-spacing: -0.015em;
}

.mkt h2 em {
  font-style: normal;
  color: #34d399;
}

.mkt .muted {
  color: #9ca3af;
}

/* Color swatches */
.mkt .swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin: 26px 0 8px;
}

.mkt .swatch {
  flex: 1 1 190px;
  border: 1px solid #1f2937;
  border-radius: 12px;
  padding: 18px;
  background: #111827;
}

.mkt .swatch.gray-swatch {
  border-color: #4b5563;
  background: #161e2e;
}

.mkt .swatch b {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 8px;
}

.mkt .dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex: none;
}

.mkt .swatch p {
  margin: 0;
  font-size: 13px;
  color: #9ca3af;
}

/* Formula */
.mkt .formula {
  margin: 24px 0 8px;
  padding: 20px 22px;
  border: 1px solid #1f2937;
  border-radius: 12px;
  background: #111827;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 14px;
  color: #a7f3d0;
  overflow-x: auto;
  white-space: nowrap;
}

/* Feature grid */
.mkt .grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 16px;
  margin-top: 26px;
}

.mkt .card {
  border: 1px solid #1f2937;
  border-radius: 12px;
  padding: 22px;
  background: #111827;
}

.mkt .card h3 {
  margin: 0 0 10px;
  font-size: 16px;
}

.mkt .card p {
  margin: 0;
  font-size: 14px;
  color: #9ca3af;
}

.mkt .card .card-icon {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  background: rgba(16, 185, 129, 0.12);
  color: #34d399;
  margin-bottom: 12px;
}

/* Split section */
.mkt .split {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 24px;
  justify-content: space-between;
}

.mkt .split > div {
  flex: 1 1 380px;
}

/* FAQ */
.mkt details {
  border: 1px solid #1f2937;
  border-radius: 10px;
  background: #111827;
  padding: 16px 20px;
  margin-top: 14px;
}

.mkt details summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 15px;
  list-style: none;
}

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

.mkt details summary::before {
  content: "+";
  display: inline-block;
  width: 1em;
  color: #34d399;
  margin-right: 6px;
}

.mkt details[open] summary::before {
  content: "\2013";
}

.mkt details p {
  margin: 12px 0 0;
  font-size: 14px;
  color: #9ca3af;
}

/* Endpoint table */
.mkt table {
  width: 100%;
  margin-top: 24px;
  border-collapse: collapse;
  font-size: 14px;
}

.mkt th,
.mkt td {
  text-align: left;
  padding: 14px;
  border-bottom: 1px solid #1f2937;
  vertical-align: top;
}

.mkt th {
  color: #9ca3af;
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.mkt td code,
.mkt p code {
  background: #1f2937;
  border-radius: 4px;
  padding: 2px 7px;
  font-size: 13px;
  white-space: nowrap;
}

.mkt pre.sample {
  margin: 24px 0 0;
  padding: 20px 22px;
  border: 1px solid #1f2937;
  border-radius: 12px;
  background: #111827;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1.6;
  color: #a7f3d0;
  overflow-x: auto;
}

/*
 * Pipeline stepper.
 *
 * Earlier version used six bordered tiles with little arrow wedges between
 * them. Two problems: at typical viewport widths six tiles plus arrows barely
 * fit on one row (and wrapped messily when they didn't), and every tile had
 * its own dark background which made the row read as six floating boxes
 * rather than one connected flow.
 *
 * Current design: a single horizontal row that never wraps. A continuous
 * gradient line runs behind the icon circles (drawn by the container's
 * ::before at the icon centerline) so the steps read as stages of one
 * process. On narrow viewports the whole row scrolls horizontally — better
 * than wrapping arrows into nothing.
 */
.mkt .pipeline {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
  margin-top: 26px;
  padding: 28px 20px 22px;
  border: 1px solid #1f2937;
  border-radius: 14px;
  background: linear-gradient(180deg, #1f2937 0%, #162032 100%);
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: #374151 transparent;
}

/* Continuous flow line behind the icons. Drawn on the container so it spans
   the full row including between steps; the icon circles sit on top of it. */
.mkt .pipeline::before {
  content: "";
  position: absolute;
  /* The container has padding; position the line at the icon vertical center.
     Icon = 88px, label gap 10px, label ~16px → icon center ≈ 28 + 44 = 72. */
  top: 72px;
  left: 60px;
  right: 60px;
  height: 2px;
  background: linear-gradient(90deg, #374151 0%, #34d399 50%, #10b981 100%);
  border-radius: 2px;
  /* Hide the line under the first and last icons themselves so it visually
     starts and ends inside a circle, not poking out. */
  z-index: 0;
}

/* position: relative so the ::before line is anchored to the container, not
   the nearest positioned ancestor. */
.mkt .pipeline {
  position: relative;
}

.mkt .pipeline-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  position: relative;
  z-index: 1; /* above the ::before line */
  flex: 1 0 auto; /* allow horizontal scroll: never shrink, can grow */
  min-width: 92px;
}

/* The icon circle. The <img> lives inside this, with the icon glyph on a
   transparent bg (the dark panel rect was stripped from the SVGs so they
   blend with the circle). */
.mkt .pipeline-circle {
  width: 88px;
  height: 88px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0b1220;
  border: 1px solid #374151;
  position: relative;
  /* Subtle inner ring so the icons visually sit on the flow line rather
     than floating above it. */
  box-shadow: 0 0 0 4px rgba(15, 23, 42, 1);
}

.mkt .pipeline-circle img {
  width: 56px;
  height: 56px;
  display: block;
}

/* Step number badge (top-right of each circle). Gives the order at a glance,
   which the icon-only design otherwise loses. */
.mkt .pipeline-circle::before {
  content: attr(data-step);
  position: absolute;
  top: -6px;
  right: -6px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #0f172a;
  color: #9ca3af;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #374151;
  font-family: ui-sans-serif, system-ui, sans-serif;
}

.mkt .pipeline-step span {
  font-size: 12px;
  font-weight: 600;
  color: #d1d5db;
  text-align: center;
  white-space: nowrap;
  letter-spacing: 0.01em;
}

/* Final step ("Colored zone") — green ring + green badge to mark the
   destination of the flow. */
.mkt .pipeline-step--final .pipeline-circle {
  border-color: #34d399;
  background: #052e26;
}

.mkt .pipeline-step--final .pipeline-circle::before {
  background: #34d399;
  color: #052e26;
  border-color: #34d399;
}

.mkt .pipeline-step--final span {
  color: #34d399;
  font-weight: 700;
}

/* Coverage grid */
.mkt .coverage {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 22px;
}

.mkt .chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid #1f2937;
  background: #111827;
  font-size: 13px;
  color: #d1d5db;
}

.mkt .chip .flag {
  font-size: 15px;
}

/* Footer */
.mkt footer {
  padding: 40px 0 56px;
  font-size: 12px;
  color: #6b7280;
}

.mkt footer .links {
  margin-bottom: 16px;
  font-size: 13px;
}

.mkt footer .links a {
  color: #9ca3af;
  text-decoration: none;
  margin-right: 18px;
}

/* Responsive — tablet */
@media (max-width: 820px) {
  .mkt .hero-grid {
    grid-template-columns: 1fr;
  }

  .mkt .hero-art {
    display: none;
  }
}

/* Responsive — mobile */
@media (max-width: 600px) {
  /*
   * THE HEADER MUST STAY ON ONE LINE.
   *
   * Four items — wordmark, two links and a filled CTA — need exactly 390px of
   * single-line width at these sizes, measured. A 390px phone is therefore the
   * precise width at which every one of them wraps at once: "SafeZone / Map",
   * "Data / API", "Open the / map", all overflowing a 60px bar. It is the first
   * thing a visitor sees and it read as broken.
   *
   * Fixed by shortening rather than by hiding. Nothing is dropped from the nav
   * at any width: a phone must still reach the API page and the chat, and
   * relegating them to the footer means scrolling a 4,400px page to find them.
   * The labels give up their least load-bearing words instead, as the viewport
   * narrows — "Open the map" -> "Open map" -> and only on the very narrowest
   * hardware "SafeZone Map" -> "SafeZone".
   */
  .mkt nav.top .wrap {
    gap: 10px;
    padding: 0 16px;
  }

  /* The wrapping itself. Without this every rule below is cosmetic. */
  .mkt .brand,
  .mkt nav.top a.nav-link,
  .mkt nav.top a.nav-cta {
    white-space: nowrap;
  }

  .mkt .brand {
    font-size: 15px;
    /* Never let the wordmark squeeze the CTA off the bar. */
    flex: 0 1 auto;
    min-width: 0;
  }

  .mkt .brand img {
    width: 22px;
    height: 22px;
  }

  .mkt nav.top a.nav-link {
    font-size: 13px;
    flex: none;
  }

  /* "Data API" -> "API". The nav sits one tap from the page it links to and the
     destination says "Data API" in its own H1, so the qualifier is carried by
     the page rather than by 30px of a 390px bar. */
  .mkt nav.top a.nav-link .nav-tail {
    display: none;
  }

  .mkt nav.top a.nav-cta {
    padding: 7px 11px;
    font-size: 13px;
    flex: none;
  }

  /* Hero adjustments */
  .mkt header.hero {
    padding: 40px 0 32px;
  }

  .mkt .wrap {
    padding: 0 16px;
  }

  .mkt .hero h1 {
    font-size: 28px;
    line-height: 1.12;
  }

  .mkt .hero p.lede {
    font-size: 16px;
  }

  /*
   * No decorative pins on mobile.
   *
   * They are absolutely positioned across the hero, which is fine beside a
   * two-column desktop hero and wrong when the text spans the full width: at
   * 390px pin-2 renders inside the word "population" in the lede and pin-4
   * inside the stats grid. Confirmed with elementFromPoint, not by eye. Hiding
   * two of the six left the other four sitting on the copy.
   */
  .mkt .hero-pins {
    display: none;
  }

  /* Stats — 2x2 grid on mobile */
  .mkt .stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }

  .mkt .stat {
    padding: 14px 16px;
    border-right: none;
    border-bottom: 1px solid #1f2937;
  }

  /* Add right border only on left column items */
  .mkt .stat:nth-child(odd) {
    border-right: 1px solid #1f2937;
  }

  /* Remove bottom border on last row */
  .mkt .stat:nth-last-child(-n+2) {
    border-bottom: none;
  }

  .mkt .stat b {
    font-size: 20px;
  }

  .mkt .stat span {
    font-size: 11px;
  }

  /* Section spacing */
  .mkt section {
    padding: 32px 0;
  }

  .mkt h2 {
    font-size: 22px;
  }

  /* Swatches stack on narrow mobile */
  .mkt .swatches {
    gap: 10px;
  }

  .mkt .swatch {
    flex: 1 1 100%;
    padding: 14px;
  }

  /* Feature cards */
  .mkt .grid {
    gap: 12px;
  }

  .mkt .card {
    padding: 16px;
  }

  /* FAQ */
  .mkt details {
    padding: 14px 16px;
  }

  /* Split section — stack on mobile */
  .mkt .split {
    flex-direction: column;
    text-align: center;
    gap: 16px;
  }

  .mkt .split > div {
    flex: 1 1 auto;
  }

  .mkt .split > div:last-child {
    width: 100%;
  }

  .mkt .split .btn {
    width: 100%;
    text-align: center;
  }

  /* Endpoint table — card layout on mobile */
  .mkt table {
    display: block;
  }

  .mkt table thead {
    display: none;
  }

  .mkt table tbody {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  .mkt table tr {
    display: flex;
    flex-direction: column;
    background: #111827;
    border: 1px solid #1f2937;
    border-radius: 10px;
    padding: 14px;
  }

  .mkt table td {
    padding: 0;
    border: none;
  }

  .mkt table td:first-child {
    margin-bottom: 8px;
  }

  .mkt table td code {
    font-size: 12px;
    display: inline-block;
    padding: 4px 8px;
    word-break: break-all;
    white-space: normal;
  }

  .mkt table td:last-child {
    font-size: 13px;
    color: #9ca3af;
  }

  /* Pipeline on mobile — keep it a single scrollable row, just tighten
     everything. Never wrap: wrapping breaks the "stages of a flow" reading
     and there's no good breakpoint for six steps. */
  .mkt .pipeline {
    gap: 4px;
    padding: 20px 12px 16px;
    -webkit-overflow-scrolling: touch;
  }

  .mkt .pipeline::before {
    /* tighter top offset for the smaller circle: 20 + 32 = 52 */
    top: 52px;
    left: 44px;
    right: 44px;
  }

  .mkt .pipeline-step {
    min-width: 72px;
    gap: 6px;
  }

  .mkt .pipeline-circle {
    width: 64px;
    height: 64px;
    box-shadow: 0 0 0 3px rgba(15, 23, 42, 1);
  }

  .mkt .pipeline-circle img {
    width: 40px;
    height: 40px;
  }

  .mkt .pipeline-circle::before {
    width: 18px;
    height: 18px;
    font-size: 10px;
    top: -4px;
    right: -4px;
  }

  .mkt .pipeline-step span {
    font-size: 10px;
  }

  /* Coverage chips */
  .mkt .coverage {
    gap: 6px;
  }

  .mkt .chip {
    padding: 6px 10px;
    font-size: 12px;
  }

  /* Footer */
  .mkt footer {
    padding: 28px 0 40px;
    text-align: center;
  }

  .mkt footer .links {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8px 16px;
  }

  .mkt footer .links a {
    margin-right: 0;
  }

  /* CTA row on mobile */
  .mkt .cta-row {
    flex-direction: column;
  }

  .mkt .cta-row .btn {
    width: 100%;
    text-align: center;
  }
}

/* Contact modal — scoped under contact-* so it never collides with the
   in-app .modal-* classes used by RequestAreaModal. Mirrors that modal's
   shape: overlay + centered card + same field set + same endpoint. */
.contact-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: max(16px, env(safe-area-inset-top, 0px)) 16px
    max(16px, env(safe-area-inset-bottom, 0px));
  background: rgba(17, 24, 39, 0.6);
  backdrop-filter: blur(3px);
}

.contact-modal {
  width: 100%;
  max-width: 440px;
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  background: #fff;
  border-radius: 14px;
  padding: 24px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
  color: #111827;
}

.contact-modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}

.contact-modal-header strong {
  font-size: 18px;
}

.contact-close {
  border: none;
  background: none;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  color: #6b7280;
  padding: 0;
}

.contact-intro {
  font-size: 13px;
  color: #6b7280;
  margin: 0 0 16px;
}

.contact-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: #374151;
  margin-bottom: 14px;
}

.contact-optional {
  font-weight: 400;
  color: #9ca3af;
}

.contact-label input,
.contact-label textarea {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 11px;
  font: inherit;
  font-size: 16px; /* avoids iOS focus zoom */
  min-height: 44px;
  font-weight: 400;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #fff;
  color: #111827;
}

.contact-label input:focus,
.contact-label textarea:focus {
  outline: none;
  border-color: #10b981;
}

.contact-label textarea {
  resize: vertical;
}

.contact-error {
  font-size: 13px;
  color: #b91c1c;
  margin-bottom: 10px;
  min-height: 1em;
}

.contact-submit {
  width: 100%;
  background: #10b981;
  color: #052e22;
  border: none;
  border-radius: 8px;
  padding: 12px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

.contact-submit:hover:not(:disabled) {
  background: #059669;
}

.contact-submit:disabled {
  opacity: 0.6;
  cursor: progress;
}

/* Inline confirmation toast */
.contact-toast {
  position: fixed;
  left: 50%;
  bottom: calc(32px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%) translateY(20px);
  z-index: 70;
  background: #10b981;
  color: #052e22;
  font-weight: 600;
  padding: 12px 20px;
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s ease;
  max-width: calc(100vw - 32px);
}

.contact-toast--show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ---------------------------------------------------------------------------
   Embed snippet builder (/data). The preview is a real embed in an iframe, so
   the only styling here is the frame around it and the form above it.
   --------------------------------------------------------------------------- */
.mkt .embed-builder {
  margin-top: 20px;
}

.mkt .embed-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 14px;
}

/* Labels in the muted grey of every other secondary text on these pages — the
   contact form's #374151 is for a white card and disappears on #0b1220. */
.mkt .embed-field {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: #9ca3af;
}

.mkt .embed-field--wide {
  display: block;
  max-width: 520px;
}

/* Dark controls, like the app's own fields: #111827 surface, #374151 border,
   #10b981 focus. The previous white slabs were the contact modal's styling —
   right for its white card, an island of light on this #0b1220 page.
   Scaled to the page's controls (14px, ~36px tall) rather than the app's
   mobile rules; the 16px/44px iOS/touch sizing returns on coarse pointers. */
.mkt .embed-field-input {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 7px 10px;
  font: inherit;
  font-size: 14px;
  font-weight: 400;
  border: 1px solid #374151;
  border-radius: 8px;
  background: #111827;
  color: #e5e7eb;
  min-height: 36px;
}

/* iOS zooms the whole page on focus below 16px, and a 36px field is a thin
   target for a thumb — the app's mobile rules, applied only where they are
   needed. */
.mkt .embed-controls .embed-field-input {
  width: auto;
  min-width: 130px;
}

@media (pointer: coarse) {
  .mkt .embed-field-input {
    font-size: 16px;
    min-height: 44px;
  }
}

/* Selects are clickable controls, not text fields — same affordance the app's
   own .country-select gives. */
.mkt select.embed-field-input {
  cursor: pointer;
}

.mkt .embed-field-input:hover {
  border-color: #4b5563;
}

.mkt .embed-field-input:focus {
  outline: none;
  border-color: #10b981;
  /* A ring rather than a lone border change: on a dark surface a same-hue
     border alone is easy to lose, and this control has no label above it. */
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.18);
}

.mkt .embed-field-input::placeholder {
  color: #6b7280;
}

/* Says what a pasted link was understood to mean — or that it was not one. */
.mkt .embed-link-status {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  font-weight: 400;
  color: #9ca3af;
  min-height: 1em;
}

/* The preview stands alone — no tray around it. It is the product at its
   default snippet size (600×400), shrunk to fit a narrow viewport, with the
   same soft shadow .hero-art carries. */
.mkt .embed-preview {
  display: block;
  width: 600px;
  height: 400px;
  max-width: 100%;
  margin-top: 18px;
  border: 1px solid #1f2937;
  border-radius: 8px;
  background: #0b1220;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
}

/* The snippet block, styled as the page's other code insets (.sample,
   .formula): bordered dark panel, not a bare slab. Position: relative is the
   anchor for the copy button; the overflow lives on the <code> below, not
   here — a button absolutely positioned inside a scrolling element would
   scroll away with the snippet. */
.mkt .embed-code-wrap {
  position: relative;
  margin: 14px 0 0;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid #1f2937;
  background: #0f172a;
  color: #e2e8f0;
  font-size: 12.5px;
  line-height: 1.55;
}

.mkt .embed-code {
  display: block;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: pre;
  overflow-x: auto;
  /* Room so a scrolling snippet's line-end never slides under the copy
     button parked above it. */
  padding-right: 40px;
}

/* The copy button lives inside the code container, top-right, the way every
   code block on GitHub and in every docs site does it — where the thing it
   copies is. Icon-only with a title, because "Copy" beside a copy glyph is
   the glyph explained twice. Swaps to a check on success; on clipboard
   failure it leaves the snippet selected for ⌘C instead. */
.mkt .embed-copy {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid #374151;
  border-radius: 6px;
  background: #111827;
  color: #9ca3af;
  cursor: pointer;
}

.mkt .embed-copy:hover {
  color: #e5e7eb;
  border-color: #4b5563;
}

.mkt .embed-copy:focus-visible {
  outline: none;
  border-color: #10b981;
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.18);
}

.mkt .embed-note {
  margin-top: 10px;
  font-size: 13px;
}

/*
 * Narrower phones: the header gives up words, in order of how little they carry.
 *
 * Thresholds are where the bar actually stops fitting at the sizes above, not
 * round numbers: "Open the map" -> "Open map" buys ~28px, and dropping "Map"
 * from the wordmark buys ~38px more, which is what keeps a 320px screen on one
 * line. Both are measured in apps/web/public/marketing.css's own terms — see
 * the header note in the 600px block.
 */
@media (max-width: 460px) {
  .mkt nav.top a.nav-cta .cta-tail {
    display: none;
  }
}

@media (max-width: 370px) {
  /* The wordmark keeps its own space: .brand is a flex container, so the two
     words must stay inside ONE child or the flex gap doubles the space between
     them at every width, desktop included. */
  .mkt .brand .brand-name .brand-tail {
    display: none;
  }

  .mkt nav.top .wrap {
    gap: 8px;
  }
}
