/* 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); }
/* A row action carrying a WORD rather than an icon. .sig-action is a 32px
   square, so "Edit" and "Remove" overflow it and collide — which is exactly
   what they did on Website Editor → Header & Footer until July 2026, and
   again from September 2026 when this line was dropped in a rewrite of the
   block above. Restored; the only consumer is manage_header_footer.html. */
.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);
}

/* ════════════════════════════════════════════════════════════════════════════
   SMALL SCREENS (added September 2026)
   ----------------------------------------------------------------------------
   Everything above this line was written desktop-only: 567 lines, 713
   consuming templates, and not one media query. These blocks are the small-
   screen half of the same components.

   Two rules govern everything below:

     1. DESKTOP IS UNTOUCHED. Every rule here lives inside a media query that
        cannot match a desktop viewport. Nothing above this line was edited.

     2. 767.98px, not 768px. Tailwind's `md:` is min-width:768px, so a
        max-width:768px query would BOTH apply at exactly 768px and the losing
        one would depend on source order. The .98 leaves no overlap.

   The public site already caps section padding at max-width:768px
   (public_preview_pagebuilder.html); that is a different surface and is left
   as it is.
   ════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 767.98px) {

  /* ── Inputs: 16px, or iOS zooms the page ───────────────────────────────
     Safari on iOS zooms to fit a focused input whose font-size is under
     16px, then leaves the page zoomed — the header is off-screen and the
     user has to pinch back out after every field. --text-body-size is 14px,
     so this affected every .sig-field and every widget-rendered form field
     on the platform (~379 templates).

     The size goes UP on small screens, which is the right direction anyway.
     Desktop keeps 14px. Mirrors the .mobile-input rule that has been sitting
     unused in apps/mobile/templates/mobile/base.html. ── */
  .sig-field,
  .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
  ) {
    font-size: var(--text-input-mobile-size);
  }

  /* ── Tap targets ───────────────────────────────────────────────────────
     .sig-action is 32px square (--space-8) — fine for a cursor, too small
     for a thumb. Buttons get a floor rather than a fixed height so a
     two-line label still grows. ── */
  .sig-action {
    min-width: var(--touch-target-min);
    min-height: var(--touch-target-min);
    width: auto;
    height: auto;
  }
  .sig-btn,
  .sig-btn--sm {
    min-height: var(--touch-target-min);
  }

  /* ── Tabs scroll, they do not wrap ─────────────────────────────────────
     .sig-tabs is a bare flex row with a bottom border. Wrapping breaks the
     border into a ragged stack and moves the page content down by a random
     amount; scrolling keeps one clean rule and one row. ── */
  .sig-tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .sig-tabs::-webkit-scrollbar { display: none; }
  .sig-tab { flex: 0 0 auto; white-space: nowrap; }

  /* ── Stepper: circles scroll, only the current label is shown ──────────
     .sig-stepper is `justify-content: space-between` with flex:1 steps and
     100px labels. At 375px a six-step wizard gives each step ~62px, so
     every label wraps into an unreadable column. Keeping the circles and
     the connectors preserves the "where am I" signal, which is what the
     component is for; the label for the step you are ON is the only one
     worth the width. ── */
  .sig-stepper {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    justify-content: flex-start;
  }
  .sig-stepper::-webkit-scrollbar { display: none; }
  .sig-step {
    flex: 0 0 auto;
    min-width: 72px;
  }
  .sig-step__label { display: none; }
  .sig-step--active .sig-step__label { display: block; }

  /* .sig-touch also applies on a narrow viewport, not only a coarse pointer
     (the `(pointer: coarse)` copy is further down). A control that only
     exists below this breakpoint — a `md:hidden` drawer trigger, say — is a
     phone control whatever the browser reports its pointer to be, and
     headless browsers report `fine`, so the pointer query alone is
     untestable. */
  .sig-touch {
    min-width: var(--touch-target-min);
    min-height: var(--touch-target-min);
  }

  /* ── Containers give their horizontal padding back ─────────────────────
     Vertical padding is kept — that is what stops a card looking cramped —
     but 20px each SIDE of a 375px screen is 11% of the width on nothing, and
     these nest.

     `:not(.sig-panel--flush)` is load-bearing. .sig-panel--flush is
     `padding: 0` (its header and body bring their own), declared far above
     this block, and a bare `.sig-panel` here is the same specificity and
     later in the file — so it silently re-added 16px to every flush panel on
     a phone. That is exactly how the dashboard ended up with a 64px inset. ── */
  .sig-card,
  .sig-panel:not(.sig-panel--flush) {
    padding: var(--space-4) var(--gutter-mobile);
  }
  /* .sig-panel--flush is `padding: 0` — its header and body bring their own —
     but it is declared ABOVE the base .sig-panel rule at the same
     specificity, so the base has always won and a flush panel has never
     actually been flush. Correcting that globally would change desktop, so
     only the horizontal half is put right here, for phones, where 20px on a
     panel that should have none is the difference between a 245px and a
     343px content column. The desktop half is reported, not changed. */
  .sig-panel--flush { padding-left: 0; padding-right: 0; }

  .sig-row           { padding: var(--space-4) var(--gutter-mobile); }
  .sig-list__header  { padding: var(--space-3) var(--gutter-mobile); }
  .sig-panel__header { padding: var(--space-4) var(--gutter-mobile); }

  /* ── The page gutter ───────────────────────────────────────────────────
     `max-w-Nxl mx-auto px-4 sm:px-6 lg:px-8` is the page-container idiom on
     488 dashboard screens. 16px each side is more than a phone can spare
     once anything nests inside it. ── */
  main :is(.max-w-2xl, .max-w-3xl, .max-w-4xl, .max-w-5xl,
           .max-w-6xl, .max-w-7xl, .max-w-full).mx-auto {
    padding-left: var(--gutter-mobile);
    padding-right: var(--gutter-mobile);
  }

  /* ── Block padding ─────────────────────────────────────────────────────
     p-6 and p-8 are 24px and 32px per side. They are container padding: 885
     uses are on a div/section against 3 on a button, and the `:not()` keeps
     the horizontal padding of anything interactive, where it is the tap
     target rather than an inset. Only the horizontal axis is capped. ── */
  main :is(.p-4, .p-5, .p-6, .p-7, .p-8, .p-10, .p-12,
           .px-4, .px-5, .px-6, .px-7, .px-8, .px-10, .px-12
          ):not(a):not(button):not(input):not(select):not(label) {
    padding-left: var(--gutter-mobile);
    padding-right: var(--gutter-mobile);
  }
}

/* ── Full-height screens: 100dvh ──────────────────────────────────────────
   .sig-auth and .sig-screen centre a card in 100vh. On mobile Safari and
   Chrome, 100vh is the height WITHOUT the browser chrome, so the card is
   pushed down and its bottom edge sits under the URL bar. dvh is the live
   value. Declared after the 100vh above it, so a browser without dvh keeps
   the old behaviour rather than losing the rule. Not in a media query — dvh
   and vh are identical on desktop. ── */
.sig-auth,
.sig-screen { min-height: 100dvh; }

/* ── Fluid hero title ─────────────────────────────────────────────────────
   .sig-page-title--hero is a hard 44px, which is ~12% of a 375px viewport
   per line. clamp caps at the same 44px, so every viewport at or above
   ~629px renders exactly as it does today. ── */
.sig-page-title--hero { font-size: clamp(28px, 7vw, 44px); }

/* ── Shared small-screen utilities ────────────────────────────────────────
   Opt-in helpers so a screen adds a class instead of inventing its own
   media query. `sig-` namespaced per this file's convention, so they cannot
   collide with a Tailwind utility.

   Deliberately NOT a new stylesheet: templates are bind-mounted and go live
   the moment `git pull` lands, but the static manifest is only rebuilt when
   the container restarts and runs collectstatic. A template referencing a
   brand-new static file inside that window raises "Missing staticfiles
   manifest entry" under CompressedManifestStaticFilesStorage — a 500, not a
   missing stylesheet. This file is already collected and already loaded by
   base.html and 55 of the 56 widget editors. ── */

/* Horizontal scroll container — for wide tables. Inert when the content
   fits, so it is safe at every width and needs no media query. */
.sig-scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}

/* A tap target that is at least a finger wide, on touch devices only.
   Keyed on pointer, not width: a touchscreen laptop needs it and a narrow
   desktop window does not. */
@media (pointer: coarse) {
  .sig-touch {
    min-width: var(--touch-target-min);
    min-height: var(--touch-target-min);
  }
}

/* Bottom padding that clears the iOS home indicator / gesture bar. */
.sig-safe-b { padding-bottom: env(safe-area-inset-bottom, 0px); }
