/**
 * Phase 2 of the unified in-app visual redesign: dashboard.html's own
 * body content (Hero, Protection Score, quick-glance stat cards, Backup
 * Timeline, Database Health, Backup Insights/Recovery Center, locked-
 * feature treatment, empty states, Activity Feed).
 *
 * Deliberately a NEW, separate component system from the pre-existing
 * .card-glass/.status-card/.dash-* rules in main.css -- those classes
 * are shared with index.html's own marketing hero stats/feature cards/
 * price cards (glassmorphism is that page's material, kept exactly as
 * it was), so this redesign's "no glassmorphism" mandate is met by never
 * touching those shared rules at all, not by changing what they render.
 * Every class here is new and app-page-only. Built entirely on the
 * Phase 0 --app-*/--space-*/--text-*/--motion-* tokens (css/variables.css).
 *
 * Loaded by dashboard.html, settings.html (Phase 3b), and
 * admin-dashboard.html (Phase 4, .app-card only -- admin-dashboard.css
 * keeps its own purpose-built .admin-sidebar/.admin-panel layout rules,
 * this file just supplies the flat card material they use). Connection
 * cards ("Your databases") were deliberately NOT restyled by this file
 * at first -- that's Phase 3 ("Connections"), added below.
 *
 * Phase 3 ("Connections") retints the EXISTING connection-card/aside
 * markup and classes in place (.conn-card, .aside-card, .badge-*,
 * .card-menu, .kebab, etc.) rather than renaming them and touching
 * dashboard.js's interactive logic (kebab menus, manual-backup quota
 * countdowns, backup polling) -- that logic is unchanged and high-risk
 * to restructure, so only the colors/surfaces change here. One
 * exception: .status-dot (base rule + .failed) is deliberately left
 * completely untouched -- unlike every other class below, it IS shared
 * with index.html (js/marketing-nav.js's own Hero stats backup-status
 * dot, js/backup-status.js, both loaded on index.html), so retinting it
 * would repaint the marketing page too. Every other class confirmed here
 * via grep across index.html's own loaded JS (marketing-nav.js,
 * radial-nav.js, backup-status.js, navbar.js, animations.js) before
 * being touched.
 */

.app-card {
  background: var(--app-surface);
  border: 1px solid var(--app-border);
  border-radius: var(--radius-lg);
}

/* Every one of these is a <section>, and main.css's own .dash-main section
   { padding: 0 } reset (1 class + 1 tag, specificity 0,1,1) otherwise
   outweighs a plain single-class ".app-hero { padding: ... }" rule (0,1,0)
   regardless of stylesheet load order. Scoped under .dash-main here to
   win instead, the exact same fix this codebase already applies to
   .settings-section (see main.css's own comment beside that rule) --
   caught via an actual getBoundingClientRect() measurement during QA
   (the Hero rendered at ~50px tall, not the intended padded height), not
   just by eyeballing a screenshot, which alone didn't make the missing
   padding obvious. */
.dash-main .app-hero,
.dash-main .app-score-card,
.dash-main .app-panel {
  padding: var(--space-24) var(--space-32);
}

/* ── Hero: instantly answers "is my database protected?", zero scroll ──── */

.app-hero {
  display: flex;
  align-items: center;
  gap: var(--space-32);
  max-height: 160px;
  margin-bottom: var(--space-24);
  overflow: hidden;
}

.app-hero-status {
  display: flex;
  align-items: center;
  gap: var(--space-16);
  flex: 0 0 auto;
}

.app-hero-status-icon {
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
}
.app-hero-status-icon.good { color: var(--app-success); }
.app-hero-status-icon.warn { color: var(--app-warning); }
.app-hero-status-icon.bad { color: var(--app-danger); }

.app-hero-status h1 {
  margin: 0;
  font-family: var(--font-app-sans);
  font-size: var(--text-metric-size);
  font-weight: var(--text-metric-weight);
  color: var(--app-text-primary);
  line-height: 1.1;
}

.app-hero-divider {
  width: 1px;
  align-self: stretch;
  background: var(--app-border);
  flex: 0 0 auto;
}

.app-hero-stats {
  display: flex;
  gap: var(--space-32);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
}

.app-hero-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.app-hero-stat .app-label {
  white-space: nowrap;
}

.app-hero-stat .app-hero-stat-value {
  font-family: var(--font-app-sans);
  font-size: var(--text-body-size);
  font-weight: 600;
  color: var(--app-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-hero-action {
  flex: 0 0 auto;
}

/* Guidance variant: zero connections yet -- Hero still answers the
   question ("Not protected yet"), with the Primary Action being the one
   thing that fixes it. */
.app-hero.is-guidance .app-hero-stats {
  color: var(--app-text-secondary);
  font-size: var(--text-description-size);
}

/* Shared small-caps label style (section labels, card labels) --
   Phase 0's --text-label-* tokens. */
.app-label {
  display: block;
  font-family: var(--font-app-sans);
  font-size: var(--text-label-size);
  font-weight: var(--text-label-weight);
  letter-spacing: var(--text-label-letter-spacing);
  text-transform: uppercase;
  color: var(--app-text-secondary);
}

/* ── Protection Score (Lite+) ─────────────────────────────────────────── */

.app-score-card {
  margin-bottom: var(--space-24);
}

.dash-hero-score-body {
  display: flex;
  align-items: center;
  gap: var(--space-32);
}

.app-score-card h2 {
  margin: 0 0 var(--space-16);
  font-family: var(--font-app-sans);
  font-size: var(--text-body-size);
  font-weight: 600;
  color: var(--app-text-primary);
}

.app-score-ring {
  position: relative;
  width: 96px;
  height: 96px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: conic-gradient(var(--score-color, var(--app-success)) calc(var(--score-pct, 0) * 1%), var(--app-border) 0);
  display: flex;
  align-items: center;
  justify-content: center;
}

.app-score-ring::before {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  background: var(--app-surface);
}

.app-score-ring-inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--font-app-sans);
  font-size: 24px;
  font-weight: 700;
  color: var(--app-text-primary);
  line-height: 1.1;
}

.app-score-ring-inner span {
  font-size: 11px;
  font-weight: 500;
  color: var(--app-text-secondary);
  text-transform: none;
  letter-spacing: normal;
}

.app-score-breakdown {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-8) var(--space-32);
}

.app-score-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-16);
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-secondary);
}

.app-score-row .value {
  color: var(--app-text-primary);
  font-weight: 500;
}

/* ── Quick-glance stat cards: number dominant, label + description under it ── */

.app-quick-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-16);
  margin-bottom: var(--space-24);
}

.app-stat-card {
  padding: var(--space-24);
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.app-stat-card .app-stat-value {
  font-family: var(--font-app-sans);
  font-size: var(--text-metric-size);
  font-weight: var(--text-metric-weight);
  color: var(--app-text-primary);
  line-height: 1.1;
}

.app-stat-card .app-stat-desc {
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-secondary);
}

/* ── Generic panel wrapper (Backup Timeline, Database Health) ───────────── */

.app-panel {
  margin-bottom: var(--space-24);
}

.app-panel h2 {
  margin: 0 0 var(--space-16);
  font-family: var(--font-app-sans);
  font-size: var(--text-body-size);
  font-weight: 600;
  color: var(--app-text-primary);
}

/* ── Backup Timeline ──────────────────────────────────────────────────── */

.app-timeline-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.app-timeline-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-16);
  padding: var(--space-16) 0;
  border-bottom: 1px solid var(--app-border);
}

.app-timeline-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.app-timeline-icon {
  width: var(--icon-size);
  height: var(--icon-size);
  flex: 0 0 auto;
  margin-top: 2px;
}
.app-timeline-icon.success { color: var(--app-success); }
.app-timeline-icon.error { color: var(--app-danger); }
.app-timeline-icon.pending { color: var(--app-info); }

.app-timeline-title {
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-primary);
  font-weight: 500;
}

.app-timeline-meta {
  display: flex;
  gap: var(--space-16);
  margin-top: 4px;
  font-family: var(--font-app-sans);
  font-size: 12px;
  color: var(--app-text-secondary);
}

/* ── Database Health: clean badges, never a raw dt/dd grid ───────────────
   Unknown = neutral (--app-text-secondary dot), failure = urgent
   (--app-danger), healthy = --app-success. Never a warning color for
   "unknown" -- an absence of data isn't itself a problem. */

.app-health-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin: 0;
}

.app-health-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-16);
  background: var(--app-bg);
  border: 1px solid var(--app-border);
  border-radius: 999px;
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-primary);
}

.app-health-badge .app-health-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  flex: 0 0 auto;
  background: var(--app-text-secondary);
}
.app-health-badge .app-health-dot.is-good { background: var(--app-success); }
.app-health-badge .app-health-dot.is-bad { background: var(--app-danger); }

.app-health-badge .app-health-label {
  color: var(--app-text-secondary);
}

/* ── Backup Insights (Pro+) / Recovery Center ────────────────────────────── */

.app-insights-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-16);
  margin-bottom: var(--space-24);
}

.app-insight-card {
  padding: var(--space-24);
}

.app-insight-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  margin: 0 0 var(--space-16);
}

.app-insight-card-header h3 {
  margin: 0;
  font-family: var(--font-app-sans);
  font-size: var(--text-body-size);
  font-weight: 600;
  color: var(--app-text-primary);
}

/* "How this is calculated" -- one small (i) button per widget, opening
   #insights-about-modal (dashboard.js's own openInsightsAboutModal()),
   the user-dashboard's port of the Admin Dashboard's #about-modal
   pattern (admin-dashboard.js/.css) sized down for a short, single-topic
   explanation rather than that page's own multi-section reference. */
.app-insight-info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--app-border);
  background: transparent;
  color: var(--app-text-secondary);
  font-family: var(--font-app-sans);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
}

.app-insight-info-btn:hover,
.app-insight-info-btn:focus-visible {
  color: var(--app-text-primary);
  border-color: var(--app-text-secondary);
}

.app-insight-card h3 {
  margin: 0 0 var(--space-16);
  font-family: var(--font-app-sans);
  font-size: var(--text-body-size);
  font-weight: 600;
  color: var(--app-text-primary);
}

.app-insight-big-number {
  font-family: var(--font-app-sans);
  font-size: var(--text-metric-size);
  font-weight: var(--text-metric-weight);
  color: var(--app-text-primary);
  line-height: 1.1;
}

/* A rate/score computed from too few real attempts to be confident --
   insights/compute.py's MIN_SAMPLE_SIZE -- still a REAL number (never
   hidden), just visually de-emphasized so it doesn't read as equally
   confident as one backed by real volume. */
.app-insight-big-number.is-low-sample {
  color: var(--app-text-secondary);
}

.app-insight-sub {
  margin: var(--space-8) 0 0;
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-secondary);
}

/* Zero-data empty state -- e.g. "No restores yet". Deliberately its own
   class (not reusing .app-insight-sub, which sits BELOW a real number)
   since this REPLACES the big-number area entirely. */
.app-insight-empty {
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-secondary);
  font-style: italic;
}

/* Risk Analyzer's real, rule-based findings -- a plain list of full
   sentences (unlike .app-insight-list's label/value pairs above). */
.app-insight-risk-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.app-insight-risk-list li {
  display: flex;
  gap: var(--space-8);
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-primary);
}

.app-insight-note {
  margin: var(--space-8) 0 0;
  font-family: var(--font-app-sans);
  font-size: 12px;
  color: var(--app-text-secondary);
}

.app-insight-big-number.is-good { color: var(--app-success); }
.app-insight-big-number.is-warn { color: var(--app-warning); }

.app-insight-risk-list li svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin-top: 0.15em;
  color: var(--app-warning);
}

/* "How this is calculated" modal (#insights-about-modal) -- the user
   dashboard's own scaled-down port of the Admin Dashboard's #about-modal
   pattern (admin-dashboard.css's .admin-about-*): one shared modal, a
   short title + a few plain paragraphs per widget, no terms/service-tag
   machinery (this page's widgets don't need it). */
.insights-about-modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-16);
  margin-bottom: var(--space-16);
}

.insights-about-modal-header h3 {
  margin: 0;
  font-family: var(--font-app-sans);
}

.insights-about-modal-close {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  border: none;
  background: color-mix(in srgb, white 6%, transparent);
  color: var(--app-text-secondary);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.insights-about-modal-close:hover {
  background: color-mix(in srgb, white 10%, transparent);
  color: var(--app-text-primary);
}

.insights-about-modal-body p {
  margin: 0 0 var(--space-16);
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  line-height: 1.6;
  color: var(--app-text-secondary);
}

.insights-about-modal-body p:last-child {
  margin-bottom: 0;
}

.app-insight-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.app-insight-list li {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-secondary);
}

.app-insight-list li span:last-child {
  color: var(--app-text-primary);
  font-weight: 500;
}

/* Recovery Center: the flagship, emotional-conclusion section -- visually
   the largest, calmest card on the page. Spans both grid columns. */
.app-recovery-center {
  grid-column: 1 / -1;
  padding: var(--space-32);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-32);
  background: linear-gradient(135deg, color-mix(in srgb, var(--app-success) 8%, var(--app-surface)), var(--app-surface));
}

.app-recovery-center h3 {
  margin: 0 0 var(--space-8);
  font-family: var(--font-app-sans);
  font-size: 20px;
  font-weight: 600;
  color: var(--app-text-primary);
}

.app-recovery-center .app-insight-sub {
  max-width: 32ch;
}

.app-recovery-center-time {
  font-family: var(--font-app-sans);
  font-size: var(--text-metric-hero-size);
  font-weight: var(--text-metric-hero-weight);
  color: var(--app-success);
  white-space: nowrap;
}

.app-recovery-center-time.is-low-sample {
  color: var(--app-text-secondary);
}

/* ── Locked features: communicate value, never a lock icon ──────────────── */

.app-locked {
  display: flex;
  align-items: flex-start;
  gap: var(--space-16);
  padding: var(--space-8) 0;
}

.app-locked-icon {
  width: var(--icon-size);
  height: var(--icon-size);
  flex: 0 0 auto;
  margin-top: 2px;
  color: var(--app-warning);
}

.app-locked-title {
  margin: 0;
  font-family: var(--font-app-sans);
  font-size: var(--text-body-size);
  font-weight: 600;
  color: var(--app-text-primary);
}

.app-locked-desc {
  margin: 4px 0 var(--space-8);
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-secondary);
}

.app-locked-upgrade,
.app-cta-link {
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  font-weight: 600;
  color: var(--app-info);
  text-decoration: none;
}
.app-locked-upgrade:hover,
.app-cta-link:hover { text-decoration: underline; }

/* ── Empty states: explain why, explain what happens next, offer a CTA ──── */

.app-empty-panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-8);
  padding: var(--space-16) 0;
}

.app-empty-panel .app-empty-title {
  margin: 0;
  font-family: var(--font-app-sans);
  font-size: var(--text-body-size);
  font-weight: 600;
  color: var(--app-text-primary);
}

.app-empty-panel .app-empty-desc {
  margin: 0;
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-secondary);
  max-width: 48ch;
}

/* ── Activity Feed ────────────────────────────────────────────────────── */

.app-activity-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.app-activity-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-16);
  padding: var(--space-16) 0;
  border-bottom: 1px solid var(--app-border);
}

.app-activity-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.app-activity-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  flex: 0 0 auto;
  margin-top: 6px;
  background: var(--app-text-secondary);
}
.app-activity-dot.success { background: var(--app-success); }
.app-activity-dot.error { background: var(--app-danger); }

.app-activity-text {
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  color: var(--app-text-primary);
}

.app-activity-meta {
  display: flex;
  gap: var(--space-16);
  margin-top: 4px;
  font-family: var(--font-app-sans);
  font-size: 12px;
  color: var(--app-text-secondary);
}

/* ── Responsive ───────────────────────────────────────────────────────── */

@media (max-width: 1024px) {
  .app-quick-cards { grid-template-columns: repeat(2, 1fr); }
  .app-insights-grid { grid-template-columns: 1fr; }
  .app-recovery-center { grid-column: auto; }

  /* The single-row Hero (status + 5 stats + action button) needs more
     width than 1024px allows -- caught via an actual tablet-width (820px)
     screenshot, where the stats visibly overlapped/garbled instead of
     just looking cramped, since .app-hero-stat's min-width:0 let its text
     shrink-wrap inside the height-capped, overflow:hidden Hero instead of
     growing it. Below this width the Hero stacks into two rows instead,
     the same treatment the narrower 768px breakpoint already had. */
  .app-hero {
    flex-wrap: wrap;
    max-height: none;
    row-gap: var(--space-16);
  }
  .app-hero-stats {
    flex-wrap: wrap;
    gap: var(--space-16);
    overflow: visible;
    flex-basis: 100%;
  }
  .app-hero-divider { display: none; }
}

@media (max-width: 768px) {
  .app-hero {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-16);
  }
  .app-score-card { flex-direction: column; align-items: flex-start; }
  .app-score-breakdown { grid-template-columns: 1fr; width: 100%; }
}

@media (max-width: 640px) {
  .app-quick-cards { grid-template-columns: 1fr; }
  .app-recovery-center { flex-direction: column; align-items: flex-start; }
}

@media (prefers-reduced-motion: no-preference) {
  .app-score-ring { transition: background var(--motion-duration) var(--motion-ease); }
}

/* ══════════════════════════════════════════════════════════════════════
   Phase 3 ("Connections"): connection cards, storage card, Activity Feed.
   ══════════════════════════════════════════════════════════════════════ */

.conn-card {
  background: var(--app-surface);
  border: 1px solid var(--app-border);
}

.conn-head h3 {
  color: var(--app-text-primary);
  font-family: var(--font-app-sans);
}

.provider-chip {
  border-color: var(--app-border);
  color: var(--app-text-secondary);
  font-family: var(--font-app-sans);
}

.conn-meta dt {
  color: var(--app-text-secondary);
  font-family: var(--font-app-sans);
}

.conn-meta dd {
  color: var(--app-text-primary);
  font-family: var(--font-app-sans);
}

.kebab {
  color: var(--app-text-secondary);
}

.kebab:hover {
  color: var(--app-text-primary);
  background: color-mix(in srgb, var(--app-text-primary) 6%, transparent);
}

.card-menu {
  background: var(--app-surface);
  border-color: var(--app-border);
}

.card-menu [role="menuitem"], [role="menuitemradio"] {
  color: var(--app-text-secondary);
  font-family: var(--font-app-sans);
}

.card-menu [role="menuitem"], [role="menuitemradio"]:hover:not([aria-disabled="true"]) {
  color: var(--app-text-primary);
  background: color-mix(in srgb, var(--app-text-primary) 6%, transparent);
}

.card-menu [role="menuitem"], [role="menuitemradio"].danger {
  color: var(--app-danger);
}

.badge-success {
  color: var(--app-success);
  background: color-mix(in srgb, var(--app-success) 12%, transparent);
}

.badge-failed {
  color: var(--app-danger);
  background: color-mix(in srgb, var(--app-danger) 12%, transparent);
}

.badge-pending {
  color: var(--app-warning);
  background: color-mix(in srgb, var(--app-warning) 12%, transparent);
}

.badge-free-trial-warning {
  color: var(--app-warning);
  background: color-mix(in srgb, var(--app-warning) 12%, transparent);
}

.badge-free-trial-ended {
  color: var(--app-danger);
  background: color-mix(in srgb, var(--app-danger) 12%, transparent);
}

.badge-manual,
.badge-scheduled,
.badge-muted {
  color: var(--app-text-secondary);
  background: color-mix(in srgb, var(--app-text-secondary) 12%, transparent);
}

.report-box {
  background: color-mix(in srgb, white 4%, transparent);
  border-color: var(--app-border);
}

.report-box-text {
  color: var(--app-text-secondary);
}

.manual-backup-quota {
  color: var(--app-text-secondary);
}

.add-card {
  color: var(--app-text-secondary);
  border-color: var(--app-border);
  font-family: var(--font-app-sans);
}

.add-card:hover {
  color: var(--app-success);
  border-color: var(--app-success);
}

.add-card-disabled,
.add-card-disabled:hover {
  color: var(--app-text-secondary);
  border-color: var(--app-border);
}

.aside-card {
  background: var(--app-surface);
  border: 1px solid var(--app-border);
}

.aside-card h2 {
  color: var(--app-text-primary);
  font-family: var(--font-app-sans);
}

.activity-item {
  border-bottom-color: var(--app-border);
  font-family: var(--font-app-sans);
}

.activity-dot.success { background: var(--app-success); }
.activity-dot.error { background: var(--app-danger); }
.activity-dot.info { background: var(--app-info); }

.activity-text {
  color: var(--app-text-primary);
}

.activity-when {
  color: var(--app-text-secondary);
}

/* ══════════════════════════════════════════════════════════════════════
   Phase 3b ("Settings"/"Billing"/"Profile"/"Notifications"/"API Keys"):
   settings.html's own tab shell + every tab panel, plus dashboard.html's
   Plan usage bar (#usage-bar, bundled here rather than with Phase 3a --
   it's a plan/billing display, the same treatment Settings' own Plan &
   Billing tab needs anyway). This file is now loaded by settings.html
   too, not just dashboard.html -- see this file's own header comment.

   Same "retint in place" approach as Phase 3a: settings.js's extensive
   interactive logic (2FA setup, API key generation, session/device
   management, notification toggles) is completely unchanged, only the
   colors/surfaces. Every class below confirmed settings/dashboard-
   exclusive via the same grep-across-index.html's-own-JS method as
   Phase 3a -- .price-amount (shared with index.html's pricing cards) is
   the one caught here and deliberately left untouched.
   ══════════════════════════════════════════════════════════════════════ */

.usage-bar,
.plan-summary {
  background: var(--app-surface);
  border: 1px solid var(--app-border);
}

.plan-chip {
  color: var(--app-success);
  background: color-mix(in srgb, var(--app-success) 12%, transparent);
}

.settings-nav {
  background: var(--app-surface);
  border: 1px solid var(--app-border);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
}

.tab-btn {
  color: var(--app-text-secondary);
  font-family: var(--font-app-sans);
}

.tab-btn:hover:not(:disabled) {
  color: var(--app-text-primary);
  background: color-mix(in srgb, var(--app-text-primary) 6%, transparent);
}

.tab-btn:focus-visible {
  outline-color: var(--app-info);
}

.tab-btn.active {
  color: var(--app-success);
  background: color-mix(in srgb, var(--app-success) 10%, transparent);
}

.settings-section h2,
.plan-summary-name h3 {
  color: var(--app-text-primary);
  font-family: var(--font-app-sans);
}

.field label {
  color: var(--app-text-secondary);
  font-family: var(--font-app-sans);
}

.field-label {
  display: block;
  margin-bottom: 0.4rem;
  color: var(--app-text-secondary);
  font-family: var(--font-app-sans);
  font-size: 0.92rem;
  font-weight: 600;
}

.field input,
.field select,
.field textarea,
.modal input {
  background: var(--app-bg);
  border-color: var(--app-border);
  color: var(--app-text-primary);
  font-family: var(--font-app-sans);
}

.field input:focus,
.field select:focus,
.field textarea:focus,
.modal input:focus {
  border-color: var(--app-info);
}

.readonly-value {
  background: color-mix(in srgb, var(--app-bg) 60%, var(--app-surface));
  border-color: var(--app-border);
  color: var(--app-text-secondary);
}

.theme-preference-group {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-8);
}

.theme-choice-card {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 42px;
  border: 1px solid var(--app-border);
  border-radius: var(--radius-md);
  background: var(--app-surface-secondary, var(--app-bg));
  color: var(--app-text-secondary);
  font-family: var(--font-app-sans);
  font-size: var(--text-description-size);
  font-weight: 600;
  cursor: pointer;
}

.theme-choice-card:hover,
.theme-choice-card:focus-visible {
  color: var(--app-text-primary);
  border-color: var(--app-border-strong, var(--app-border));
  background: var(--color-surface-hover);
}

.theme-choice-card:focus-visible {
  outline: 2px solid var(--app-focus-ring);
  outline-offset: 2px;
}

.theme-choice-card.is-active {
  color: var(--color-brand);
  border-color: var(--color-brand-border);
  background: var(--color-brand-soft);
}

.theme-choice-card svg {
  width: 16px;
  height: 16px;
  stroke-width: 1.75;
}

/* Upgrade cards (Lite/Pro/Max): no longer the shared .card-glass material
   with index.html's own pricing cards -- an intentional, unavoidable
   consequence of this whole redesign's "no glassmorphism" mandate for
   in-app pages. index.html's pricing cards are untouched. */
.upgrade-card {
  background: var(--app-surface);
  border: 1px solid var(--app-border);
}

.upgrade-card.popular {
  border-color: color-mix(in srgb, var(--app-success) 35%, transparent);
  box-shadow: none;
}

.upgrade-card.popular:hover {
  box-shadow: 0 12px 32px -8px color-mix(in srgb, var(--app-success) 30%, transparent);
}

.upgrade-card-badge {
  background: var(--app-success);
  color: var(--app-bg);
}

.upgrade-card-current-badge {
  background: color-mix(in srgb, var(--app-text-secondary) 20%, transparent);
  color: var(--app-text-secondary);
}

.upgrade-card h3 {
  color: var(--app-text-primary);
  font-family: var(--font-app-sans);
}

.upgrade-card-features li::before {
  color: var(--app-success);
}

.pref-row {
  border-bottom-color: color-mix(in srgb, var(--app-border) 60%, transparent);
}

.pref-text strong {
  color: var(--app-text-primary);
  font-family: var(--font-app-sans);
}

.saved-flash {
  color: var(--app-success);
}

#twofa-secret-text {
  background: var(--app-bg);
  color: var(--app-text-primary);
}

.toggle .track {
  background: var(--app-border);
}

.toggle input:checked ~ .track {
  background: color-mix(in srgb, var(--app-success) 35%, var(--app-border));
}

.toggle input:checked ~ .track::after {
  background: var(--app-success);
}

.toggle input:focus-visible ~ .track {
  outline-color: var(--app-info);
}

.danger-card {
  border-color: color-mix(in srgb, var(--app-danger) 40%, transparent);
}

/* Explicit, not left to fall through to the generic ".settings-section h2"
   rule above (same specificity, would otherwise win on load order alone
   and silently neutralize this) -- main.css's own comment on this rule
   explains why the Danger Zone heading stays red-toned deliberately. */
.danger-card h2 {
  color: var(--app-danger);
}

/* .btn-danger is an outline-style button (transparent bg, colored border/
   text) -- only the color itself changes, not the fundamental treatment. */
.btn-danger {
  color: var(--app-danger);
  border-color: var(--app-danger);
}

.btn-danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--app-danger) 12%, transparent);
}

.modal {
  background: var(--app-surface);
  border: 1px solid var(--app-border);
}

.modal h3 {
  color: var(--app-text-primary);
  font-family: var(--font-app-sans);
}

.history-row {
  border-bottom-color: var(--app-border);
  font-family: var(--font-app-sans);
}

.history-row-time {
  color: var(--app-text-primary);
}

.history-row-meta,
.history-row-error {
  color: var(--app-text-secondary);
}

.form-error {
  color: var(--app-danger);
}

.progress {
  background: var(--app-border);
}

.progress > span {
  background: linear-gradient(90deg, var(--app-success), var(--app-info));
}

/* ==========================================================================
   Phase 3.2: shared component primitives + core page migration.

   Scope is intentionally narrow: Dashboard, Settings, API Keys, and Team add
   .core-theme-page on <body>. Other authenticated pages still load this file,
   but they are explicitly outside this migration phase.
   ========================================================================== */

body.core-theme-page {
  color: var(--color-text-primary);
}

body.core-theme-page .app-content {
  padding-top: var(--space-24);
  padding-bottom: var(--space-48);
}

body.core-theme-page .text-muted,
body.core-theme-page .dash-page-sub,
body.core-theme-page .section-sub,
body.core-theme-page .field-note,
body.core-theme-page .key-meta,
body.core-theme-page .app-insight-sub,
body.core-theme-page .app-timeline-meta,
body.core-theme-page .app-activity-meta {
  color: var(--color-text-muted);
}

body.core-theme-page .dash-page-title,
body.core-theme-page .settings-title,
body.core-theme-page .subsection-title,
body.core-theme-page .key-row-title strong,
body.core-theme-page .pref-text strong,
body.core-theme-page .storage-readout,
body.core-theme-page .dash-table td,
body.core-theme-page .modal strong {
  color: var(--color-text-primary);
}

body.core-theme-page .app-card,
body.core-theme-page .settings-nav,
body.core-theme-page .settings-section,
body.core-theme-page .usage-bar,
body.core-theme-page .plan-summary,
body.core-theme-page .upgrade-card,
body.core-theme-page .aside-card,
body.core-theme-page .conn-card,
body.core-theme-page .dash-table-card {
  background: var(--color-surface-primary);
  border: 1px solid var(--color-border-default);
  box-shadow: 0 10px 28px var(--color-shadow-card);
}

:root[data-theme="dark"] body.core-theme-page .app-card,
:root[data-theme="dark"] body.core-theme-page .settings-nav,
:root[data-theme="dark"] body.core-theme-page .settings-section,
:root[data-theme="dark"] body.core-theme-page .usage-bar,
:root[data-theme="dark"] body.core-theme-page .plan-summary,
:root[data-theme="dark"] body.core-theme-page .upgrade-card,
:root[data-theme="dark"] body.core-theme-page .aside-card,
:root[data-theme="dark"] body.core-theme-page .conn-card,
:root[data-theme="dark"] body.core-theme-page .dash-table-card {
  background: var(--color-surface-primary);
  border-color: var(--color-border-default);
  box-shadow: none;
}

body.core-theme-page .app-card.is-locked,
body.core-theme-page .app-locked,
body.core-theme-page .key-empty-state,
body.core-theme-page .app-empty-panel,
body.core-theme-page .empty-state {
  background: var(--color-surface-secondary);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-md);
}

body.core-theme-page .app-locked,
body.core-theme-page .app-empty-panel,
body.core-theme-page .key-empty-state {
  padding: var(--space-16);
}

body.core-theme-page .empty-state {
  color: var(--color-text-primary);
}

body.core-theme-page .app-label,
body.core-theme-page .app-stat-card .app-stat-desc,
body.core-theme-page .app-score-row,
body.core-theme-page .app-health-badge .app-health-label,
body.core-theme-page .app-insight-list li,
body.core-theme-page .app-empty-panel .app-empty-desc,
body.core-theme-page .app-locked-desc {
  color: var(--color-text-secondary);
}

body.core-theme-page .app-stat-card,
body.core-theme-page .app-insight-card {
  background: var(--color-surface-primary);
}

body.core-theme-page .app-stat-card {
  border-left: 3px solid var(--color-brand-border);
}

body.core-theme-page .app-stat-card .app-stat-value,
body.core-theme-page .app-insight-big-number,
body.core-theme-page .app-hero-status h1,
body.core-theme-page .app-hero-stat .app-hero-stat-value,
body.core-theme-page .app-score-ring-inner,
body.core-theme-page .app-score-row .value,
body.core-theme-page .app-timeline-title,
body.core-theme-page .app-health-badge,
body.core-theme-page .app-insight-list li span:last-child,
body.core-theme-page .app-empty-panel .app-empty-title,
body.core-theme-page .app-locked-title,
body.core-theme-page .app-activity-text {
  color: var(--color-text-primary);
}

body.core-theme-page .app-score-ring {
  background: conic-gradient(var(--score-color, var(--color-success)) calc(var(--score-pct, 0) * 1%), var(--color-border-default) 0);
}

body.core-theme-page .app-score-ring::before {
  background: var(--color-surface-primary);
}

body.core-theme-page .app-health-badge,
body.core-theme-page .badge,
body.core-theme-page .session-current {
  border: 1px solid transparent;
}

body.core-theme-page .badge-success,
body.core-theme-page .session-current {
  color: var(--color-success-text);
  background: var(--color-success-soft);
  border-color: var(--color-success-border);
}

body.core-theme-page .badge-failed,
body.core-theme-page .badge-free-trial-ended {
  color: var(--color-danger-text);
  background: var(--color-danger-soft);
  border-color: var(--color-danger-border);
}

body.core-theme-page .badge-pending,
body.core-theme-page .badge-free-trial-warning,
body.core-theme-page .badge-lock,
body.core-theme-page .badge-lite-lock {
  color: var(--color-warning-text);
  background: var(--color-warning-soft);
  border-color: var(--color-warning-border);
}

body.core-theme-page .badge-muted,
body.core-theme-page .badge-manual,
body.core-theme-page .badge-scheduled,
body.core-theme-page .plan-pill,
body.core-theme-page .upgrade-card-current-badge {
  color: var(--color-text-secondary);
  background: var(--color-surface-secondary);
  border-color: var(--color-border-default);
}

body.core-theme-page .plan-chip,
body.core-theme-page .upgrade-card-badge {
  color: var(--color-brand-foreground);
  background: var(--color-brand-soft);
  border: 1px solid var(--color-brand-border);
}

body.core-theme-page .btn {
  border: 1px solid transparent;
  box-shadow: none;
  transform: none;
}

body.core-theme-page .btn:hover:not(:disabled) {
  transform: none;
}

body.core-theme-page .btn-solid,
body.core-theme-page .btn-primary {
  background: var(--color-brand);
  border-color: var(--color-brand);
  color: var(--color-brand-foreground);
}

body.core-theme-page .btn-solid:hover:not(:disabled),
body.core-theme-page .btn-primary:hover:not(:disabled) {
  background: var(--color-brand-hover);
  border-color: var(--color-brand-hover);
  color: var(--color-brand-foreground);
}

body.core-theme-page .btn-outline {
  background: var(--color-info-soft);
  border-color: var(--color-info-border);
  color: var(--color-info-text);
}

body.core-theme-page .btn-outline:hover:not(:disabled) {
  background: color-mix(in srgb, var(--color-info) 14%, transparent);
  border-color: var(--color-info);
  color: var(--color-info-text);
}

body.core-theme-page .btn-ghost {
  background: transparent;
  border-color: var(--color-border-default);
  color: var(--color-text-secondary);
}

body.core-theme-page .btn-ghost:hover:not(:disabled) {
  background: var(--color-surface-hover);
  border-color: var(--color-border-strong);
  color: var(--color-text-primary);
}

body.core-theme-page .btn-danger {
  background: var(--color-danger-soft);
  border-color: var(--color-danger-border);
  color: var(--color-danger-text);
}

body.core-theme-page .btn-danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--color-danger) 18%, transparent);
  border-color: var(--color-danger);
  color: var(--color-danger-text);
}

body.core-theme-page .btn-danger-solid {
  background: var(--color-danger);
  border-color: var(--color-danger);
  color: var(--color-danger-on-strong);
}

body.core-theme-page .btn-danger-solid:hover:not(:disabled) {
  background: var(--color-danger-hover);
  border-color: var(--color-danger-hover);
}

body.core-theme-page .btn:disabled,
body.core-theme-page .btn[aria-disabled="true"],
body.core-theme-page .tab-btn:disabled,
body.core-theme-page .tab-btn.is-locked {
  background: var(--color-disabled-bg);
  border-color: var(--color-disabled-border);
  color: var(--color-disabled-text);
  opacity: 1;
  cursor: not-allowed;
}

body.core-theme-page .btn:focus-visible,
body.core-theme-page .link-btn:focus-visible,
body.core-theme-page .kebab:focus-visible,
body.core-theme-page .tab-btn:focus-visible,
body.core-theme-page .audit-details summary:focus-visible,
body.core-theme-page .checkbox-label:focus-within,
body.core-theme-page .theme-choice-card:focus-visible,
body.core-theme-page .insights-about-modal-close:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

body.core-theme-page .field input,
body.core-theme-page .field select,
body.core-theme-page .field textarea,
body.core-theme-page .modal input,
body.core-theme-page .readonly-value {
  background: var(--color-surface-primary);
  border: 1px solid var(--color-border-default);
  color: var(--color-text-primary);
}

body.core-theme-page .field input::placeholder,
body.core-theme-page .field textarea::placeholder {
  color: var(--color-text-disabled);
}

body.core-theme-page .field input:focus,
body.core-theme-page .field select:focus,
body.core-theme-page .field textarea:focus,
body.core-theme-page .modal input:focus {
  border-color: var(--color-border-focus);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-focus-ring) 18%, transparent);
}

body.core-theme-page .field input:disabled,
body.core-theme-page .field select:disabled,
body.core-theme-page .field textarea:disabled,
body.core-theme-page .field input[readonly] {
  background: var(--color-disabled-bg);
  border-color: var(--color-disabled-border);
  color: var(--color-disabled-text);
  cursor: not-allowed;
}

body.core-theme-page .checkbox-label {
  color: var(--color-text-secondary);
}

body.core-theme-page input[type="checkbox"],
body.core-theme-page input[type="radio"] {
  accent-color: var(--color-brand);
}

body.core-theme-page .toggle .track {
  background: var(--color-disabled-bg);
  border: 1px solid var(--color-border-default);
}

body.core-theme-page .toggle .track::after {
  background: var(--color-text-disabled);
}

body.core-theme-page .toggle input:checked ~ .track {
  background: var(--color-brand-soft);
  border-color: var(--color-brand-border);
}

body.core-theme-page .toggle input:checked ~ .track::after {
  background: var(--color-brand);
}

body.core-theme-page .toggle-disabled .track {
  background: var(--color-disabled-bg);
  opacity: 1;
}

body.core-theme-page .form-error,
body.core-theme-page .danger-card h2,
body.core-theme-page .link-btn.danger {
  color: var(--color-danger-text);
}

body.core-theme-page .danger-card {
  background: var(--color-danger-soft);
  border-color: var(--color-danger-border);
}

body.core-theme-page .modal-overlay {
  background: var(--color-surface-overlay);
}

body.core-theme-page .modal {
  background: var(--color-surface-elevated);
  border-color: var(--color-border-default);
  color: var(--color-text-primary);
  box-shadow: 0 24px 70px var(--color-shadow-modal);
}

body.core-theme-page .modal h3 {
  color: var(--color-text-primary);
}

body.core-theme-page .modal-actions {
  align-items: center;
}

body.core-theme-page .alert {
  border: 1px solid var(--color-info-border);
  background: var(--color-info-soft);
  color: var(--color-info-text);
}

body.core-theme-page .alert-warning {
  border-color: var(--color-warning-border);
  background: var(--color-warning-soft);
  color: var(--color-warning-text);
}

body.core-theme-page .toast {
  background: var(--color-surface-elevated);
  border: 1px solid var(--color-border-default);
  color: var(--color-text-primary);
  box-shadow: 0 12px 36px var(--color-shadow-modal);
}

body.core-theme-page .toast-success {
  border-left-color: var(--color-success);
  background: var(--color-success-soft);
  color: var(--color-success-text);
}

body.core-theme-page .toast-error {
  border-left-color: var(--color-danger);
  background: var(--color-danger-soft);
  color: var(--color-danger-text);
}

body.core-theme-page .toast-warning {
  border-left-color: var(--color-warning);
  background: var(--color-warning-soft);
  color: var(--color-warning-text);
}

body.core-theme-page .toast-info {
  border-left-color: var(--color-info);
  background: var(--color-info-soft);
  color: var(--color-info-text);
}

body.core-theme-page .settings-nav {
  border-radius: var(--radius-lg);
  padding: var(--space-8);
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

body.core-theme-page .tab-btn {
  color: var(--color-text-secondary);
}

body.core-theme-page .tab-btn:hover:not(:disabled) {
  background: var(--color-surface-hover);
  color: var(--color-text-primary);
}

body.core-theme-page .tab-btn.active {
  background: var(--color-brand-soft);
  color: var(--color-brand);
}

body.core-theme-page .theme-choice-card {
  background: var(--color-surface-secondary);
  border-color: var(--color-border-default);
  color: var(--color-text-secondary);
}

body.core-theme-page .theme-choice-card.is-active {
  background: var(--color-brand-soft);
  border-color: var(--color-brand-border);
  color: var(--color-brand);
}

body.core-theme-page .pref-row,
body.core-theme-page .session-row,
body.core-theme-page .key-row,
body.core-theme-page .audit-row,
body.core-theme-page .app-timeline-item,
body.core-theme-page .app-activity-item,
body.core-theme-page .history-row {
  border-bottom-color: var(--color-border-default);
}

body.core-theme-page .key-reveal,
body.core-theme-page .report-box,
body.core-theme-page .pitr-fresh-warning,
body.core-theme-page .override-active-conn-warning {
  background: var(--color-surface-secondary);
  border: 1px solid var(--color-border-default);
  color: var(--color-text-primary);
}

body.core-theme-page .key-reveal code,
body.core-theme-page #twofa-secret-text {
  background: var(--color-surface-secondary);
  border: 1px solid var(--color-border-default);
  color: var(--color-text-primary);
}

body.core-theme-page .audit-details summary,
body.core-theme-page .link-btn {
  color: var(--color-info-text);
}

body.core-theme-page .audit-details summary:hover,
body.core-theme-page .link-btn:hover {
  color: var(--color-info);
}

body.core-theme-page .dash-table-card {
  overflow-x: auto;
  border-radius: var(--radius-lg);
}

body.core-theme-page .dash-table {
  width: 100%;
  border-collapse: collapse;
  color: var(--color-text-primary);
}

body.core-theme-page .dash-table th,
body.core-theme-page .dash-table td {
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--color-border-default);
  text-align: left;
}

body.core-theme-page .dash-table th {
  background: var(--color-surface-secondary);
  color: var(--color-text-secondary);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

body.core-theme-page .dash-table tr:hover td {
  background: var(--color-surface-hover);
}

body.core-theme-page .app-recovery-center {
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--color-success) 8%, transparent), transparent),
    var(--color-surface-primary);
}

body.core-theme-page .paywall-guard-main-card,
body.core-theme-page .paywall-modal {
  background: var(--color-surface-primary);
  border-color: var(--color-border-default);
  box-shadow: 0 20px 50px var(--color-shadow-card);
}

body.core-theme-page .paywall-guard-title-hero,
body.core-theme-page .paywall-preview-card h4 {
  background: none;
  -webkit-text-fill-color: currentColor;
  color: var(--color-text-primary);
}

body.core-theme-page .paywall-guard-subtitle-hero,
body.core-theme-page .paywall-guard-fcard-desc,
body.core-theme-page .paywall-preview-card p,
body.core-theme-page .paywall-guard-cta-caption,
body.core-theme-page .paywall-guard-teaser-pill {
  color: var(--color-text-secondary);
}

body.core-theme-page .paywall-guard-fcard,
body.core-theme-page .paywall-guard-teaser-card,
body.core-theme-page .paywall-preview-card {
  background: var(--color-surface-secondary);
  border-color: var(--color-border-default);
  box-shadow: none;
}

body.core-theme-page .paywall-guard-cta-btn-hero {
  background: var(--color-brand);
  color: var(--color-brand-foreground) !important;
  box-shadow: none;
}

@media (max-width: 640px) {
  body.core-theme-page .app-content {
    padding-top: var(--space-16);
  }

  body.core-theme-page .dash-main .app-hero,
  body.core-theme-page .dash-main .app-score-card,
  body.core-theme-page .dash-main .app-panel,
  body.core-theme-page .dash-main .settings-section {
    padding: var(--space-16);
  }

  body.core-theme-page .theme-preference-group {
    grid-template-columns: 1fr;
  }

  body.core-theme-page .pref-row,
  body.core-theme-page .key-row {
    align-items: flex-start;
  }
}
