/* Digible.ai marketing — port of the Claude Design project
 * "Digible.ai homepage redesign" (e2233010-cdd0-4537-b603-36240535f3c7).
 *
 * The design's four `.dc.html` files are Design Canvas documents: they run a
 * React-based runtime (`support.js` + `_ds_bundle.js`) that resolves
 * `<x-import>` component tags, `<sc-for>` loops, and `{{ }}` bindings from a
 * `DCLogic` class. That runtime is a design tool, not a production dependency,
 * and this site is static objects on GCS with no build step — so the port
 * replaces it rather than shipping it.
 *
 * WHAT WAS PORTED, AND HOW FAITHFULLY:
 *
 * - Every inline `style="…"` from the design is copied VERBATIM onto the same
 *   element. That is deliberate: it makes a diff against the source mechanical
 *   rather than a matter of judgement. Do not "tidy" them into classes.
 * - `style-hover="…"` is a DC attribute with no browser meaning. Each one
 *   became a real `:hover` rule below, keyed by a `data-h` attribute so the
 *   pairing with its element stays visible.
 * - The three DS components used — Wordmark, Button, ConstellationField — were
 *   ported from `_ds_bundle.js` to markup + CSS + (for the field) JS. Their
 *   values are transcribed, not approximated.
 * - `<sc-for>` loops were expanded from the `renderVals()` data, so the markup
 *   holds what the design would have rendered.
 *
 * DELIBERATE DEVIATIONS, all noted where they occur:
 *
 * 1. Fonts are SELF-HOSTED from `fonts/`, not `@import`ed from
 *    fonts.googleapis.com as `tokens/fonts.css` does. A third-party font
 *    request on the page Google's verification crawler must always reach is a
 *    dependency and a disclosure this site does not need.
 * 2. `.dc.html` cross-links became real routes (`/`, `/privacy/`, `/terms/`).
 * 3. `prefers-reduced-motion` is honored per-animation rather than by the
 *    export's blanket `*{animation:none!important}`.
 */

/* ── Fonts. Inter 400–700 (variable), Poppins 600 (wordmark only),
      JetBrains Mono 400 (literals: the 404 kicker, the legal dates). ── */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/inter-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/poppins-600-latin.woff2") format("woff2");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-latin.woff2") format("woff2");
}

/* ── Tokens, transcribed from the project's tokens/colors.css. Names are the
      designer's export names (unprefixed), not this repo's `cx-` ones — the
      design references them directly. ── */

:root {
  --bg-page: #020617;
  --bg-screen: #0c1222;
  --bg-space: #05061a;
  --surface-card: #0f172a;
  --surface-field: rgba(15, 23, 42, 0.7);
  --fill-muted: #1e293b;
  --text-strong: #f1f5f9;
  --text-bright: #e2e8f0;
  --text-body: #cbd5e1;
  --text-muted: #94a3b8;
  --text-faint: #64748b;
  --text-ghost: #475569;
  --text-on-cta: #ffffff;
  --border: #334155;
  --border-strong: #475569;
  --border-soft: #1e293b;
  --border-hover: #64748b;
  --teal-bright: #2dd4bf;
  --teal-text: #5eead4;
  --purple-text: #c4b5fd;
  --purple-hover: #e9d5ff;
  --success: #22c55e;
  --grad-cta: linear-gradient(135deg, #6d28d9, #0f766e);
  --shadow-cta: 0 10px 26px rgba(2, 6, 23, 0.6);
  --focus-ring: 0 0 0 3px rgba(45, 212, 191, 0.16);
  --radius-panel: 12px;
  --radius-sm: 10px;
  --font-sans: "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;
}

/* ── Keyframes, transcribed from tokens/animations.css. Only the ones these
      four pages actually use, plus the two the homepage defines inline. ── */

@keyframes stepUp {
  0% {
    opacity: 0;
    transform: translateY(7px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes heroIn {
  0% {
    opacity: 0;
    transform: translateY(10px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

@keyframes fxA {
  0%,
  100% {
    transform: translate3d(0, 0, 0);
  }
  50% {
    transform: translate3d(26px, -18px, 0);
  }
}

@keyframes fxB {
  0%,
  100% {
    transform: translate3d(0, 0, 0);
  }
  50% {
    transform: translate3d(-22px, 20px, 0);
  }
}

@keyframes fxC {
  0%,
  100% {
    transform: translate3d(0, 0, 0);
  }
  50% {
    transform: translate3d(14px, 24px, 0);
  }
}

@keyframes fxTwinkle {
  0%,
  100% {
    opacity: 0.25;
  }
  50% {
    opacity: 0.9;
  }
}

@keyframes fxLine {
  0%,
  100% {
    opacity: 0.06;
  }
  50% {
    opacity: 0.3;
  }
}

@keyframes fxBloom {
  0%,
  100% {
    transform: translate3d(0, 0, 0) scale(1);
  }
  50% {
    transform: translate3d(40px, 26px, 0) scale(1.12);
  }
}

/* ── Page base. Copied from each design file's inline <style>. The two legal
      pages and the homepage use `--bg-page`; the 404 uses `--bg-space`, set on
      that page itself. ── */

html,
body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text-body);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--purple-text);
  text-decoration: none;
}

a:hover {
  color: var(--purple-hover);
}

/* ── Legal section numbers. DELIBERATE DEVIATION 4: the design renders
      "1. Two roles…" as one run of heading text, at heading weight and colour.
      The numbers stay — they are the documents' addressing scheme, and Terms
      §18's survival list ("Sections 5, 9, 10, 13–16, and 18 survive") cannot
      be written without them, counsel's markup arrives as section numbers, and
      docs/legal/review-notes.md cites them 73 times. But they are apparatus
      rather than title, so they read faint and small and drop out of a scan.

      `display:inline-block` with a `min-width` is what keeps the TITLES
      aligned: `tabular-nums` alone equalises digit widths, not digit COUNTS,
      so "10." would still be wider than "1." and every title from section 10
      down would shift right. Both documents cross that boundary — privacy runs
      to 12, terms to 19. ── */

.legal-num {
  display: inline-block;
  min-width: 1.75em;
  color: var(--text-faint);
  font-size: 0.75em;
  font-weight: 500;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* ── Wordmark. No CSS any more.
 *
 * The first import of this design used the `Wordmark` React component — live
 * text in Poppins with ".ai" tinted — and this file carried a `.ds-wordmark`
 * class to reproduce it. The 2026-09-05 design revision replaced that component
 * with an `<img>` pointing at the PNGs we generated from `src/brand/`, served
 * here at `/brand/wordmark-560.png` with a `2x` srcset.
 *
 * That is a better arrangement than the one it replaced, and worth keeping: the
 * mark on the page, the mark in the design, and the mark uploaded to the Google
 * OAuth consent screen are now literally the same bytes, generated by
 * `bun run build-logo`. Nothing can drift because a font failed to load.
 *
 * `width`/`height` attributes are on every instance so the header does not
 * reflow while the image decodes. ── */

/* ── Button. Ported from components/actions/Button.jsx.
      Sizes: lg 16px/32px · 17px · radius-panel; md 14px/24px · 15.5px ·
      radius-panel. Ghost subtracts 4px from the horizontal padding, which the
      source does with a regex on the padding string. ── */

.ds-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--font-sans);
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  box-sizing: border-box;
  border: 0;
  outline: none;
  transition:
    filter 140ms ease,
    border-color 140ms ease,
    background 140ms ease,
    color 140ms ease,
    box-shadow 140ms ease;
}

.ds-btn[data-size="lg"] {
  padding: 16px 32px;
  font-size: 17px;
  border-radius: var(--radius-panel);
}

.ds-btn[data-size="md"] {
  padding: 14px 24px;
  font-size: 15.5px;
  border-radius: var(--radius-panel);
}

.ds-btn[data-variant="primary"] {
  background: var(--grad-cta);
  color: var(--text-on-cta);
  box-shadow: var(--shadow-cta);
}

.ds-btn[data-variant="primary"]:hover {
  filter: brightness(1.14);
}

.ds-btn[data-variant="secondary"] {
  background: transparent;
  color: var(--text-body);
  border: 1px solid var(--border-strong);
}

.ds-btn[data-variant="secondary"]:hover {
  border-color: var(--border-hover);
}

.ds-btn[data-variant="ghost"] {
  background: transparent;
  color: var(--text-muted);
}

.ds-btn[data-variant="ghost"][data-size="lg"] {
  padding: 16px 28px;
}

.ds-btn[data-variant="ghost"][data-size="md"] {
  padding: 14px 20px;
}

.ds-btn[data-variant="ghost"]:hover {
  background: rgba(51, 65, 85, 0.25);
  color: var(--text-strong);
}

.ds-btn:focus-visible {
  box-shadow: var(--focus-ring);
}

.ds-btn[data-variant="primary"]:focus-visible {
  box-shadow: var(--shadow-cta), var(--focus-ring);
}

/* The hero's primary CTA carries an extra purple glow, passed in the design as
   `glowProps` — `{ style: { boxShadow: '0 12px 30px rgba(109,40,217,0.4)' } }`,
   which replaces the default CTA shadow rather than adding to it. */
.ds-btn[data-glow] {
  box-shadow: 0 12px 30px rgba(109, 40, 217, 0.4);
}

/* ── `style-hover` replacements. Each `data-h` value names the design attribute
      it stands in for, so the pairing survives a re-read of the source. ── */

[data-h="nav-link"] {
  transition: color 140ms cubic-bezier(0.22, 0.9, 0.24, 1);
}

[data-h="nav-link"]:hover,
[data-h="foot-link"]:hover,
[data-h="brand-link"]:hover {
  color: var(--text-strong);
}

[data-h="foot-link"],
[data-h="brand-link"] {
  transition: color 140ms cubic-bezier(0.22, 0.9, 0.24, 1);
}

[data-h="card"] {
  transition: border-color 140ms cubic-bezier(0.22, 0.9, 0.24, 1);
}

[data-h="card"]:hover {
  border-color: var(--border-hover);
}

/* ── Reduced motion. The export blanket-disables every animation; this keeps
      the constellation and marquee still while leaving the entrance fades,
      which carry no motion sickness risk at 7–10px of travel. ── */

@media (prefers-reduced-motion: reduce) {
  .ds-field *,
  .marquee-track {
    animation: none !important;
  }
}
