:root {
  /* ---- Round 29: refreshed SaaS design tokens ----
     Neutral slate + indigo accent, softer shadows, larger radii.
     Semantic color names kept identical to before so every page/badge
     that references var(--ok)/var(--warn)/etc keeps working unchanged --
     only the underlying values moved to a slightly richer, more modern
     palette. */
  --ink: #14181f;
  --ink-soft: #4c5566;
  --muted: #8892a3;
  --line: #e5e8ee;
  --line-soft: #eef0f4;
  --bg: #f5f6f9;
  --panel: #ffffff;
  --accent: #4f46e5;
  --accent-soft: #eef0ff;
  --accent-ink: #3730a3;
  --ok: #0f9d63;
  --ok-bg: #e7f8ef;
  --warn: #b4740a;
  --warn-bg: #fbf1dc;
  --danger: #d0342c;
  --danger-bg: #fdecea;
  --radius: 10px;
  --radius-lg: 14px;
  --radius-sm: 7px;
  --shadow-sm: 0 1px 2px rgba(20, 24, 31, 0.05);
  --shadow-md: 0 6px 20px rgba(20, 24, 31, 0.08);
  --shadow-card-hover: 0 10px 28px rgba(20, 24, 31, 0.10);
  --mono: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
  --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Inter, Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent-ink); text-decoration: none; }
a:hover { text-decoration: underline; }

.mono { font-family: var(--mono); }
.muted { color: var(--muted); }
.small { font-size: 12px; }
.strong { font-weight: 600; }

/* ---- layout ---- */
.wrap {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px;
}
.wrap-narrow { max-width: 700px; }

main.wrap { padding-top: 28px; padding-bottom: 60px; }

/* ---- page header ---- */
.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 22px;
}
.page-head h1 {
  margin: 0 0 4px;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.3px;
}
.page-head p {
  margin: 0;
  color: var(--muted);
  font-size: 13.5px;
}
.page-head-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* ---- top nav ---- */
.topnav {
  background: var(--ink);
  color: #fff;
}
.topnav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 56px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  color: #fff;
  font-weight: 700;
  letter-spacing: 0.2px;
  font-size: 14.5px;
}
.brand:hover { text-decoration: none; opacity: 0.9; }
.brand-mark {
  width: 26px; height: 26px;
  object-fit: contain;
  border-radius: 6px;
}
.topnav-links { display: flex; align-items: center; }
.topnav-links a {
  color: #b7c0d1;
  margin-left: 22px;
  font-size: 13px;
  font-weight: 500;
  transition: color .12s;
}
.topnav-links a:hover { color: #fff; text-decoration: none; }

/* ---- impersonation banner (Round 38 follow-up #8) ----
   Deliberately loud (warning colors, full-width, above the regular
   topnav) -- this needs to be impossible to miss while it's active, both
   so the admin never forgets they're not in their own account, and so
   anyone glancing at the screen with them can tell immediately. */
.impersonation-banner {
  background: var(--warn-bg);
  color: var(--warn);
  border-bottom: 1px solid #f1dfb0;
}
.impersonation-banner-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 20px;
  font-size: 13px;
  font-weight: 600;
}
.impersonation-banner form { margin: 0; }

/* ---- stat cards ---- */
.stat-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-bottom: 22px;
}
.stat-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  box-shadow: var(--shadow-sm);
  display: flex;
  align-items: center;
  gap: 14px;
  transition: box-shadow .15s, transform .1s;
}
.stat-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.stat-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
}
.stat-value { font-size: 24px; font-weight: 700; letter-spacing: -0.5px; line-height: 1.1; }
.stat-label { color: var(--muted); font-size: 12px; margin-top: 3px; font-weight: 500; }

/* ---- panels ---- */
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 22px 24px;
  margin-bottom: 20px;
  box-shadow: var(--shadow-sm);
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  flex-wrap: wrap;
  gap: 10px;
}
.panel-head.plain {
  background: transparent;
  border: none;
  padding: 0;
  margin-bottom: 20px;
}
.panel-head h2 { margin: 0; font-size: 16px; font-weight: 700; }
.panel-head-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* ---- buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 9px 16px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 600;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background .12s, border-color .12s, box-shadow .12s, transform .05s;
  line-height: 1.2;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79, 70, 229, 0.25); }
.btn-primary:hover { background: var(--accent-ink); text-decoration: none; }
.btn-ghost { background: var(--panel); border-color: var(--line); color: var(--ink-soft); }
.btn-ghost:hover { border-color: #c7cedb; background: #fafbfd; text-decoration: none; }
.btn-sm { padding: 7px 12px; font-size: 12.5px; }
.btn-block { width: 100%; margin-top: 6px; }

/* ---- table ---- */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.table { width: 100%; border-collapse: collapse; }
.table th {
  text-align: left;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted);
  font-weight: 700;
  background: #fafbfd;
  border-bottom: 1px solid var(--line);
  padding: 10px 12px;
  white-space: nowrap;
}
.table td {
  padding: 14px 12px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}
.table tr:last-child td { border-bottom: none; }
.table tbody tr { transition: background .1s; }
.table tbody tr:hover { background: #fafbfd; }
.truncate {
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row-actions { display: flex; flex-wrap: wrap; gap: 2px 12px; }
.row-actions a { font-size: 12px; font-weight: 600; color: var(--ink-soft); }
.row-actions a:hover { color: var(--accent-ink); }
.danger-link { color: var(--danger) !important; }
.clicks-link { font-weight: 700; }

/* ---- badges ---- */
.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 700;
}
.badge-perm { background: var(--accent-soft); color: var(--accent-ink); }
.badge-temp { background: #fdeee0; color: #a05a12; }
.badge-status-active { background: var(--ok-bg); color: var(--ok); }
.badge-status-paused { background: var(--warn-bg); color: var(--warn); }
.badge-ssl-on { background: var(--ok-bg); color: var(--ok); margin-top: 4px; display: inline-block; }
.badge-ssl-off { background: var(--warn-bg); color: var(--warn); margin-top: 4px; display: inline-block; }

/* ---- forms ---- */
.form-row { margin-bottom: 16px; }
.form-row-inline { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.checkbox-row { display: flex; flex-direction: column; gap: 8px; }
.checkbox-label { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-soft); }
.checkbox-label input { width: auto; }

label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 5px;
}
input[type="text"], input[type="url"], input[type="email"], input[type="password"], input[type="date"], input[type="datetime-local"], input[type="number"], select, textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: 14px;
  color: var(--ink);
  background: #fff;
  font-family: inherit;
  transition: border-color .12s, box-shadow .12s;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.14);
}
.hint { font-size: 12px; color: var(--muted); margin: 5px 0 0; }
.form-actions { display: flex; gap: 10px; margin-top: 22px; }

.path-generate-row {
  display: flex;
  gap: 8px;
}
.path-generate-row input { flex: 1; }
.path-generate-row select {
  width: auto;
  flex: 0 0 auto;
}
.path-generate-row .btn {
  flex: 0 0 auto;
  white-space: nowrap;
}

.search-form input {
  width: 240px;
}

/* ---- form sections (Round 29): break a long form into labeled,
   collapsible-feeling groups so it reads as a guided flow instead of one
   wall of fields -- same underlying <form>/fields, purely visual/markup
   grouping. */
.form-section {
  padding: 20px 0;
  border-bottom: 1px solid var(--line-soft);
}
.form-section:first-child { padding-top: 0; }
.form-section:last-of-type { border-bottom: none; padding-bottom: 4px; }
.form-section-head { margin-bottom: 16px; }
.form-section-head h3 {
  margin: 0 0 2px;
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 8px;
}
.form-section-head p { margin: 0; font-size: 12.5px; color: var(--muted); }

details.form-section > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
details.form-section > summary::-webkit-details-marker { display: none; }
details.form-section > summary .form-section-head { margin-bottom: 0; }
details.form-section[open] > summary { margin-bottom: 16px; }
details.form-section > summary .chevron {
  color: var(--muted);
  font-size: 12px;
  transition: transform .15s;
  flex-shrink: 0;
}
details.form-section[open] > summary .chevron { transform: rotate(90deg); }
details.form-section .form-section-body { padding-top: 4px; }

/* ---- setup-type cards (Round 35): the three-way Full Domain / URL /
   Branded redirect-type picker at the top of the New Redirect form. Each
   card is a big clickable label wrapping a radio input, styled like a
   selectable tile rather than a plain radio list. */
.setup-type-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.setup-type-card {
  position: relative;
  display: block;
  padding: 14px 14px 14px 40px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: border-color .12s, box-shadow .12s, background .12s;
}
.setup-type-card:hover { border-color: var(--accent); }
.setup-type-card input[type="radio"] {
  position: absolute;
  top: 16px;
  left: 14px;
  width: 16px;
  margin: 0;
}
.setup-type-card .setup-type-card-title {
  display: block;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 3px;
}
.setup-type-card .setup-type-card-desc {
  display: block;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.4;
}
.setup-type-card:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: var(--shadow-sm);
}
.setup-type-card:has(input:checked) .setup-type-card-title { color: var(--accent-ink); }

@media (max-width: 720px) {
  .setup-type-cards { grid-template-columns: 1fr; }
}

/* ---- filter toolbar ---- */
.filter-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-bottom: 18px;
  padding: 12px 14px;
  background: #fafbfd;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.filter-toolbar select { width: auto; padding: 8px 10px; font-size: 13px; }
.filter-toolbar .search-form input { padding: 8px 12px; }

/* ---- empty state ---- */
.empty-state {
  text-align: center;
  padding: 52px 20px;
  color: var(--muted);
}
.empty-state .empty-icon {
  font-size: 34px;
  width: 64px;
  height: 64px;
  margin: 0 auto 14px;
  border-radius: 16px;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
}
.empty-state p { max-width: 360px; margin: 0 auto; }
.empty-state .btn { margin-top: 16px; }

/* ---- alerts ---- */
.alert {
  padding: 11px 15px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  margin-bottom: 14px;
}
.alert-error { background: var(--danger-bg); color: var(--danger); border: 1px solid #f5c6c0; }

/* ---- login ---- */
.login-body {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(160deg, #14181f 0%, #232c3d 100%);
}
.login-card {
  background: #fff;
  width: 340px;
  padding: 32px 30px;
  border-radius: var(--radius-lg);
  box-shadow: 0 20px 60px rgba(0,0,0,0.35);
}
.login-mark {
  width: 48px; height: 48px;
  object-fit: contain;
  margin-bottom: 14px;
}
.login-card h1 { font-size: 19px; margin: 0 0 4px; }
.login-card p { margin: 0 0 18px; }

/* ---- QR panel ---- */
.qr-row {
  display: flex;
  align-items: center;
  gap: 20px;
}
.qr-image {
  width: 140px;
  height: 140px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
  padding: 8px;
}

/* ---- breakdown grid (device/OS/browser/country) ---- */
.breakdown-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-bottom: 20px;
}
.breakdown-grid .panel { margin-bottom: 0; padding: 16px 18px; }
.breakdown-grid .table td { padding: 7px 4px; font-size: 13px; }
.breakdown-grid .table td:last-child { text-align: right; font-weight: 600; }

/* ---- bot indicators ---- */
.badge-bot { background: #f1f0f4; color: #6b6478; }
.badge-expiry-expired { background: var(--danger-bg); color: var(--danger); }
.badge-expiry-soon { background: var(--warn-bg); color: var(--warn); }
.badge-expiry-warning { background: #fdeee0; color: #a05a12; }
.badge-expiry-ok { background: var(--ok-bg); color: var(--ok); }
.badge-expiry-unknown { background: #f1f0f4; color: #6b6478; }
tr.row-bot { opacity: 0.6; }

/* ---- DNS check ---- */
.badge-dns-ok { background: var(--ok-bg); color: var(--ok); }
.badge-dns-mismatch { background: var(--danger-bg); color: var(--danger); }
.badge-dns-unchecked { background: #f1f0f4; color: #6b6478; }

@media (max-width: 900px) {
  .breakdown-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 720px) {
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  .form-row-inline { grid-template-columns: 1fr; }
  .search-form input { width: 160px; }
  .path-generate-row { flex-wrap: wrap; }
  .path-generate-row input { flex: 1 1 100%; }
  .page-head { flex-direction: column; }
}

/* ---- print ---- */
.print-only { display: none; }

@media print {
  .no-print, .topnav { display: none !important; }
  .print-only { display: block; margin: 0 0 16px; font-size: 18px; }
  body { background: #fff; }
  main.wrap { padding: 0; }
  .panel { border: none; box-shadow: none; padding: 0; margin-bottom: 24px; }
  .stat-row { display: none; } /* dashboard summary cards aren't useful on paper */
  .table th, .table td { padding: 6px 8px; font-size: 12px; }
  .badge { border: 1px solid currentColor; background: none !important; }
  a { color: inherit; text-decoration: none; }
}

/* ---- multi-user / groups ---- */
.badge-role-admin { background: var(--accent-soft); color: var(--accent-ink); margin-top: 4px; display: inline-block; }
/* Round 38 follow-up #5: the lighter "support" admin role -- reuses the --warn token pair (amber) so it reads as distinct from both admin (accent) and user (neutral gray) at a glance. */
.badge-role-support { background: var(--warn-bg); color: var(--warn); margin-top: 4px; display: inline-block; }

/* ---- admin hub ---- */
.badge-status-pending { background: var(--warn-bg); color: var(--warn); }
.alert-info { background: var(--accent-soft); color: var(--accent-ink); border: 1px solid #d7d9ff; padding: 12px 16px; border-radius: var(--radius); margin-bottom: 16px; }
.admin-hub-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: 1fr;
}
@media (min-width: 680px) {
  .admin-hub-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 960px) {
  .admin-hub-grid { grid-template-columns: repeat(4, 1fr); }
}
.admin-hub-card {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 0;
  color: var(--ink);
  transition: border-color .15s, transform .1s, box-shadow .15s;
}
.admin-hub-card:hover {
  border-color: var(--accent);
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: var(--shadow-card-hover);
}
.admin-hub-icon {
  font-size: 26px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  border-radius: 10px;
  flex-shrink: 0;
}

/* ---- user roles/status/danger button ---- */
.badge-role-user { background: #f1f0f4; color: #6b6478; }
.badge-status-approved { background: var(--ok-bg); color: var(--ok); }
.badge-status-rejected { background: var(--danger-bg); color: var(--danger); }
/* Round 38: suspension is orthogonal to the status enum above (a
   suspended account can be 'approved' status but still blocked at login),
   so it gets its own badge class shown alongside the status badge rather
   than folded into it. */
.badge-suspended { background: var(--danger-bg); color: var(--danger); }
.btn-danger { background: var(--danger-bg); color: var(--danger); border-color: #f5c6c0; }
.btn-danger:hover { background: #f9d5d0; }

/* ---- user edit: group checkboxes ---- */
.checkbox-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 0;
}

/* ---- bulk actions toolbar ---- */
.bulk-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--accent-soft);
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  margin-bottom: 12px;
}
