/* ──────────────────────────────────────────────────────────────────────
 * components.css — net-new shared components only.
 *
 * Everything here is built from base.css tokens (--card, --border,
 * --radius-*, --shadow-*, --alert-*, --space-*, --brand). No new color/
 * radius/shadow token is introduced. See docs/DESIGN_APPLE.md for the
 * token source of truth and the rationale for keeping this file additive
 * rather than a parallel design system.
 * ────────────────────────────────────────────────────────────────────── */

/* ── Motion tokens (genuine gap — base.css uses scattered literals) ──── */
:root {
  --dur-fast: 150ms;
  --dur-base: 200ms;
  --dur-slow: 280ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in:  cubic-bezier(0.7, 0, 0.84, 0);
  --ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
}

/* ── Branded confirm dialog (replaces native confirm()) ──────────────── */
.ui-confirm-ov {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: var(--space-4);
  animation: ui-confirm-fade var(--dur-base) var(--ease-out);
}
.ui-confirm-ov--leaving { animation: ui-confirm-fade var(--dur-fast) var(--ease-in) reverse; }
@keyframes ui-confirm-fade { from { opacity: 0; } to { opacity: 1; } }

.ui-confirm-box {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  max-width: 420px;
  width: 100%;
  padding: var(--space-6);
  animation: ui-confirm-scale var(--dur-slow) var(--ease-spring);
}
.ui-confirm-ov--leaving .ui-confirm-box { animation: ui-confirm-scale var(--dur-fast) var(--ease-in) reverse; }
@keyframes ui-confirm-scale { from { transform: scale(.94); opacity: 0; } to { transform: scale(1); opacity: 1; } }

.ui-confirm-msg {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--white);
  line-height: 1.4;
}
.ui-confirm-detail {
  font-size: var(--text-md);
  color: var(--muted);
  line-height: 1.5;
  margin-top: var(--space-2);
}
.ui-confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-6);
}
.ui-confirm-btn {
  font-family: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  padding: 9px var(--space-5);
  border-radius: var(--radius-pill);
  border: none;
  cursor: pointer;
  min-height: 40px;
  transition: transform var(--dur-fast) ease, background var(--dur-fast) ease, opacity var(--dur-fast) ease;
}
.ui-confirm-btn:active { transform: scale(.97); }
.ui-confirm-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px var(--brand-glow);
}
.ui-confirm-cancel  { background: var(--card-2); color: var(--text); border: 1px solid var(--border); }
.ui-confirm-cancel:hover  { border-color: var(--border-strong); }
.ui-confirm-primary { background: var(--brand); color: #fff; }
.ui-confirm-primary:hover { background: var(--brand-dark); }
.ui-confirm-danger   { background: var(--alert-error-fg); color: #fff; }
.ui-confirm-danger:hover   { opacity: .88; }

@media (prefers-reduced-motion: reduce) {
  .ui-confirm-ov, .ui-confirm-box, .ui-confirm-ov--leaving, .ui-confirm-ov--leaving .ui-confirm-box {
    animation: none !important;
  }
}

/* ── Shared modal overlay/box — sibling of .ui-confirm above, for richer
   modals (forms, multi-field content) instead of a simple message+actions
   dialog. Toggled via .open (element stays in the DOM and is shown/hidden
   by class, unlike .ui-confirm-ov which ui.confirm() inserts/removes) —
   promoted from three near-identical .modal-overlay/.modal-box copies in
   admin_ad_accounts.html, account_security.html, and reports.html. Each
   page can still override max-width with an inline style where needed. */
.ui-modal-ov {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .45);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: var(--space-4);
}
.ui-modal-ov.open { display: flex; animation: ui-confirm-fade var(--dur-base) var(--ease-out); }
.ui-modal-box {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  max-width: 480px;
  width: 100%;
  padding: var(--space-6);
  max-height: 88vh;
  overflow-y: auto;
}
.ui-modal-ov.open .ui-modal-box { animation: ui-confirm-scale var(--dur-slow) var(--ease-spring); }
@media (prefers-reduced-motion: reduce) {
  .ui-modal-ov.open, .ui-modal-ov.open .ui-modal-box { animation: none !important; }
}

/* ── Shared status-pill badge base ─────────────────────────────────────
 * Consolidates the ~identical .badge layout rule duplicated across
 * admin_sync, admin_maintenance, admin_ad_accounts, reports, project_detail
 * and projects (see docs/DESIGN_APPLE.md "Remaining gaps"). Each page keeps
 * only its own color modifiers (.ui-badge.ok, .ui-badge.active, etc).
 * NOT applied to admin_data_integrity.html or intelligence.html — those are
 * structurally different (icon+gap layout; compact non-pill sentiment tag)
 * rather than drifted duplicates. */
.ui-badge {
  display: inline-flex;
  align-items: center;
  font-size: 10px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  text-transform: uppercase;
  letter-spacing: .5px;
  white-space: nowrap;
}
/* Shared brand-scope pill — used in the topbar badge, Ad Accounts, and the
   Users table. Pages that already define their own copy of this rule keep
   working unchanged (harmless duplicate); new usages can rely on this one. */
.ui-badge.brand { background: var(--ltblue); color: var(--blue-text); }

/* ── iOS-style toggle switch ────────────────────────────────────────────
 * For a single standalone on/off SETTING (chat assistant enabled, an alert
 * enabled, a report public/private) — not for list/row selection, which
 * stays a plain checkbox per Apple HIG (UISwitch is reserved for settings,
 * not table-row multi-select). Promoted from users.html's page-local
 * .toggle/.toggle-slider, which had the identical implementation.
 *
 * Markup:
 *   <label class="ui-switch">
 *     <input type="checkbox" ...>
 *     <span class="ui-switch-track"></span>
 *   </label>
 */
.ui-switch { position: relative; display: inline-block; width: 32px; height: 18px; flex-shrink: 0; cursor: pointer; }
.ui-switch input { opacity: 0; width: 0; height: 0; position: absolute; }
.ui-switch-track {
  position: absolute; inset: 0; background: var(--dim);
  border-radius: 18px; transition: background var(--dur-base) ease;
}
.ui-switch-track::before {
  content: ''; position: absolute; height: 12px; width: 12px;
  left: 3px; bottom: 3px; background: #fff; border-radius: 50%;
  transition: transform var(--dur-base) ease; box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.ui-switch input:checked + .ui-switch-track { background: var(--brand); }
.ui-switch input:checked + .ui-switch-track::before { transform: translateX(14px); }
.ui-switch input:disabled + .ui-switch-track { opacity: .5; cursor: not-allowed; }
.ui-switch input:focus-visible + .ui-switch-track { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ── Shared card surface ──────────────────────────────────────────────
 * Consolidates ~identical .card rules duplicated across 12 templates
 * (admin_api_keys, admin_llm_keys, admin_system_health, admin_meta_platform,
 * brand_settings, campaign_quality, campaign_creator, knowledge,
 * leads_insights, reports, seo, project_detail) — same tokens
 * (var(--card)/var(--border)/var(--radius-lg)) with only padding/radius/
 * shadow drift between copies. NOT applied to the ~8 templates
 * (campaign_fit, budget_optimizer, campaign_planner, forecast, engines,
 * journey, updates, roadmap, …) that hardcode background:#fff — those
 * define their own deliberate, self-contained light-only design system
 * (--c-card/--c-line/--c-ink) and are not drifted duplicates of this one. */
.ui-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  margin-bottom: 16px;
}

/* ── Empty state ("no data yet") ───────────────────────────────────────
 * Consolidates the ~30+ templates that each hand-roll centered muted
 * "no data" messaging under a different class name (.empty, .empty-state,
 * .ciq-empty, .no-data, .empty-feed, or inline styles) — all doing the
 * same thing: padded, centered, muted-color text, optionally with an icon.
 * .ui-empty covers the plain text-only case; .ui-empty .icon is the
 * optional icon variant (was .empty-state's icon child elsewhere). */
.ui-empty {
  padding: 34px 20px;
  text-align: center;
  color: var(--muted);
}
.ui-empty .icon {
  font-size: 28px;
  opacity: .5;
  margin-bottom: 8px;
}

/* ── Data table ─────────────────────────────────────────────────────────
 * Consolidates the dark-dashboard-theme table family (var(--border)/
 * var(--card) tokens) — ~16 templates each hand-rolled the same
 * border-collapse/uppercase-header/hover-row rules. Based on
 * report_builder.html's .rb-table, the most feature-complete impl in the
 * app, trimmed to the common subset. The light "planning-suite" table
 * family (--c-ink3/--c-line tokens, e.g. campaign_fit/forecast/research)
 * is a separate, deliberately self-contained design system — same call as
 * .ui-card, not in scope here. */
.ui-table-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: auto;
  background: var(--card);
}
.ui-table { border-collapse: collapse; width: 100%; font-size: 13px; }
.ui-table thead th {
  background: var(--card-2);
  color: var(--muted);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .4px;
  text-align: left;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.ui-table tbody td { padding: 10px 14px; border-bottom: 1px solid var(--border); }
.ui-table tbody tr:hover td { background: var(--card-2); }
.ui-table tbody tr:nth-child(even) td { background: rgba(127,127,127,.035); }

/* Wrapper trio, previously copy-pasted verbatim in admin/google/linkedin/
 * unified/index/users (same duplication problem, one layer up). */
.ui-table-card { background: var(--card); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; margin-bottom: 16px; }
.ui-table-header { padding: 12px 16px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--border); flex-wrap: wrap; gap: 8px; }
.ui-table-scroll { overflow-x: auto; max-height: 560px; overflow-y: auto; }

/* ── Tab bar ────────────────────────────────────────────────────────────
 * Two clusters found doing the same thing with byte-identical CSS: an
 * "underline" style (index/google/linkedin/campaign_creator/knowledge/
 * admin, differing only in active accent color — kept as a page-scoped
 * override, same pattern as .spinner's color deltas) and a "bordered
 * panel" style (admin_system_health/admin_meta_platform/project_detail/
 * users — literally identical CSS across all four). Both use core dark
 * tokens, so both are in scope (unlike the table split). */
.ui-tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); overflow-x: auto; }
.ui-tab {
  padding: 12px 18px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: .2s;
}
.ui-tab:hover { color: var(--white); }
.ui-tab.active { color: var(--brand); border-bottom-color: var(--brand); }
/* bordered-panel variant */
.ui-tabs--panel { border-bottom: 1px solid var(--border); margin: 0 0 18px; }
.ui-tabs--panel .ui-tab { padding: 10px 16px; font-size: 13px; margin-bottom: -1px; }
.ui-tabs--panel .ui-tab.active { border-color: var(--brand); color: var(--white); }

/* ── Segmented control ─────────────────────────────────────────────────
 * .seg-tabs/.seg-tab was byte-identical across index/google/linkedin (the
 * All/Active/Paused campaign filter) — promoted verbatim. The active
 * button itself keeps its background/shadow as a no-JS fallback (so it
 * still looks correct if ui.js fails to load); .ui-seg-thumb is a
 * progressive-enhancement overlay that slides between options — see
 * ui.segSlide() in static/js/ui.js. */
.ui-segmented { display: inline-flex; gap: 2px; background: var(--card-2); border: 1px solid var(--border); border-radius: 8px; padding: 2px; position: relative; }
.ui-seg {
  position: relative;
  z-index: 1;
  background: transparent;
  border: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  padding: 5px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: color .15s;
}
.ui-seg:hover { color: var(--white); }
.ui-seg.active { background: var(--card); color: var(--white); box-shadow: 0 1px 2px rgba(0,0,0,.12); }
.ui-seg-thumb {
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: 0;
  width: 0;
  background: var(--card);
  border-radius: 6px;
  box-shadow: 0 1px 2px rgba(0,0,0,.12);
  transition: transform .25s cubic-bezier(.2,.8,.2,1), width .25s cubic-bezier(.2,.8,.2,1);
  z-index: 0;
  pointer-events: none;
}
/* the thumb already provides the sliding highlight — drop the active
   button's own background so they don't double up and look flat-stacked.
   ui.segSlide() adds this class once it creates the thumb (progressive
   enhancement — without JS, .ui-seg.active's own background above is the
   fallback indicator). */
.ui-segmented--js .ui-seg.active { background: transparent; box-shadow: none; }
