/* ============================================================
   core.css — Vox Ordo shared component layer
   ------------------------------------------------------------
   The recurring, PROVEN components that the washed live pages
   (pricing / signup / onboarding-flow / checkout / connect-
   anthropic / billing) each re-invented inline — extracted ONCE
   into class-based primitives so future pages @import instead of
   copy-pasting.

   DEPENDS ON TOKENS. This file references ONLY the design-token
   custom properties declared in styles.css (fonts · colors ·
   typography · spacing · motion) and their semantic aliases
   (--bg, --fg, --accent, --border, …). It declares NO tokens of
   its own and NO raw hex where a token exists.

   LOAD ORDER (both required, in this order):
     <link rel="stylesheet" href="/static/vox-ds/styles.css">
     <link rel="stylesheet" href="/static/vox-ds/components/core.css">
   styles.css MUST load first — it defines every var() used below.

   NAMING. Every class is `vo-`prefixed so it never collides with a
   page's own local styles. Modifiers use `--mod`; states use `.is-*`.

   MOTION. motion.css already ships a global prefers-reduced-motion
   guard that neutralises animation + transition; this file does not
   re-declare it and must not fight it.
   ============================================================ */

/* ============================================================
   BUTTONS
   ------------------------------------------------------------
   Base + three faces. Chrome is the ONE shine in the system
   (brushed-steel CTA); it lifts -1px on hover and nudges back on
   press. Outline + ghost are hairline; ghost gains an amber edge
   on hover. Brand: chrome CTA is the only shine · amber = hover.
   ============================================================ */
.vo-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  line-height: 1;
  color: var(--fg);
  background: transparent;
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-sm);
  padding: 11px 16px;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
  transition: filter var(--dur-base) var(--ease-out),
              transform var(--dur-instant) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out);
}
.vo-btn:disabled,
.vo-btn.is-disabled {
  filter: grayscale(0.6);
  opacity: 0.6;
  cursor: not-allowed;
}
.vo-btn:active:not(:disabled) { transform: translateY(1px); }

/* Chrome — the brushed-steel primary CTA face. The system's one shine. */
.vo-btn--chrome {
  color: var(--accent-fg);
  background: var(--vo-chrome);
  border: 0;
  box-shadow: 0 0 0 1px var(--vo-chrome-edge) inset;
}
.vo-btn--chrome:hover:not(:disabled) {
  filter: brightness(1.1);
  transform: translateY(-1px);           /* lift on hover */
}
.vo-btn--chrome:active:not(:disabled) { transform: translateY(0); }

/* Outline — hairline face; border firms toward amber on hover. */
.vo-btn--outline {
  color: var(--fg);
  border-color: var(--border-strong);
}
.vo-btn--outline:hover:not(:disabled) { border-color: var(--border-hover); }

/* Ghost — quietest; amber hover edge + text brightens muted→fg. */
.vo-btn--ghost {
  color: var(--fg-muted);
  border-color: transparent;
}
.vo-btn--ghost:hover:not(:disabled) {
  color: var(--fg);
  border-color: var(--border-hover);     /* amber edge */
}

/* Mono label variant — uppercase tracked, for system-labelled CTAs
   (the tier-cta pattern on pricing). Compose with --outline. */
.vo-btn--mono {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

/* ============================================================
   CARD / PANE
   ------------------------------------------------------------
   Card = marketing/dialog surface (radius-lg, inset top highlight
   via shadow-card). Pane = workspace surface (radius-md); it rings
   cyan only when live (.is-active) — glow is reserved for state.
   ============================================================ */
.vo-card {
  background: var(--surface-card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-8);
}
/* Premium card — pearl 1px ring (chrome edge) over the card shadow. */
.vo-card--premium {
  border-color: var(--border-strong);
  box-shadow: 0 0 0 1px var(--vo-chrome-edge), var(--shadow-card);
}

.vo-pane {
  background: var(--bg-card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  transition: border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.vo-pane:hover { border-color: var(--border-hover); }
.vo-pane.is-active {
  border-color: var(--border-active);    /* cyan */
  box-shadow: var(--glow-active);
}

/* ============================================================
   STATUS DOT
   ------------------------------------------------------------
   Status is a colored dot, never an icon or emoji. Online pulses
   with the runner heartbeat; the rest are steady.
   ============================================================ */
.vo-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--fg-muted);
  flex: none;
  vertical-align: middle;
}
.vo-dot--online { background: var(--vo-online); animation: vo-runner-pulse var(--loop-pulse) ease-out infinite; }
.vo-dot--active { background: var(--vo-active); }
.vo-dot--warn   { background: var(--vo-warn); }
.vo-dot--error  { background: var(--vo-error); }
.vo-dot--gpu    { background: var(--vo-gpu); }
.vo-dot--disk   { background: var(--vo-disk); }

/* ============================================================
   CHIP / PILL
   ------------------------------------------------------------
   Pill-shaped tracked mono label. Optionally leads with a .vo-dot.
   --mono lifts it to uppercase system-label register.
   ============================================================ */
.vo-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-label);
  color: var(--fg-muted);
  background: transparent;
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-pill);
  padding: 4px 11px;
  white-space: nowrap;
}
.vo-chip--mono { text-transform: uppercase; letter-spacing: var(--tracking-eyebrow); }

/* ============================================================
   EYEBROW / LABEL
   ------------------------------------------------------------
   Tiny mono uppercase kicker over a heading. Widely tracked.
   ============================================================ */
.vo-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--fg-dim);
}

/* ============================================================
   GAUGE BAR
   ------------------------------------------------------------
   The agent-hours meter — a thin static track + fill. Set the fill
   with `style="--vo-fill:42%"` (or an inline width on the fill).
   ============================================================ */
.vo-gauge {
  height: 5px;
  border-radius: var(--radius-pill);
  background: var(--border-soft);
  overflow: hidden;
}
.vo-gauge__fill {
  display: block;
  height: 100%;
  width: var(--vo-fill, 0%);
  border-radius: var(--radius-pill);
  background: var(--fg-muted);
}
.vo-gauge__fill--accent { background: var(--fg); }

/* ============================================================
   INPUT
   ------------------------------------------------------------
   Recessed well; cyan focus ring (active hue + active glow).
   ============================================================ */
.vo-input {
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--fg);
  background: var(--bg-input);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  transition: border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.vo-input::placeholder { color: var(--fg-dim); }
.vo-input:focus {
  outline: none;
  border-color: var(--border-active);
  box-shadow: 0 0 0 3px var(--vo-active-glow);
}

/* ============================================================
   KBD
   ------------------------------------------------------------
   Bordered mono chip for a key glyph.
   ============================================================ */
.vo-kbd {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--fg-muted);
  background: var(--bg-input);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-xs);
  padding: 1px 5px;
}

/* ============================================================
   TOAST
   ------------------------------------------------------------
   Slide-in status card. Soft shadow, left-edge state color + a
   matching dot. (Mirrors the runtime toast.js contract so the same
   markup works with or without the script.)
   ============================================================ */
.vo-toast {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-width: 240px;
  max-width: 440px;
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--fg);
  background: var(--bg-card);
  border: var(--border-width) solid var(--border);
  border-left: 3px solid var(--fg-muted);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-toast);
  padding: 10px 12px 10px 14px;
}
.vo-toast .vo-dot { width: 8px; height: 8px; }
.vo-toast--info    { border-left-color: var(--vo-info); }
.vo-toast--success { border-left-color: var(--vo-online); }
.vo-toast--warn    { border-left-color: var(--vo-warn); }
.vo-toast--error   { border-left-color: var(--vo-error); }

/* ============================================================
   NAV / TOPBAR
   ------------------------------------------------------------
   Sticky chrome that the cockpit reads through — backdrop blur
   over a translucent near-black, hairline underline, --topbar-h.
   ============================================================ */
.vo-topbar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  height: var(--topbar-h);
  padding: 0 var(--space-6);
  background: var(--vo-chrome-bg);  /* translucent backdrop for the blur pane */
  border-bottom: var(--border-width) solid var(--border);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  user-select: none;
}
.vo-topbar__spacer { flex: 1; }
.vo-topbar__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--fg);
}

/* ============================================================
   ORB MARK
   ------------------------------------------------------------
   The brand glyph — concentric voice-rings + a core dot, drawn
   with currentColor so it themes monochrome. The whole mark
   breathes at rest (vo-breathe). `.is-listening` expands a ring
   (vo-ring). Drop the assets/orb-mark.svg inline as the child.
   ============================================================ */
.vo-orb {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  color: var(--accent);
}
.vo-orb svg { width: 100%; height: 100%; }
.vo-orb__core { animation: vo-breathe var(--loop-breathe) var(--ease-in-out) infinite; }
/* Fallback: if no __core marked, breathe the whole mark. */
.vo-orb:not(:has(.vo-orb__core)) svg { animation: vo-breathe var(--loop-breathe) var(--ease-in-out) infinite; }
.vo-orb::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-pill);
  border: var(--border-width) solid currentColor;
  opacity: 0;
  pointer-events: none;
}
.vo-orb.is-listening::after { animation: vo-ring var(--loop-pulse) var(--ease-in-out) infinite; }
/* Live runner — green heartbeat around the mark. */
.vo-orb--live { color: var(--vo-online); }
.vo-orb--live::after { animation: vo-runner-pulse var(--loop-pulse) ease-out infinite; opacity: 1; }

/* ============================================================
   HAIRLINE DIVIDER
   ============================================================ */
.vo-rule {
  border: 0;
  border-top: var(--border-width) solid var(--border-soft);
  margin: var(--space-8) 0;
}
.vo-rule--strong { border-top-color: var(--border); }

/* ============================================================
   LEDGER / TAPE ROW
   ------------------------------------------------------------
   The signed-ledger "tape" repeated on pricing + billing — a mono
   run of time · description · amount · SIGNED, over the deepest
   surface. Static/illustrative by default; never render as live
   without the honesty caveat the pages carry.
   ============================================================ */
.vo-ledger {
  background: var(--vo-void);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.vo-tape {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}
.vo-tape__row {
  display: flex;
  gap: var(--space-5);
  align-items: baseline;
  flex-wrap: wrap;
  color: var(--fg-muted);
}
.vo-tape__time { color: var(--fg-dim); }
.vo-tape__spacer { flex: 1; }
.vo-tape__amt { color: var(--fg); }
.vo-tape__sig { color: var(--fg-faint); letter-spacing: var(--tracking-label); }
