/* AUTO-GENERATED from /design/signal-primitives.css by scripts/sync-signal-tokens.js — DO NOT EDIT. */
/* ============================================================
   bLocal · Signal — primitives (CANONICAL SOURCE OF TRUTH)
   ------------------------------------------------------------
   Hand-written, token-driven component classes. Generated copies live in
   backend/static/css/ and frontend/src/app/ — edit THIS file, then run
   `npm run sync:tokens`. Every value below resolves to a Signal token from
   signal-tokens.css — NO hard-coded colours/spacing/radii here.

   Stage 3 scope: only the primitives the Articles-list proving slice needs —
   list/row, status pill, button, input/select. (Tabs, cards, AI button: later.)
   `sig-` namespace so these never collide with Tailwind/utility classes; they
   are inert until a template opts in, so loading this file changes nothing.
   ============================================================ */

/* ── Button — primary / secondary / ghost / destructive ──────────── */
.sig-btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-label-size); font-weight: var(--text-label-weight);
  line-height: var(--text-label-leading);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer; text-decoration: none;
  transition: background-color var(--motion-base) var(--ease-standard),
              border-color var(--motion-base) var(--ease-standard),
              color var(--motion-base) var(--ease-standard);
}
.sig-btn--sm { padding: var(--space-1) var(--space-3); }
/* ── CTA modifier — larger + a bold border, for a page's primary
   "Add/Create" action where sig-btn--primary alone reads too quiet
   against the black-border card language used elsewhere in the app. ── */
.sig-btn--cta {
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-body-size);
  font-weight: 700;
  border-width: 2px;
  border-color: var(--color-text-strong);
}

.sig-btn--primary {
  background: var(--color-accent); color: var(--color-text-on-accent);
  box-shadow: var(--shadow-button);
}
.sig-btn--primary:hover  { background: var(--color-accent-hover); }
.sig-btn--primary:active { background: var(--color-accent-active); }
.sig-btn--primary:disabled,
.sig-btn--primary[aria-disabled="true"] {
  background: var(--color-accent-disabled); cursor: default; box-shadow: none;
}

.sig-btn--secondary {
  background: var(--color-surface-raised);
  border-color: var(--color-border);
  color: var(--color-text-body);
}
.sig-btn--secondary:hover { background: var(--color-surface-sunken); }

.sig-btn--ghost {
  background: var(--color-accent-tint); color: var(--color-accent-text);
}
.sig-btn--ghost:hover { background: var(--color-accent-tint-strong); }

.sig-btn--destructive {
  background: var(--color-surface-raised);
  border-color: var(--color-error-border);
  color: var(--color-error);
}
.sig-btn--destructive:hover { background: var(--color-error-bg); }

/* ── AI / generative button — Signal "Direction A" (generative-in-green).
   The ONE unified generative family; replaces the ad-hoc rainbow AI buttons.
   Same green accent as primary; AI is carried by the ✦ mark + a subtle same-hue
   sheen (no hue change). Operator/backend UI only. A leading ✦ is added
   automatically — drop the old per-button icon when migrating onto this. ── */
.sig-btn--ai {
  background: linear-gradient(160deg, var(--color-accent-hover), var(--color-accent));
  color: var(--color-text-on-accent);
  box-shadow: var(--shadow-button);
}
.sig-btn--ai::before { content: "\2726"; margin-right: var(--space-1); font-size: 0.95em; line-height: 1; }
.sig-btn--ai:hover  { background: var(--color-accent-hover); }
.sig-btn--ai:active { background: var(--color-accent-active); }
.sig-btn--ai:disabled, .sig-btn--ai[aria-disabled="true"] {
  background: var(--color-accent-disabled); box-shadow: none; cursor: default;
}

.sig-btn:focus-visible {
  outline: var(--focus-border-width) solid var(--focus-border-color);
  outline-offset: 1px;
  box-shadow: 0 0 0 var(--focus-ring-width) var(--color-focus-ring);
}

/* ── Auth (centered credential screens: login / signup / verify) ──── */
.sig-auth {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-bg);
  padding: var(--space-8) var(--space-4);
}
.sig-auth__card { width: 100%; max-width: 400px; }
.sig-auth__icon { color: var(--color-accent); text-align: center; }
.sig-auth__title {
  font-family: var(--font-display);
  font-size: var(--text-h1-size); font-weight: var(--text-h1-weight);
  line-height: var(--text-h1-leading); letter-spacing: var(--text-h1-tracking);
  color: var(--color-text-strong); text-align: center;
}
.sig-auth__subtitle {
  font-family: var(--font-body);
  font-size: var(--text-body-sm-size); color: var(--color-text-muted);
  text-align: center;
}

/* ── Link + checkbox + labelled divider (reusable across archetypes) ─ */
.sig-link {
  color: var(--color-accent-text); font-weight: var(--text-label-weight);
  text-decoration: none;
}
.sig-link:hover { color: var(--color-accent); text-decoration: underline; }
.sig-checkbox {
  accent-color: var(--color-accent);
  width: var(--space-4); height: var(--space-4);
}
.sig-divider {
  display: flex; align-items: center; gap: var(--space-3);
  color: var(--color-text-faint);
  font-family: var(--font-body); font-size: var(--text-caption-size);
}
.sig-divider::before, .sig-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--color-border);
}

/* ── Screen — generic centered single-card screen (confirm / error / empty / success).
      (sig-auth is a candidate to fold into sig-screen in a later consolidation.) ── */
.sig-screen {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-bg);
  padding: var(--space-8) var(--space-4);
}

/* ── Confirm / destructive dialog (Cancel = sig-btn--secondary, action = sig-btn--destructive) ── */
.sig-confirm__icon {
  background: var(--color-error-bg); color: var(--color-error);
  border-radius: var(--radius-pill);
}
.sig-confirm__title {
  font-family: var(--font-display);
  font-size: var(--text-h2-size); font-weight: var(--text-h2-weight);
  line-height: var(--text-h2-leading);
  color: var(--color-text-strong);
}
.sig-confirm__text {
  font-family: var(--font-body);
  font-size: var(--text-body-size); line-height: var(--text-body-leading);
  color: var(--color-text-muted);
}

/* ── Inset panel — sunken detail box (reusable: confirm details, form sections) ── */
.sig-inset {
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}

/* ── Panel header/flush variant — panels with a divided header + own-padding body ── */
.sig-panel--flush { padding: 0; }
.sig-panel__header {
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--color-divider);
}

/* ── Section heading (h2) — generic, reusable across archetypes ─────── */
.sig-section-title {
  font-family: var(--font-display);
  font-size: var(--text-h2-size); font-weight: var(--text-h2-weight);
  line-height: var(--text-h2-leading);
  color: var(--color-text-strong);
}

/* ── Body text — generic, reusable everywhere (rounds out the type set).
      Candidates to fold in later: sig-confirm__text, sig-page-subtitle. ── */
.sig-text {
  font-family: var(--font-body);
  font-size: var(--text-body-size); line-height: var(--text-body-leading);
  color: var(--color-text-body);
}
.sig-text--muted  { color: var(--color-text-muted); }
.sig-text--strong { color: var(--color-text-strong); }

/* ── sig-text sets its own explicit color, which normally wins over a
   hover:text-white utility on an ancestor (direct rule beats inherited
   value). Force white back on when that hover state is active, so
   .hover\:bg-black .hover\:text-white sibling cards stay legible. ── */
.hover\:text-white:hover .sig-text,
.hover\:text-white:hover .sig-text--muted,
.hover\:text-white:hover .sig-text--strong {
  color: #fff;
}

/* ── Top hairline (complement to sig-panel__header) — section separators ── */
.sig-divider-t { border-top: 1px solid var(--color-divider); }

/* ── Tabs (STATEFUL) — Website-Editor tab system. Per Signal Primitive→token spec:
      active  = accent text · 2.5px accent underline · weight 700
      default = text-muted · weight 500
   Toggle .sig-tab--active in JS to switch state. ── */
.sig-tabs {
  display: flex; gap: var(--space-1);
  border-bottom: 1px solid var(--color-border);
}
.sig-tab {
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-body); font-size: var(--text-label-size); font-weight: 500;
  color: var(--color-text-muted);
  background: none; border: 0; cursor: pointer;
  border-bottom: 2.5px solid transparent; margin-bottom: -1px;
  transition: color var(--motion-base) var(--ease-standard),
              border-color var(--motion-base) var(--ease-standard);
}
.sig-tab:not(.sig-tab--active):hover { color: var(--color-text-body); }
.sig-tab--active {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
  font-weight: 700;
}

/* ── Wizard stepper (STATEFUL) — progress chrome. States: --active / --completed.
   Circle/connector dimensions (40/20/2px) are component structure, not scale values. ── */
.sig-stepper { display: flex; justify-content: space-between; align-items: center; }
.sig-step {
  display: flex; flex-direction: column; align-items: center;
  flex: 1; position: relative;
}
.sig-step:not(:last-child)::after {
  content: ''; position: absolute; top: 20px; left: 50%;
  width: 100%; height: 2px; background: var(--color-border); z-index: 0;
}
.sig-step--completed::after, .sig-step--active::after { background: var(--color-accent); }
.sig-step__circle {
  width: 40px; height: 40px; border-radius: var(--radius-pill);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-body); font-weight: var(--text-label-weight); font-size: var(--text-body-sm-size);
  z-index: 1;
  background: var(--color-surface-raised);
  border: 2px solid var(--color-border); color: var(--color-text-faint);
  transition: background-color var(--motion-base) var(--ease-standard),
              border-color var(--motion-base) var(--ease-standard),
              color var(--motion-base) var(--ease-standard);
}
.sig-step--completed .sig-step__circle, .sig-step--active .sig-step__circle {
  background: var(--color-accent); border-color: var(--color-accent); color: var(--color-text-on-accent);
}
.sig-step--active .sig-step__circle { box-shadow: 0 0 0 var(--focus-ring-width) var(--color-focus-ring); }
.sig-step__label {
  margin-top: var(--space-2);
  font-family: var(--font-body); font-size: var(--text-caption-size);
  color: var(--color-text-muted); text-align: center; max-width: 100px;
}
.sig-step--active .sig-step__label, .sig-step--completed .sig-step__label {
  color: var(--color-accent-text); font-weight: 500;
}

/* ── Card — generic content card (grids, listings) ─────────────────── */
.sig-card {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
}
.sig-card--interactive { transition: box-shadow var(--motion-base) var(--ease-standard); }
.sig-card--interactive:hover { box-shadow: var(--shadow-md); }
.sig-card__title {
  font-family: var(--font-display);
  font-size: var(--text-h3-size); font-weight: var(--text-h3-weight);
  line-height: var(--text-h3-leading);
  color: var(--color-text-strong);
}

/* ── Stat / KPI card contents (use inside .sig-card) ───────────────── */
.sig-stat__label {
  font-family: var(--font-body);
  font-size: var(--text-label-size); font-weight: var(--text-label-weight);
  color: var(--color-text-muted);
}
.sig-stat__value {
  font-family: var(--font-display);
  font-size: var(--text-display-size); font-weight: var(--text-display-weight);
  line-height: var(--text-display-leading); letter-spacing: var(--text-display-tracking);
  color: var(--color-text-strong);
}
.sig-stat__icon {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-md);
  background: var(--color-accent-tint); color: var(--color-accent);
}

/* ── Input / select — filter bar ─────────────────────────────────── */
.sig-field {
  display: block; width: 100%;
  font-family: var(--font-body);
  font-size: var(--text-body-size); line-height: var(--text-body-leading);
  color: var(--color-text-body);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  transition: border-color var(--motion-base) var(--ease-standard),
              box-shadow var(--motion-base) var(--ease-standard);
}
.sig-field::placeholder { color: var(--color-text-faint); }
.sig-field:focus {
  outline: none;
  border-color: var(--focus-border-color); border-width: var(--focus-border-width);
  box-shadow: 0 0 0 var(--focus-ring-width) var(--color-focus-ring);
}
.sig-field--error { border-color: var(--color-error); }

/* ── Form wrapper (.sig-form) — styles Django WIDGET-rendered fields ({{ form.x }}) by
   ALLOWLIST. Deliberate scoped-element-selector exception to the .sig-*-only rule; wrapped in
   :where() (0 specificity) so explicit classes always win. Allowlist = text-like inputs +
   textarea + select ONLY → checkbox / radio / file / hidden / submit / button / range / color
   are NEVER field-styled (the anti-leak; proven by the nested-controls fixture). ── */
.sig-form :where(
  input:not([type]), input[type="text"], input[type="email"], input[type="password"],
  input[type="number"], input[type="search"], input[type="tel"], input[type="url"],
  input[type="date"], input[type="time"], input[type="datetime-local"],
  input[type="month"], input[type="week"], textarea, select
) {
  display: block; width: 100%;
  font-family: var(--font-body);
  font-size: var(--text-body-size); line-height: var(--text-body-leading);
  color: var(--color-text-body);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  transition: border-color var(--motion-base) var(--ease-standard),
              box-shadow var(--motion-base) var(--ease-standard);
}
.sig-form :where(input, textarea, select)::placeholder { color: var(--color-text-faint); }
.sig-form :where(
  input:not([type]), input[type="text"], input[type="email"], input[type="password"],
  input[type="number"], input[type="search"], input[type="tel"], input[type="url"],
  input[type="date"], input[type="time"], input[type="datetime-local"], textarea, select
):focus {
  outline: none;
  border-color: var(--focus-border-color); border-width: var(--focus-border-width);
  box-shadow: 0 0 0 var(--focus-ring-width) var(--color-focus-ring);
}

/* ── Validation — fitted to Django's real <ul class="errorlist"> + manual .sig-error.
   Field border on error: hand-written uses .sig-field--error; widget forms via [aria-invalid]
   (Django 4.2 doesn't set it — ready for a SignalFormMixin / Django 5+). ── */
.sig-form .errorlist, .sig-error {
  list-style: none; margin: var(--space-1) 0 0; padding: 0;
  color: var(--color-error);
  font-family: var(--font-body); font-size: var(--text-caption-size); line-height: var(--text-caption-leading);
}
.sig-form .errorlist li { margin: 0; }
.sig-form :where(input, textarea, select)[aria-invalid="true"] { border-color: var(--color-error); }

/* ── Help / hint text under a field ── */
.sig-help {
  display: block; margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-family: var(--font-body); font-size: var(--text-caption-size); line-height: var(--text-caption-leading);
}

/* ── File upload — Signal-styled native file input (hand-written .sig-file OR .sig-form file) ── */
.sig-file, .sig-form :where(input[type="file"]) {
  display: block; width: 100%;
  font-family: var(--font-body); font-size: var(--text-body-sm-size);
  color: var(--color-text-muted);
}
.sig-file::file-selector-button,
.sig-form :where(input[type="file"])::file-selector-button {
  font-family: var(--font-body);
  font-size: var(--text-label-size); font-weight: var(--text-label-weight);
  color: var(--color-text-body);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3); margin-right: var(--space-3);
  cursor: pointer;
  transition: background-color var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out);
}
.sig-file::file-selector-button:hover,
.sig-form :where(input[type="file"])::file-selector-button:hover {
  background: var(--color-accent-tint); color: var(--color-accent-text);
}

.sig-label {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-label-size); font-weight: var(--text-label-weight);
  color: var(--color-text-muted);
  margin-bottom: var(--space-1);
}

/* ── Status pill ─────────────────────────────────────────────────── */
.sig-pill {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-family: var(--font-body);
  font-size: var(--text-caption-size); font-weight: var(--text-label-weight);
  line-height: 1;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-pill);
}
.sig-pill--success { color: var(--color-success); background: var(--color-success-bg); }
.sig-pill--warning { color: var(--color-warning); background: var(--color-warning-bg); }
.sig-pill--error   { color: var(--color-error);   background: var(--color-error-bg); }
.sig-pill--info    { color: var(--color-info);     background: var(--color-info-bg); }
.sig-pill--accent  { color: var(--color-accent-text); background: var(--color-accent-tint); }
.sig-pill--neutral { color: var(--color-text-muted); background: var(--color-surface-sunken); }

/* ── Page heading + panel (chrome scaffolding for the slice) ──────── */
.sig-page-title {
  font-family: var(--font-display);
  font-size: var(--text-h1-size); font-weight: var(--text-h1-weight);
  line-height: var(--text-h1-leading); letter-spacing: var(--text-h1-tracking);
  color: var(--color-text-strong);
}
.sig-page-subtitle {
  font-family: var(--font-body);
  font-size: var(--text-body-size); color: var(--color-text-muted);
  margin-top: var(--space-2);
}
/* ── Hero modifier — larger, heavier weight for a page's primary
   list-view header (Articles, Magazines, etc.) where the base
   .sig-page-title reads too quiet. Geist isn't self-hosted yet (no
   @font-face — --font-display silently falls back to sans-serif), so
   this leans on weight 900 + tight tracking to read as "Black" until
   real Geist font files are added. ── */
.sig-page-title--hero {
  font-size: 44px;
  font-weight: 900;
  letter-spacing: -0.03em;
  line-height: 1.05;
}
.sig-panel {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-5);
}

/* ── List / table row family ─────────────────────────────────────── */
.sig-list {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.sig-list ul { list-style: none; margin: 0; padding: 0; }
.sig-list li + li { border-top: 1px solid var(--color-divider); }
.sig-list__header {
  background: var(--color-surface-sunken);
  color: var(--color-text-faint);
  font-family: var(--font-body);
  font-size: var(--text-caption-size); font-weight: var(--text-label-weight);
  text-transform: uppercase; letter-spacing: 0.04em;
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--color-divider);
}
.sig-row {
  /* Padded block CONTAINER — inner markup handles horizontal layout. */
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface-raised);
  color: var(--color-text-body);
}
.sig-row:hover { background: var(--color-surface-sunken); }
.sig-row__title {
  font-family: var(--font-display);
  font-size: var(--text-h3-size); font-weight: var(--text-h3-weight);
  line-height: var(--text-h3-leading);
  color: var(--color-text-strong);
}
.sig-row__title-link { color: inherit; text-decoration: none; }
.sig-row__title-link:hover { color: var(--color-accent-text); }
.sig-row__meta {
  font-size: var(--text-body-sm-size); color: var(--color-text-muted);
  line-height: var(--text-body-sm-leading);
}

/* ── Card-differentiated list variant — each row becomes its own
   bordered card with a gap, instead of one flat container with a
   near-invisible 1px divider (--color-divider is a very light gray
   that reads as "blending together" on longer lists). Opt-in: add
   alongside .sig-list, e.g. class="sig-list sig-list--cards". ── */
.sig-list--cards {
  background: transparent;
  border: none;
  box-shadow: none;
  overflow: visible;
}
.sig-list--cards ul { display: flex; flex-direction: column; gap: var(--space-3); }
.sig-list--cards li + li { border-top: none; }
.sig-list--cards .sig-row {
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.sig-list--cards .sig-row:hover {
  box-shadow: var(--shadow-md);
  background: var(--color-surface-raised);
}

/* ── Bordered card modifier — strengthens .sig-card's near-invisible
   default border for grids where items need to read as clearly
   separate (e.g. dense card grids on white/light-gray page backgrounds). ── */
.sig-card--bordered { border: 1px solid var(--color-text-strong); }

/* ── Media thumbnail tile + overlay dot (semantic: default/video/audio) ─ */
.sig-thumb {
  border-radius: var(--radius-md);
  background: var(--color-accent-tint); color: var(--color-accent-text);
}
.sig-thumb--danger { background: var(--color-error-bg); color: var(--color-error); }
.sig-thumb--info   { background: var(--color-info-bg);  color: var(--color-info); }
.sig-thumb-img { border-radius: var(--radius-md); }
.sig-dot { border-radius: var(--radius-pill); color: var(--color-text-on-accent); }
.sig-dot--danger { background: var(--color-error); }
.sig-dot--info   { background: var(--color-info); }

/* ── Toast (JS-built notification) ───────────────────────────────── */
.sig-toast {
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  color: var(--color-text-on-accent);
}
.sig-toast--success { background: var(--color-accent); }
.sig-toast--error   { background: var(--color-error); }
.sig-toast--info    { background: var(--color-info); }

/* ── Empty state ─────────────────────────────────────────────────── */
.sig-empty__icon { color: var(--color-text-faint); font-size: 48px; }
.sig-empty__title {
  font-family: var(--font-display);
  font-size: var(--text-h3-size); font-weight: var(--text-h3-weight);
  color: var(--color-text-strong);
}

/* ── Row actions — one disciplined family ────────────────────────── */
.sig-action {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--space-8); height: var(--space-8);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  border: 1px solid transparent;
  background: transparent; cursor: pointer; text-decoration: none;
  transition: color var(--motion-fast) var(--ease-out),
              background-color var(--motion-fast) var(--ease-out);
}
.sig-action:hover         { color: var(--color-text-strong); background: var(--color-surface-sunken); }
.sig-action--edit         { color: var(--color-accent-text); }
.sig-action--edit:hover   { color: var(--color-accent); background: var(--color-accent-tint); }
.sig-action--danger       { color: var(--color-error); }
.sig-action--danger:hover { color: var(--color-error); background: var(--color-error-bg); }
.sig-action--text         { width: auto; padding: 0 var(--space-3); }
.sig-action:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--focus-ring-width) var(--color-focus-ring);
}
