/* theme.css -- design tokens (role-based, NEVER raw hex in components).
 *
 * Why this exists: generated apps look "AI-default" because they scatter raw
 * colors and ship only a happy-path light theme. A real designed app uses ROLE
 * tokens (bg, surface, text, primary, ...) referenced everywhere, ships a
 * parallel dark theme from the same variable block, and honors the OS setting.
 * Swapping one block re-themes the whole app. Modern, high-contrast, accessible.
 *
 * Generated by contract-scaffold M3 (general -- no product-specific colors;
 * a strong neutral+indigo default any greenfield app can ship and re-brand).
 */
:root {
  /* Surfaces */
  --bg: #f7f8fa;
  --surface: #ffffff;
  --surface-2: #f0f2f5;
  --border: #e3e6eb;
  /* Text (AA contrast on --bg / --surface) */
  --text: #1a1d24;
  --text-muted: #5a6472;
  /* Brand accent -- a confident modern indigo (re-brand by editing here only) */
  --primary: #5b35e8;
  --primary-contrast: #ffffff;
  --primary-weak: #ece8fd;
  /* Semantic */
  --ok: #1f9d55;
  --warn: #b7791f;
  --danger: #c2333a;
  /* Shape + depth (subtle, not shadow-heavy) */
  --radius: 12px;
  --radius-sm: 8px;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.08);
  --space: 16px;
}

/* Dark theme -- same roles, honored automatically from the OS preference. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1117;
    --surface: #171a21;
    --surface-2: #1e222b;
    --border: #2a2f3a;
    --text: #eef1f6;
    --text-muted: #9aa4b2;
    --primary: #8b6dff;
    --primary-contrast: #0f1117;
    --primary-weak: #241f3d;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.5);
  }
}
/* Explicit override hook (a theme toggle sets data-theme on <html>). */
:root[data-theme="dark"] {
  --bg: #0f1117; --surface: #171a21; --surface-2: #1e222b; --border: #2a2f3a;
  --text: #eef1f6; --text-muted: #9aa4b2; --primary: #8b6dff;
  --primary-contrast: #0f1117; --primary-weak: #241f3d;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: var(--space);
}
.btn-primary {
  background: var(--primary); color: var(--primary-contrast);
  border: none; border-radius: var(--radius-sm);
  padding: 8px 16px; font-weight: 600; cursor: pointer;
}
.btn-primary:hover { filter: brightness(1.05); }

/* --- the three UI states every data surface ships --- */
/* 1. skeleton (loading) -- a shimmer, never a blank flash */
.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--border) 37%, var(--surface-2) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
  border-radius: var(--radius-sm); height: 16px;
}
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
/* 2. empty state -- a dashed invitation with a CTA, never a void */
.empty {
  border: 1px dashed var(--border); border-radius: var(--radius);
  padding: calc(var(--space) * 2); text-align: center; color: var(--text-muted);
}
/* 3. first-run banner -- "you're viewing sample data" so screen 1 is alive */
.first-run {
  background: var(--primary-weak); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 16px; color: var(--text);
  display: flex; align-items: center; gap: 8px; font-size: 14px;
}
