/* AUTO-EXTRACTED from dashboard/index.html by S2-4 (one design system).
   MOVE, NOT REWRITE (C-9): every rule below is byte-identical to its
   source except (a) hard-coded hex -> tokens (SPRINT2_DESIGN §4.2) and
   (b) the .status-pill -> .angle-pill/.listing-pill rename (§4.3's three-step
   handoff: L3 aliased, L2 flipped the JS strings, and SERIAL-LAST has now
   DELETED the alias — verified first that no module or page still emits the
   bare `status-pill` class). Load order matters — see §4.1. */

/* components.css — the shared vocabulary: pills, buttons, toasts, the
   confirm modal, skeletons. Loaded on EVERY page. */
/* ─────────────────────────────────────────────────────────────────────
   Angle status pills — single visual vocabulary across the dashboard.
   ───────────────────────────────────────────────────────────────────── */
.angle-pill{
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase;
  background: var(--glass-edge); color: var(--ink-soft);
  white-space: nowrap;
}
.angle-pill .dot{
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
}
.angle-pill.s-built{ background: var(--pill-neutral-bg); color: var(--pill-neutral-ink); }
.angle-pill.s-approved{ background: color-mix(in oklab, var(--accent) 18%, transparent); color: var(--accent); }
.angle-pill.s-drafted{ background: color-mix(in oklab, var(--warn) 22%, transparent); color: var(--warn); }
.angle-pill.s-published{ background: var(--good-soft); color: var(--good); }
.angle-pill.s-stale{ background: var(--bad-soft); color: var(--bad); animation: stalePulse 2.4s ease-in-out infinite; }
@keyframes stalePulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--bad-soft); }
  50%      { box-shadow: 0 0 0 4px transparent; }
}
/* Photo-on-card pill variant — sits over the hero photo */
.angle-pill.over-photo{
  background: rgba(255,255,255,.94); backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 1px 4px rgba(0,0,0,.16);
}
[data-theme="dark"] .angle-pill.over-photo{ background: rgba(40,42,50,.92); }
/* Status pills — soft entrance + smooth color transition */
.angle-pill{
  transition: background .25s ease, color .25s ease;
  animation: pillIn .32s cubic-bezier(.4,0,.2,1) backwards;
}
/* Toast lift on enter */
.toast {
  animation: toastIn .32s cubic-bezier(.34,1.42,.64,1) backwards;
}
@keyframes toastIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Confirmation modal — shared style for "Push to Facebook" + similar */
.confirm-modal-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.55);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  display: none; align-items: center; justify-content: center;
  z-index: 260; opacity: 0; transition: opacity var(--t-base);
}
.confirm-modal-overlay.show { display: flex; opacity: 1; }
.confirm-modal {
  background: var(--paper); background-image: var(--bg-grad);
  border-radius: var(--r-lg);
  width: min(440px, 92vw);
  padding: 28px;
  box-shadow: var(--shadow-lg);
}
.confirm-modal .icon-circle {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--accent) 18%, transparent);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 16px;
  font-size: 26px;
}
.confirm-modal h2 {
  text-align: center;
  margin: 0 0 8px;
  font-size: 19px; font-weight: 700; color: var(--ink);
}
.confirm-modal .lede {
  text-align: center;
  margin: 0 0 20px;
  font-size: 14px; line-height: 1.45; color: var(--ink-soft);
}
.confirm-modal .lede strong { color: var(--ink); font-weight: 600; }
.confirm-modal .what-happens {
  background: var(--glass-bg);
  border-radius: 9px;
  padding: 12px 14px;
  margin-bottom: 20px;
  font-size: 12px; color: var(--ink-soft); line-height: 1.5;
}
.confirm-modal .what-happens strong { color: var(--ink); }
.confirm-modal .what-happens ul {
  margin: 4px 0 0; padding-left: 18px;
}
.confirm-modal .what-happens li { margin-bottom: 2px; }
.confirm-modal .actions {
  display: flex; gap: 10px;
}
.confirm-modal .actions button {
  flex: 1;
  padding: 11px;
  border-radius: 10px;
  font-size: 13px; font-weight: 700;
  cursor: pointer;
  transition: filter var(--t-fast), background var(--t-fast);
}
.confirm-modal .actions .go-back {
  background: var(--glass-edge); color: var(--ink);
}
.confirm-modal .actions .go-back:hover {
  background: color-mix(in oklab, var(--ink) 10%, transparent);
}
.confirm-modal .actions .confirm {
  background: var(--good); color: white;
  box-shadow: 0 4px 14px -4px color-mix(in oklab, var(--good) 50%, transparent);
}
.confirm-modal .actions .confirm:hover { filter: brightness(1.1); }
.confirm-modal .actions .confirm:disabled { opacity: .6; cursor: wait; }
/* F-12 — NOT a move, a 3-line completion, and it is deliberate.
   confirmDialog({danger:true}) has ALWAYS emitted `.danger-confirm` on the
   confirm button (index.html:8298) but the matching rule was never written,
   so a destructive confirm rendered with the GREEN "this is safe" button.
   S2-4 puts that dialog in front of the LIVE Facebook publish (F-05), which
   makes a green go-button an actively misleading affordance rather than a
   cosmetic gap — so the missing rule ships with the dialog that needs it. */
.confirm-modal .actions .confirm.danger-confirm {
  background: var(--bad);
  box-shadow: 0 4px 14px -4px color-mix(in oklab, var(--bad) 50%, transparent);
}
.btn-publish {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 22px;
  border-radius: 14px;
  background: var(--accent);
  color: white; font-size: 13px; font-weight: 700; letter-spacing: .02em;
  box-shadow: 0 6px 20px -6px rgba(45,79,160,.6), 0 1px 0 rgba(255,255,255,.2) inset;
  transition: transform var(--t-fast), filter var(--t-fast);
  white-space: nowrap;
}
.btn-publish:hover:not(:disabled) { filter: brightness(1.08); transform: translateY(-1px); }
.btn-publish:active { transform: translateY(0); }
.btn-publish:disabled { opacity: .45; cursor: not-allowed; filter: grayscale(.5); }
.btn-publish svg { width: 14px; height: 14px; }
@keyframes modalIn {
  from { opacity: 0; transform: translateY(20px) scale(.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes spin { to { transform: rotate(360deg); } }
.listing-pill{
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 7px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  border-radius: 999px;
}
.listing-pill.active{ background: var(--good-soft);  color: var(--good); }
.listing-pill.pending{ background: var(--warn-soft);  color: var(--warn); }
.listing-pill.sold{ background: var(--rule);       color: var(--ink-soft); }
.qa-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 7px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  border-radius: 999px;
}
.qa-pill.pass { background: var(--good-soft);  color: var(--good); }
.qa-pill.warn { background: var(--warn-soft);  color: var(--warn); }
.qa-pill.fail { background: var(--bad-soft);   color: var(--bad); }
.qa-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.btn-primary {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 13px 20px;
  border-radius: 18px;
  background: var(--accent);
  color: white; font-weight: 600; font-size: 14px;
  letter-spacing: .01em;
  box-shadow: 0 6px 20px -6px rgba(45,79,160,.6), 0 1px 0 rgba(255,255,255,.2) inset;
  transition: transform var(--t-fast), filter var(--t-fast), box-shadow var(--t-fast);
}
.btn-primary:hover { filter: brightness(1.08); transform: translateY(-1px); }
.btn-primary:active { transform: translateY(0); }
.btn-primary svg { width: 14px; height: 14px; }
.btn-secondary {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  font-size: 12px; font-weight: 600;
  border-radius: 999px;
  background: var(--glass-edge);
  color: var(--ink);
  transition: background var(--t-fast), transform var(--t-fast);
}
.btn-secondary:hover { background: color-mix(in oklab, var(--ink) 8%, transparent); transform: translateY(-1px); }
.btn-secondary svg { width: 12px; height: 12px; }
.btn-secondary.success {
  background: var(--good-soft); color: var(--good);
}
.btn-secondary.danger {
  background: var(--bad-soft); color: var(--bad);
}
/* ─────────────────────────────────────────────────────────────────────────
   12. Toasts
   ───────────────────────────────────────────────────────────────────────── */
.toast-stack {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 8px;
  z-index: 200; pointer-events: none;
}
.toast {
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--ink); color: var(--paper);
  font-size: 13px; font-weight: 500;
  box-shadow: var(--shadow-lg);
  animation: toastIn 320ms var(--spring) both;
  display: flex; align-items: center; gap: 10px;
  pointer-events: auto;
}
.toast.success { background: var(--good); color: white; }
.toast.warn { background: var(--warn); color: white; }
.toast.bad { background: var(--bad); color: white; }
@keyframes toastIn {
  from { opacity: 0; transform: translateY(12px) scale(.96); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
/* ─────────────────────────────────────────────────────────────────────────
   14. Misc utilities
   ───────────────────────────────────────────────────────────────────────── */
.divider { height: 1px; background: var(--rule); margin: 16px 0; }
.muted { color: var(--ink-soft); }
.center { text-align: center; }
.flex-row { display: flex; align-items: center; gap: 8px; }
.skeleton { background: linear-gradient(90deg, var(--rule) 25%, var(--paper-2) 50%, var(--rule) 75%);
            background-size: 200% 100%; animation: shimmer 1.4s linear infinite; }
@keyframes shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.site-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .01em;
}
.site-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.site-pill.p-none        { background: var(--pill-neutral-bg); color: var(--pill-neutral-ink); }
.site-pill.p-draft       { background: var(--pill-neutral-bg); color: var(--pill-neutral-ink); }
.site-pill.p-published   { background: var(--good-soft); color: var(--good); }
.site-pill.p-unpublished { background: color-mix(in oklab, var(--warn) 22%, transparent); color: var(--warn); }
.site-pill.p-expired     { background: var(--bad-soft); color: var(--bad); }

/* ═════════════════════════════════════════════════════════════════════════
   S2-4 ADDITIONS — the shared form / card / table / banner vocabulary.

   These are NEW CSS, not a move. They exist because deleting the six legacy
   pages' <style> blocks (profile, sold, admin, login, signup, reset) removes
   the only styling those pages had, and C-6 forbids re-declaring it per page.
   Every rule is expressed in the SAME visual language as index.html's
   `.scrape-field` / `.glass` / `.btn-primary`, in tokens only, so the six
   pages look native instead of merely "not broken".
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Page frame ─────────────────────────────────────────────────────────── */
.wrap {
  max-width: 960px;
  margin: 34px auto 80px;
  padding: 0 24px;
}
.wrap.narrow { max-width: 760px; }
.wrap.wide   { max-width: 1180px; }

.page-head { margin-bottom: 26px; }
.page-head h1 {
  font-family: 'DM Serif Display', Georgia, serif;
  font-weight: 400; letter-spacing: -.01em;
  font-size: 34px; margin: 0 0 6px; line-height: 1.1;
}
.page-head p { color: var(--ink-soft); font-size: 15px; margin: 0; max-width: 60ch; }

.section-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-faint); margin: 34px 0 14px;
}

/* ── Card ───────────────────────────────────────────────────────────────── */
.card {
  background: var(--glass-bg-2);
  backdrop-filter: blur(40px) saturate(180%);
  -webkit-backdrop-filter: blur(40px) saturate(180%);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--shadow-sm);
  border-radius: var(--r-lg);
  padding: 26px 28px;
  margin-bottom: 22px;
}
.card > h2 {
  font-size: 16px; font-weight: 700; margin: 0 0 16px; letter-spacing: -.01em;
}
.card > h1 { font-size: 22px; margin: 0 0 4px; }
.page-lede { color: var(--ink-soft); font-size: 14px; margin: 0 0 22px; line-height: 1.5; }
.field-hint { font-size: 12px; color: var(--ink-soft); margin-top: 5px; line-height: 1.5; }

/* ── Form controls ──────────────────────────────────────────────────────── */
.form-label {
  display: block; font-size: 13px; font-weight: 600; margin: 14px 0 6px; color: var(--ink);
}
.inp {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule);
  background: var(--paper);
  font-size: 15px; color: var(--ink);
  font-family: inherit;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.inp:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}
.inp::placeholder { color: var(--ink-faint); }
textarea.inp { resize: vertical; min-height: 62px; }
select.inp { cursor: pointer; }
.inp:disabled { opacity: .6; cursor: not-allowed; }

.form-row { display: flex; gap: 14px; flex-wrap: wrap; }
.form-row > div { flex: 1 1 200px; min-width: 0; }

.req { color: var(--bad); font-weight: 700; }
.reco-tag {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: var(--warn-soft); color: var(--warn); vertical-align: middle;
}

/* ── Inline status line (Saving… / Saved. / error) ──────────────────────── */
.status-line { font-size: 13px; min-height: 18px; margin-top: 14px; color: var(--ink-soft); }
.status-line.ok  { color: var(--good); }
.status-line.err { color: var(--bad); }

/* ── Banner ─────────────────────────────────────────────────────────────── */
.banner {
  border-radius: var(--r-md); padding: 14px 16px; font-size: 13.5px; line-height: 1.5;
  margin: 0 0 20px; display: none;
}
.banner.warn { background: var(--warn-soft); color: var(--warn); display: block; }
.banner.ok   { background: var(--good-soft); color: var(--good); display: block; }
.banner.bad  { background: var(--bad-soft);  color: var(--bad);  display: block; }
.banner strong { color: var(--ink); }
.banner ul { margin: 8px 0 0; padding-left: 18px; }
.banner.row { display: flex; align-items: center; gap: 12px; }

/* ── Table ──────────────────────────────────────────────────────────────── */
.table {
  width: 100%; border-collapse: collapse;
  background: var(--glass-bg-2);
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.table th, .table td {
  text-align: left; padding: 12px 14px;
  border-bottom: 1px solid var(--rule);
  font-size: 14px; vertical-align: middle;
}
.table th {
  background: var(--paper-2);
  font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-soft); font-weight: 700;
}
.table tr:last-child td { border-bottom: 0; }

/* ── Small pill (role / subscription / generic label) ───────────────────── */
.tag-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: .01em;
}
.tag-pill.good    { background: var(--good-soft);      color: var(--good); }
.tag-pill.warn    { background: var(--warn-soft);      color: var(--warn); }
.tag-pill.bad     { background: var(--bad-soft);       color: var(--bad); }
.tag-pill.accent  { background: var(--accent-soft);    color: var(--accent-dark); }
.tag-pill.neutral { background: var(--pill-neutral-bg); color: var(--pill-neutral-ink); }
.tag-pill .pdot, .tag-pill .dot {
  width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: 0 0 auto;
}

/* ── Ghost + danger buttons (index.html only had primary/secondary) ─────── */
.btn-link {
  background: transparent; color: var(--accent);
  font-weight: 600; font-size: 13px; padding: 8px 4px;
}
.btn-link:hover { text-decoration: underline; }
.btn-primary:disabled, .btn-secondary:disabled {
  opacity: .5; cursor: not-allowed; box-shadow: none; transform: none; filter: none;
}

/* Non-index pages have no `.app` grid, so they must scroll normally.
   base.css's `html, body { height: 100% }` is index.html's full-height shell
   requirement and is left untouched (C-9); this opts the other pages out. */
body.apex-page { height: auto; min-height: 100vh; }
