/* ============================================================
   Zharkwave SEO Toolkit — design system
   Cloudflare-dashboard-inspired: dark sidebar/content, card-based
   panels, flat buttons, rounded pill badges. Dark mode is the
   default (matches the reference); a light mode is fully defined
   below and toggled via [data-theme] on <html>.
   ============================================================ */

:root {
  /* ---- Dark mode (default) ---- */
  --bg: #151414;
  --bg-elevated: #101010;
  --bg-panel: #101010;
  --bg-panel-2: #201f1f;
  --bg-hover: #272626;
  --border: #302f2f;
  --text: #f7f4ee;
  --text-dim: #9a9d9f;
  --text-faint: #6f7274;
  --brand: #1c46f2;
  --brand-hover: #3457f5;
  --brand-text: #ffffff;
  --pass: #35d399;
  --warn: #f5b942;
  --fail: #ef5a6f;
  --info: #6c8cff;
  --radius: 10px;
  --radius-sm: 6px;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  /* One vertical rhythm for every page. Stacked blocks are spaced by flex
     `gap` on their container rather than per-element margins — margins were
     silently doing nothing between a .panel and a plain results <div>, which
     is why some pages read as cramped and others didn't. */
  --stack-gap: 20px;
}

:root[data-theme="light"] {
  --bg: #ffffff;
  --bg-elevated: #ffffff;
  --bg-panel: #ffffff;
  --bg-panel-2: #f5f6f7;
  --bg-hover: #eef0f2;
  --border: #e3e5e8;
  --text: #212427;
  --text-dim: #6b6e70;
  --text-faint: #96999b;
  --brand: #1c46f2;
  --brand-hover: #1636c9;
  --brand-text: #ffffff;
  --pass: #1a9e6c;
  --warn: #b9790a;
  --fail: #c23a4c;
  --info: #3a5bd9;
  --shadow: 0 1px 2px rgba(33, 36, 39, 0.06);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, Helvetica, Arial, sans-serif;
}

body { transition: background-color 0.15s ease, color 0.15s ease; }

a { color: var(--info); }

svg { display: block; }

.app-shell {
  display: flex;
  min-height: 100vh;
}

/* ---------- Sidebar ---------- */
.sidebar {
  width: 240px;
  flex-shrink: 0;
  background: var(--bg-elevated);
  border-right: 1px solid var(--border);
  padding: 16px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px 14px;
}

.brand .theme-toggle { margin-left: 4px; }

.brand-mark {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--brand);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.brand-mark svg { width: 15px; height: 15px; }

.brand-name {
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.1px;
}

.brand-sub {
  font-size: 12.5px;
  color: var(--text-dim);
  margin-top: -2px;
}

.nav-group { display: flex; flex-direction: column; gap: 1px; }
.nav-group + .nav-group { margin-top: 14px; }

.nav-group-label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-faint);
  padding: 4px 10px 6px;
}

.nav {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  font-size: 14.5px;
  color: var(--text-dim);
  cursor: pointer;
  border: none;
  background: none;
  text-align: left;
  width: 100%;
  font-family: inherit;
}

.nav-item-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0.85;
}
.nav-item-icon svg { width: 16px; height: 16px; stroke: currentColor; }

.nav-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.nav-item:hover { background: var(--bg-hover); color: var(--text); }

.nav-item.active {
  background: var(--bg-hover);
  color: var(--text);
  box-shadow: inset 2px 0 0 var(--brand);
}

.nav-item[disabled] {
  cursor: not-allowed;
  opacity: 0.5;
}
.nav-item[disabled]:hover { background: none; color: var(--text-dim); }

.badge-soon {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 999px;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  flex-shrink: 0;
}

.sidebar-footer {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text-dim);
  padding: 10px 8px 4px;
  border-top: 1px solid var(--border);
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--bg-panel-2);
  color: var(--text-dim);
  cursor: pointer;
  flex-shrink: 0;
}
.theme-toggle:hover { color: var(--text); border-color: var(--brand); }
.theme-toggle svg { width: 15px; height: 15px; }
.theme-toggle .icon-sun { display: none; }
:root[data-theme="light"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: none; }

/* ---------- Main ---------- */
.main {
  flex: 1;
  min-width: 0;
  padding: 30px 36px 60px;
}

/* Every view stacks its blocks with one consistent gap. Empty result
   containers are hidden so they don't leave a phantom gap before anything
   has been run. */
.main > section {
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap);
}
.main > section > :empty { display: none; }
/* The gap owns the spacing now — per-element margins would double it. */
.main > section > .panel + .panel { margin-top: 0; }

.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.page-title {
  font-size: 24px;
  font-weight: 700;
  margin: 0 0 4px;
  letter-spacing: -0.2px;
}

.page-desc {
  color: var(--text-dim);
  font-size: 15px;
  margin: 0;
  max-width: 640px;
}

.panel {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  box-shadow: var(--shadow);
}

.panel + .panel { margin-top: var(--stack-gap); }

#projectsView,
#projectTabBody {
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap);
}
#projectsView > :empty,
#projectTabBody > :empty { display: none; }
#projectsView > .panel + .panel,
#projectTabBody > .panel + .panel { margin-top: 0; }
/* The title block and its tab row read as one unit — full stack spacing
   between them makes the tabs look detached from the project they belong to. */
#projectsView > .workspace-head + .workspace-tabs { margin-top: -6px; }
/* These carry their own margins for use outside a flex stack; inside one the
   gap already handles it. */
#projectTabBody > .stat-cards { margin-top: 0; }

.form-row {
  display: flex;
  gap: 10px;
  row-gap: 14px;
  flex-wrap: wrap;
  align-items: flex-end;
}
.form-row + .form-row { margin-top: 14px; }

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 220px;
}

.field label {
  font-size: 13.5px;
  color: var(--text-dim);
}

input[type="text"], input[type="url"], input[type="password"], input[type="number"], input[type="email"], input[type="search"], select, textarea {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  color: var(--text);
  font-size: 15px;
  outline: none;
  font-family: inherit;
}
input[type="text"]:focus, input[type="url"]:focus, input[type="password"]:focus, input[type="number"]:focus, input[type="email"]:focus, input[type="search"]:focus, select:focus, textarea:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(28, 70, 242, 0.18);
}

/**
 * No spinner on number inputs.
 *
 * The little up/down stepper is a tiny hit target that appears on hover,
 * shifts the text as it does, and steps by 1 — useless for a field like
 * "Max pages" where the useful jumps are 50 at a time. Every number field
 * here is quicker to type than to click.
 *
 * Arrow keys still increment the value: this hides the control, it does not
 * change the input's behaviour, and the field stays type="number" so mobile
 * still gets the numeric keypad and the browser still validates it.
 */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
textarea {
  width: 100%;
  resize: vertical;
  line-height: 1.5;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 14px;
}
select {
  appearance: none;
}

.btn {
  background: var(--brand);
  color: var(--brand-text);
  border: none;
  border-radius: var(--radius-sm);
  padding: 10px 18px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  align-self: flex-end;
}
.btn:hover { background: var(--brand-hover); }
.btn:disabled { opacity: 0.6; cursor: not-allowed; }

.btn-secondary {
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  color: var(--text);
}
.btn-secondary:hover { background: var(--bg-hover); }

.hint {
  font-size: 13px;
  color: var(--text-dim);
  margin-top: 8px;
}

/* ---------- Score / summary ---------- */
.summary-row {
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}

.score-circle {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  font-weight: 700;
  flex-shrink: 0;
  border: 4px solid var(--border);
}

.score-circle.good { border-color: var(--pass); color: var(--pass); }
.score-circle.mid { border-color: var(--warn); color: var(--warn); }
.score-circle.bad { border-color: var(--fail); color: var(--fail); }

.summary-stats {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.stat-value { font-size: 19.5px; font-weight: 700; }
.stat-label { font-size: 12.5px; color: var(--text-dim); }

/* ---------- Category filter chips ---------- */
.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 16px 0 4px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-panel-2);
  font-size: 14px;
  color: var(--text-dim);
  cursor: pointer;
  user-select: none;
}
.chip input { accent-color: var(--brand); }
.chip.active { color: var(--text); border-color: var(--brand); }

/* ---------- Checks list ---------- */
.check-group {
  margin-top: 18px;
}

.check-group-title {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-faint);
  margin: 0 0 8px;
}

.check-item {
  display: flex;
  gap: 12px;
  padding: 11px 4px;
  border-top: 1px solid var(--border);
}
.check-item:first-child { border-top: none; }

.check-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-top: 5px;
  flex-shrink: 0;
}
.check-dot.pass { background: var(--pass); }
.check-dot.warn { background: var(--warn); }
.check-dot.fail { background: var(--fail); }
.check-dot.info { background: var(--info); }

.check-body { flex: 1; min-width: 0; }
.check-label { font-size: 15px; font-weight: 600; }
.check-message { font-size: 14px; color: var(--text-dim); margin-top: 2px; line-height: 1.5; }

.check-recommendation {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  margin-top: 8px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  font-size: 13.5px;
  color: var(--text-dim);
  line-height: 1.5;
}
.check-recommendation strong { color: var(--text); font-weight: 600; }

.kw-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.kw-pill {
  font-size: 13px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text-dim);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 13px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
}

.empty-state {
  color: var(--text-dim);
  font-size: 14.5px;
  padding: 30px 10px;
  text-align: center;
}

.error-box {
  background: rgba(239, 90, 111, 0.12);
  border: 1px solid var(--fail);
  color: var(--fail);
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  font-size: 14.5px;
}

.demo-banner {
  background: rgba(245, 185, 66, 0.12);
  border: 1px solid var(--warn);
  color: var(--warn);
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  margin-bottom: 14px;
}

.coming-soon {
  text-align: center;
  padding: 60px 20px;
  color: var(--text-dim);
}
.coming-soon h2 { color: var(--text); font-size: 18.5px; }

/* ---------- Actions row / sub-panels ---------- */
.actions-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.sub-panel {
  margin-top: 14px;
  background: var(--bg-panel-2);
}

/* ---------- Mode toggle (Landing Page: Optimize vs Write new) ---------- */
.mode-toggle {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border-radius: var(--radius);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  margin-bottom: 16px;
}
.mode-toggle-btn {
  border: none;
  background: transparent;
  color: var(--text-dim);
  font-size: 14.5px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 7px;
  cursor: pointer;
}
.mode-toggle-btn.active { background: var(--brand); color: var(--brand-text); }

/* ---------- Optimization suggestion cards (Landing Page: optimize mode) ---------- */
.opt-area {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.opt-area:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.opt-area-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.opt-area-title { font-size: 15.5px; font-weight: 700; }
.opt-area-reasons { font-size: 14px; color: var(--text-dim); margin-bottom: 10px; line-height: 1.5; }
.opt-suggestion {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  margin-top: 7px;
}
.opt-suggestion-text { flex: 1; font-size: 14.5px; line-height: 1.5; word-break: break-word; }
.opt-suggestion-text .opt-sub { display: block; font-size: 13px; color: var(--text-dim); margin-top: 2px; }
.opt-copy-btn {
  flex-shrink: 0;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text-dim);
  font-size: 13px;
  padding: 5px 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.opt-copy-btn:hover { color: var(--text); border-color: var(--brand); }
.opt-copy-btn.copied { color: var(--pass); border-color: var(--pass); }
.opt-schema-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13.5px;
  white-space: pre-wrap;
  word-break: break-word;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  margin-top: 6px;
  max-height: 260px;
  overflow-y: auto;
}

/* ---------- Image picker (Article / Landing generators) ---------- */
.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
  margin-top: 8px;
}

.image-thumb {
  display: block;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 2px solid var(--border);
  cursor: pointer;
  background: var(--bg);
}
.image-thumb.selected { border-color: var(--brand); }
.image-thumb img { display: block; width: 100%; height: 84px; object-fit: cover; }
.image-credit {
  display: block;
  font-size: 11.5px;
  color: var(--text-dim);
  padding: 4px 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------- Device tabs (reused: SERP preview, social preview simulator) ---------- */
.device-tabs {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border-radius: var(--radius);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.device-tab {
  border: none;
  background: transparent;
  color: var(--text-dim);
  font-size: 14px;
  font-weight: 600;
  padding: 7px 13px;
  border-radius: 7px;
  cursor: pointer;
  white-space: nowrap;
}
.device-tab.active { background: var(--brand); color: var(--brand-text); }

/* ---------- Google SERP preview ---------- */
.serp-card {
  max-width: 600px;
  font-family: arial, sans-serif;
}
.serp-card[data-device="mobile"] { max-width: 380px; }
.serp-url-row { display: flex; align-items: center; gap: 10px; margin-bottom: 3px; }
.serp-favicon {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  object-fit: contain;
  padding: 4px;
  flex-shrink: 0;
}
.serp-site-name { font-size: 15.5px; color: var(--text); line-height: 1.3; }
.serp-url { font-size: 13.5px; color: var(--text-dim); line-height: 1.3; overflow-wrap: anywhere; }
.serp-title {
  font-size: 22px;
  color: var(--info);
  line-height: 1.3;
  margin-top: 2px;
  overflow-wrap: break-word;
}
.serp-card[data-device="mobile"] .serp-title { font-size: 19.5px; }
.serp-desc { font-size: 15.5px; color: var(--text-dim); line-height: 1.55; margin-top: 4px; overflow-wrap: break-word; }

/* ---------- Generic link preview (OG / Twitter Card unfurl) ---------- */
.link-preview-tabs { display: flex; gap: 8px; margin-bottom: 12px; }
.link-preview-card {
  max-width: 440px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-panel-2);
}
.link-preview-image {
  width: 100%;
  aspect-ratio: 1.91 / 1;
  object-fit: cover;
  background: var(--bg);
  display: block;
}
.link-preview-body { padding: 10px 12px; }
.link-preview-domain { font-size: 12.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.4px; }
.link-preview-title { font-size: 15.5px; font-weight: 700; margin-top: 3px; line-height: 1.35; }
.link-preview-desc { font-size: 14px; color: var(--text-dim); margin-top: 3px; line-height: 1.5; }
.link-preview-missing { font-size: 13.5px; color: var(--text-faint); font-style: italic; }

/* ---------- Social media preview simulator ---------- */
.social-tabs { display: flex; gap: 6px; margin-bottom: 14px; flex-wrap: wrap; }
.social-tab {
  border: 1px solid var(--border);
  background: var(--bg-panel-2);
  color: var(--text-dim);
  font-size: 13.5px;
  font-weight: 600;
  padding: 7px 12px;
  border-radius: 999px;
  cursor: pointer;
}
.social-tab.active { background: var(--brand); border-color: var(--brand); color: var(--brand-text); }

.social-card {
  max-width: 420px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
}
.social-card-image {
  width: 100%;
  aspect-ratio: 1.91 / 1;
  object-fit: cover;
  background: var(--bg);
  display: block;
}
.social-card-body { padding: 10px 12px; }
.social-card-domain { font-size: 12.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.3px; }
.social-card-title { font-size: 16px; font-weight: 700; margin-top: 4px; line-height: 1.35; }
.social-card-desc { font-size: 14px; color: var(--text-dim); margin-top: 4px; line-height: 1.5; }

/* WhatsApp: rounded chat-bubble chrome around the card */
.social-card--whatsapp {
  max-width: 340px;
  background: var(--bg-hover);
  border-radius: 4px 14px 14px 14px;
  padding: 8px;
  border: none;
}
.social-card--whatsapp .social-card-image { border-radius: 8px 8px 0 0; aspect-ratio: 1.6 / 1; }
.social-card--whatsapp .social-card-body { background: var(--bg-panel); border-radius: 0 0 8px 8px; padding: 8px 10px; }
.social-card--whatsapp .social-card-title { font-size: 15px; }
.social-card--whatsapp .social-msg { font-size: 14.5px; color: var(--text); padding: 2px 6px 8px; }

/* Facebook: square-ish card, domain above title */
.social-card--facebook { border-radius: 8px; }

/* Twitter / X: fully rounded corners */
.social-card--twitter { border-radius: 16px; }
.social-card--twitter .social-card-image { aspect-ratio: 2 / 1; }

/* Threads: minimal, tighter card closer to a chat attachment */
.social-card--threads { max-width: 380px; border-radius: 18px; }
.social-card--threads .social-card-image { aspect-ratio: 1 / 1; max-width: 120px; float: left; margin-right: 10px; border-radius: 10px; }
.social-card--threads .social-card-body { padding: 10px 12px; overflow: auto; }

/* Reddit: horizontal row, small thumbnail on the left */
.social-card--reddit {
  display: flex;
  align-items: stretch;
  max-width: 460px;
  border-radius: 8px;
}
.social-card--reddit .social-card-image {
  width: 96px;
  height: 96px;
  flex-shrink: 0;
  aspect-ratio: auto;
  border-radius: 8px 0 0 8px;
}
.social-card--reddit .social-card-body { padding: 10px 12px; display: flex; flex-direction: column; justify-content: center; }
.social-card--reddit .social-card-title { font-size: 15px; }

/* ---------- Heading outline (proper heading structure) ---------- */
.heading-outline { margin-top: 8px; }
.heading-outline-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 4px 0;
  font-size: 14px;
  color: var(--text-dim);
}
.heading-outline-tag {
  flex-shrink: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  font-weight: 700;
  color: var(--info);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
  min-width: 26px;
  text-align: center;
}
.heading-outline-text { color: var(--text); overflow-wrap: anywhere; }

.print-header { display: none; }

/* ---------- Print / PDF export ---------- */
@media print {
  .sidebar, .no-print, #auditForm, .panel > form { display: none !important; }
  .app-shell { display: block; }
  .main { padding: 0; }
  body, .app-shell, .main { background: #ffffff; }
  .panel {
    background: #ffffff;
    border: none;
    padding: 0;
    box-shadow: none;
  }
  .print-header {
    display: block;
    margin-bottom: 16px;
    padding-bottom: 10px;
    border-bottom: 2px solid #111;
  }
  .print-brand { font-size: 17.5px; font-weight: 700; color: #000; }
  .print-meta { font-size: 12.5px; color: #444; margin-top: 2px; }
  * { color: #111 !important; }
  .check-dot.pass { background: #1a9e6c !important; }
  .check-dot.warn { background: #b9790a !important; }
  .check-dot.fail { background: #c23a4c !important; }
  .check-dot.info { background: #3a5bd9 !important; }
  .check-item, .check-group { break-inside: avoid; }
  .score-circle { border-color: #111 !important; }
}

.spinner {
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: white;
  border-radius: 50%;
  display: inline-block;
  animation: spin 0.7s linear infinite;
  vertical-align: -3px;
  margin-right: 6px;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (max-width: 760px) {
  .app-shell { flex-direction: column; }
  .sidebar { width: 100%; flex-direction: column; }
  .sidebar-footer { display: flex; }
  .main { padding: 20px; }
}


/* ============================================================
   v2 components — Cloudflare dashboard conventions
   ------------------------------------------------------------
   Cloudflare's dashboard is data-dense but calm. The patterns
   applied consistently below:
     - Severity/status reads as a soft tinted pill (colour-mix
       against the surface), never a loud solid block.
     - Tables use small uppercase letter-spaced headers, hairline
       row separators, right-aligned numerics, and a hover tint.
     - Cards are flat: 1px border, small radius, no drop shadow.
     - Colour is reserved for state and the single primary action;
       everything else is greyscale so the data stands out.
     - Generous vertical rhythm, restrained type scale.
   ============================================================ */

/* ---------- Buttons: small + danger variants ---------- */
.btn-sm {
  padding: 5px 11px;
  font-size: 13.5px;
  border-radius: var(--radius-sm);
}
.btn.danger,
.btn-secondary.danger {
  color: var(--fail);
  border-color: color-mix(in srgb, var(--fail) 35%, var(--border));
}
.btn.danger:hover,
.btn-secondary.danger:hover {
  background: color-mix(in srgb, var(--fail) 12%, transparent);
}

/* ---------- Loading / empty rows ---------- */
.loading-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14.5px;
  color: var(--text-dim);
  padding: 6px 0;
}

/* ---------- Severity pills ----------
   Tinted, not solid — Cloudflare uses these to mark state without
   the badge itself competing with the content for attention. */
.sev-badge {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.045em;
  padding: 2px 7px;
  border-radius: 4px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.sev-critical,
.sev-high {
  color: var(--fail);
  background: color-mix(in srgb, var(--fail) 13%, transparent);
  border-color: color-mix(in srgb, var(--fail) 28%, transparent);
}
.sev-medium {
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 14%, transparent);
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
}
.sev-low {
  color: var(--text-dim);
  background: var(--bg-panel-2);
  border-color: var(--border);
}

/* ---------- Score pill (compact score in tables/cards) ---------- */
.score-pill {
  display: inline-block;
  min-width: 34px;
  text-align: center;
  font-size: 13.5px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 5px;
  border: 1px solid transparent;
}
.score-pill.pass {
  color: var(--pass);
  background: color-mix(in srgb, var(--pass) 13%, transparent);
  border-color: color-mix(in srgb, var(--pass) 28%, transparent);
}
.score-pill.warn {
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 14%, transparent);
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
}
.score-pill.fail {
  color: var(--fail);
  background: color-mix(in srgb, var(--fail) 13%, transparent);
  border-color: color-mix(in srgb, var(--fail) 28%, transparent);
}

/* ---------- Data tables ---------- */
.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-elevated);
}
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14.5px;
}
.data-table thead th {
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-panel-2);
  white-space: nowrap;
  position: sticky;
  top: 0;
}
.data-table td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  vertical-align: middle;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover td { background: var(--bg-hover); }
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.data-table .truncate {
  max-width: 340px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.data-table .you-col {
  background: color-mix(in srgb, var(--brand) 7%, transparent);
}
.data-table td.winner {
  color: var(--pass);
  font-weight: 600;
}

/* ---------- Findings (site audit) ---------- */
.finding {
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}
.finding:last-of-type { border-bottom: none; }
.finding-head {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
}
.finding-label { font-size: 15px; font-weight: 600; color: var(--text); }
.finding-reach { font-size: 13px; color: var(--text-faint); margin-left: auto; white-space: nowrap; }
.finding-message { font-size: 14px; color: var(--text-dim); margin: 5px 0 0 21px; line-height: 1.5; }
.finding .check-recommendation { margin-left: 21px; }
.finding-sample { margin: 8px 0 0 21px; }
.finding-sample summary {
  font-size: 13.5px;
  color: var(--brand);
  cursor: pointer;
  user-select: none;
}
.finding-sample summary:hover { text-decoration: underline; }
.finding-sample ul {
  margin: 8px 0 0;
  padding-left: 16px;
  font-size: 13.5px;
  color: var(--text-dim);
  line-height: 1.7;
  overflow-wrap: anywhere;
}

/* ---------- Project cards ---------- */
.project-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.project-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px;
  background: var(--bg-elevated);
  transition: border-color 0.12s ease;
}
.project-card:hover { border-color: color-mix(in srgb, var(--brand) 40%, var(--border)); }
.project-card-head { display: flex; align-items: flex-start; gap: 10px; }
.project-card-head > div:first-child { flex: 1; min-width: 0; }

/* Compact connection status — a small dot and a label, not a big circle.
   Matches how Cloudflare marks the state of an integration. */
.status-row { display: flex; align-items: center; gap: 12px; }
.status-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 20%, transparent);
}
.status-dot.on { background: var(--pass); color: var(--pass); }
.status-dot.off { background: var(--text-faint); color: var(--text-faint); }
.project-card-name { font-size: 15.5px; font-weight: 600; color: var(--text); }
.project-card-url {
  font-size: 13px;
  color: var(--text-faint);
  margin-top: 2px;
  overflow-wrap: anywhere;
}
.project-card-meta { font-size: 13px; color: var(--text-dim); margin-top: 10px; }
.project-card-actions { display: flex; gap: 6px; margin-top: 12px; flex-wrap: wrap; }

/* ---------- Diff (what changed between audits) ---------- */
.diff-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
  margin-top: 18px;
}
.diff-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 14px;
  color: var(--text);
  padding: 4px 0;
  line-height: 1.5;
}
.diff-row .check-dot { margin-top: 5px; flex-shrink: 0; }
.diff-meta { color: var(--text-faint); font-size: 13px; }

/* ---------- Sparkline ---------- */
.sparkline {
  width: 100%;
  height: 90px;
  display: block;
  margin-top: 10px;
  overflow: visible;
}

/* ---------- Rank movement ---------- */
.rank-up { color: var(--pass); font-weight: 600; }
.rank-down { color: var(--fail); font-weight: 600; }

/* ---------- Plain lists ---------- */
.plain-list {
  margin: 10px 0 0;
  padding-left: 18px;
  font-size: 14px;
  color: var(--text-dim);
  line-height: 1.8;
  overflow-wrap: anywhere;
}
.plain-list strong { color: var(--text); }

/* ---------- Setup steps (numbered instructions) ---------- */
.setup-steps {
  margin: 10px 0 0;
  padding-left: 20px;
  font-size: 14.5px;
  color: var(--text-dim);
  line-height: 1.9;
}
.setup-steps strong { color: var(--text); }
.inline-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13.5px;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
  color: var(--text);
  overflow-wrap: anywhere;
}

/* ---------- Code output ---------- */
.code-output {
  width: 100%;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13.5px;
  line-height: 1.6;
  background: var(--bg-panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px;
  resize: vertical;
  margin-top: 10px;
}
.code-output:focus {
  outline: none;
  border-color: var(--brand);
}

/* ---------- Schema field grid ---------- */
.schema-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.schema-grid .span-2 { grid-column: 1 / -1; }

/* ---------- Email preview ---------- */
.email-preview {
  width: 100%;
  height: 520px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #fff;
  margin-top: 10px;
}

/* ---------- Responsive ---------- */
@media (max-width: 720px) {
  .project-grid { grid-template-columns: 1fr; }
  .data-table .truncate { max-width: 180px; }
  .finding-reach { margin-left: 0; width: 100%; }
}


/* ============================================================
   v2.1 — project workspace, charts, and full-detail lists
   ============================================================ */

/* ---------- Workspace header ---------- */
.workspace-head {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.btn-back {
  background: none;
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: var(--radius-sm);
  padding: 6px 12px;
  font-size: 14px;
  cursor: pointer;
  font-family: inherit;
  flex-shrink: 0;
}
.btn-back:hover { color: var(--text); border-color: var(--brand); }
.workspace-title { min-width: 0; flex: 1; }
.workspace-title h2 { margin: 0; font-size: 20.5px; font-weight: 700; letter-spacing: -0.2px; }
.workspace-url {
  font-size: 14px;
  color: var(--text-dim);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.workspace-url:hover { color: var(--brand); text-decoration: underline; }
.workspace-score { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.workspace-score-label { font-size: 12.5px; color: var(--text-faint); line-height: 1.4; }
.workspace-score-label span { color: var(--text-dim); }

.score-pill.lg { min-width: 52px; font-size: 19.5px; padding: 8px 12px; }

/* ---------- Workspace tabs (underline style, like Cloudflare) ---------- */
.workspace-tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
}
.workspace-tab {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--text-dim);
  padding: 11px 14px;
  font-size: 14.5px;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
  margin-bottom: -1px;
}
.workspace-tab:hover { color: var(--text); }
.workspace-tab.active { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }

/* ---------- Stat cards ---------- */
.stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-top: 16px;
}
.stat-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}
.stat-card-label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
}
.stat-card-value {
  font-size: 29px;
  font-weight: 700;
  margin-top: 6px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
/* An em-dash at 27px reads as a horizontal rule, not as "no data". Shrink and
   mute it so an empty card looks empty rather than broken. */
.stat-card-value.empty {
  font-size: 22px;
  color: var(--text-faint);
  font-weight: 400;
}
.stat-card-value.pass { color: var(--pass); }
.stat-card-value.warn { color: var(--warn); }
.stat-card-value.fail { color: var(--fail); }
.stat-card-meta { font-size: 13px; color: var(--text-dim); margin-top: 6px; }

/* ---------- "Run something" cards ---------- */
.run-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.run-card {
  text-align: left;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px;
  cursor: pointer;
  font-family: inherit;
  color: var(--text);
  transition: border-color 0.12s ease, background 0.12s ease;
}
.run-card:hover:not(:disabled) { border-color: var(--brand); background: var(--bg-hover); }
.run-card:disabled { opacity: 0.6; cursor: progress; }
.run-card.running { border-color: var(--brand); }
.run-card-title { font-size: 15px; font-weight: 600; }
.run-card-desc { font-size: 13.5px; color: var(--text-dim); margin-top: 4px; line-height: 1.5; }

.inline-result {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  font-size: 14px;
  color: var(--text-dim);
}
.inline-result strong { color: var(--text); }
.inline-result select { padding: 5px 8px; font-size: 14px; }

.diff-head {
  font-size: 12.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 8px;
}
.diff-head.pass { color: var(--pass); }
.diff-head.fail { color: var(--fail); }

/* ---------- Charts ---------- */
.line-chart {
  width: 100%;
  height: 160px;
  display: block;
  margin-top: 10px;
  overflow: visible;
}
.chart-grid { stroke: var(--border); stroke-width: 1; }
.chart-axis { fill: var(--text-faint); font-size: 11.5px; font-family: inherit; }
.chart-area { fill: var(--brand); opacity: 0.1; }
.chart-line { fill: none; stroke: var(--brand); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart-dot { fill: var(--brand); }
.chart-empty {
  font-size: 13.5px;
  color: var(--text-faint);
  padding: 22px 0;
  text-align: center;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  margin-top: 10px;
}

/* ---------- Per-keyword rank cards ---------- */
.rank-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.period-tabs { display: flex; gap: 4px; flex-wrap: wrap; }

.keyword-charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 14px;
  margin-top: 16px;
}
.keyword-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}
.keyword-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.keyword-card-title { font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.keyword-card-stats { display: flex; align-items: center; gap: 10px; flex-shrink: 0; font-size: 14px; }
.keyword-pos { font-size: 17.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.keyword-pos.unranked { font-size: 13.5px; font-weight: 500; color: var(--text-faint); }
.keyword-card-foot {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  color: var(--text-dim);
}
.keyword-card-foot strong { color: var(--text); font-variant-numeric: tabular-nums; }
.keyword-card-url { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

/* ---------- Links to real pages ---------- */
.url-link {
  color: var(--info);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.url-link:hover { text-decoration: underline; }
.url-raw {
  display: block;
  font-size: 12.5px;
  color: var(--text-faint);
  overflow-wrap: anywhere;
  margin-top: 1px;
}

/* ---------- Full affected-page lists ----------
   These can run to hundreds of rows, so the container scrolls rather than
   pushing the rest of the report off-screen. Every row is still there. */
.affected-list {
  margin-top: 10px;
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-elevated);
}
.affected-row {
  padding: 7px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
  line-height: 1.5;
}
.affected-row:last-child { border-bottom: none; }
.affected-row .diff-meta { margin-left: 8px; }
.broken-row { display: flex; flex-direction: column; gap: 2px; }
.broken-row .sev-badge { align-self: flex-start; }

/* ---------- Misc ---------- */
.btn-inline {
  background: none;
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 4px;
  padding: 3px 9px;
  font-size: 13px;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
}
.btn-inline:hover:not(:disabled) { color: var(--brand); border-color: var(--brand); }
.btn-inline:disabled { opacity: 0.55; cursor: default; }

.signal-bar { color: var(--brand); letter-spacing: -1px; font-size: 11.5px; }

@media (max-width: 720px) {
  .keyword-charts { grid-template-columns: 1fr; }
  .stat-cards { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
  .workspace-score { margin-left: 0; }
}

/* ============================================================
   SEMRUSH-STYLE APPLICATION SHELL
   ------------------------------------------------------------
   A two-level navigation: a narrow icon rail for top-level
   product areas, and a section sidebar listing the tools inside
   the selected area. This is the shape Semrush uses and the
   reason it scales — the sidebar never grows past a screenful
   no matter how many tools ship, because only one area's tools
   are ever listed at a time.
   ============================================================ */

:root {
  --rail-w: 76px;
  --sidebar-w: 232px;
  --topbar-h: 56px;

  /* Globe (landing page). Declared here so both themes get a value
     and globe.js never has to guess a fallback. */
  /* Brand blue is too dark to read against the near-black dark-mode
     background; the globe uses a lifted tint of it instead. */
  --globe-dot: #4d74ff;
  --globe-grid: rgba(255, 255, 255, 0.13);
  --globe-marker: #a9bcff;
}

:root[data-theme="light"] {
  --globe-dot: #1c46f2;
  --globe-grid: rgba(33, 36, 39, 0.10);
  --globe-marker: #1c46f2;
}

/* ---------- Icon rail ---------- */
.rail {
  width: var(--rail-w);
  flex-shrink: 0;
  background: var(--bg-elevated);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px 0 14px;
  gap: 2px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.rail-brand {
  width: 36px;
  height: 36px;
  border-radius: 9px;
  background: var(--brand);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
  flex-shrink: 0;
}
/* The mark is supplied white-on-transparent, so it sits on the brand tile
   without a second asset per theme. */
.rail-brand svg { width: 20px; height: 20px; }
.rail-brand img { width: 22px; height: 22px; display: block; }

/* The wordmark in the topbar. Two files rather than one recoloured by CSS:
   the mark is multi-tone, so a filter that made the type readable would also
   flatten the mark. Only one is ever displayed. */
.topbar-brand { display: flex; align-items: center; flex-shrink: 0; margin-right: 4px; }
.topbar-wordmark { height: 22px; width: auto; display: block; }
.topbar-wordmark.light { display: none; }
:root[data-theme="light"] .topbar-wordmark.light { display: block; }
:root[data-theme="light"] .topbar-wordmark.dark { display: none; }

.rail-item {
  width: 62px;
  padding: 8px 2px 6px;
  border: 0;
  background: transparent;
  color: var(--text-dim);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  line-height: 1.25;
  text-align: center;
  transition: background-color 0.12s ease, color 0.12s ease;
  flex-shrink: 0;
}
.rail-item svg { width: 20px; height: 20px; }
.rail-item:hover { background: var(--bg-hover); color: var(--text); }
.rail-item.active { background: var(--bg-panel-2); color: var(--text); font-weight: 600; }
.rail-item.active svg { color: var(--brand); }

.rail-spacer { flex: 1; min-height: 8px; }

/* ---------- Section sidebar ---------- */
.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--bg-panel-2);
  border-right: 1px solid var(--border);
  padding: 16px 10px 20px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.sidebar-title {
  font-size: 16.5px;
  font-weight: 700;
  color: var(--text);
  padding: 2px 10px 10px;
  letter-spacing: -0.01em;
}

/* Only the nav groups belonging to the selected rail area are shown. */
.nav-group[hidden] { display: none; }

.nav-group {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-bottom: 10px;
}

.nav-group-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-faint);
  padding: 10px 10px 5px;
  letter-spacing: 0.01em;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-dim);
  font: inherit;
  font-size: 15px;
  text-align: left;
  cursor: pointer;
  transition: background-color 0.12s ease, color 0.12s ease;
}
.nav-item:hover:not(:disabled) { background: var(--bg-hover); color: var(--text); }
.nav-item.active { background: var(--bg-hover); color: var(--text); font-weight: 600; }
.nav-item:disabled { opacity: 0.5; cursor: not-allowed; }
.nav-item-icon { display: flex; flex-shrink: 0; }
.nav-item-icon svg { width: 15px; height: 15px; }
.nav-item-label { flex: 1; min-width: 0; }

.sidebar-footer {
  margin-top: auto;
  padding: 12px 10px 0;
  border-top: 1px solid var(--border);
  font-size: 13px;
  color: var(--text-faint);
  line-height: 1.5;
}

/* ---------- Workspace column ---------- */
.workspace {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg);
}

.topbar {
  height: var(--topbar-h);
  flex-shrink: 0;
  border-bottom: 1px solid var(--border);
  background: var(--bg-elevated);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 20px;
  position: sticky;
  top: 0;
  z-index: 20;
}

.tool-search {
  position: relative;
  flex: 1;
  max-width: 420px;
}
.tool-search input {
  width: 100%;
  height: 34px;
  padding: 0 38px 0 12px;
  font-size: 15px;
}
.tool-search-btn {
  position: absolute;
  right: 3px;
  top: 3px;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.tool-search-btn:hover { background: var(--bg-hover); color: var(--text); }
.tool-search-btn svg { width: 15px; height: 15px; }

/* Type-ahead results for the tool search. */
.tool-search-results {
  position: absolute;
  top: 40px;
  left: 0;
  right: 0;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
  padding: 5px;
  max-height: 340px;
  overflow-y: auto;
  z-index: 30;
}
.tool-search-results:empty { display: none; }
.tool-search-result {
  display: block;
  width: 100%;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 15px;
  text-align: left;
  padding: 7px 10px;
  border-radius: 6px;
  cursor: pointer;
}
.tool-search-result:hover, .tool-search-result.cursor { background: var(--bg-hover); }
.tool-search-result .group { color: var(--text-faint); font-size: 13.5px; }

.topbar-spacer { flex: 1; }

.topbar-link {
  border: 0;
  background: transparent;
  color: var(--text-dim);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
  padding: 6px 8px;
  border-radius: 6px;
}
.topbar-link:hover { background: var(--bg-hover); color: var(--text); }

.avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  border: 0;
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}

.main {
  flex: 1;
  min-width: 0;
  padding: 20px 24px 60px;
}

/* ---------- Breadcrumb + dashboard header ---------- */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 14px;
  color: var(--text-faint);
  margin-bottom: 10px;
}
.breadcrumb a { color: var(--text-dim); text-decoration: none; }
.breadcrumb a:hover { color: var(--text); text-decoration: underline; }
.breadcrumb svg { width: 12px; height: 12px; }

.dash-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.dash-title {
  margin: 0;
  font-size: 23px;
  font-weight: 700;
  letter-spacing: -0.015em;
}
.dash-title .domain { color: var(--brand); }
.dash-head-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }

/* ---------- Widget cards ---------- */
/* The `min(…, 100%)` is load-bearing, not decoration.
   A bare `minmax(420px, 1fr)` sets a floor the track cannot go below, so on a
   viewport narrower than the floor the grid keeps its 420px track and pushes
   the whole page sideways — found on a 390px phone, where the Pages table sat
   30px off the right edge and the body scrolled horizontally. Wrapping the
   floor in `min()` lets the track shrink to the container on small screens and
   changes nothing at all above 420px, where `min(420px, 100%)` is just 420px. */
.widget-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 16px;
}
.widget-grid.cols-2 { grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); }

.widget {
  position: relative;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px 18px;
  min-width: 0;
}
.widget.span-2 { grid-column: span 2; }
@media (max-width: 1100px) { .widget.span-2 { grid-column: span 1; } }

.widget-head {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 14px;
}
.widget-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.01em;
}
.widget-meta { margin-left: auto; font-size: 13.5px; color: var(--text-faint); display: flex; gap: 10px; align-items: center; }

/* The little ⓘ that explains what a metric means. Semrush leans on these
   heavily and they are the difference between a number and an insight. */
.info-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1px solid var(--text-faint);
  color: var(--text-faint);
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: help;
  flex-shrink: 0;
  font-style: normal;
  line-height: 1;
}
.info-dot:hover { border-color: var(--text); color: var(--text); }

.widget-dismiss {
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text-faint);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.widget-dismiss:hover { background: var(--bg-hover); color: var(--text); }
.widget-dismiss svg { width: 13px; height: 13px; }

.widget-body { font-size: 15px; color: var(--text-dim); line-height: 1.55; }

/* An unconfigured tool: description plus a single call to action. */
.widget.setup { display: flex; flex-direction: column; }
.widget.setup .widget-body { flex: 1; margin-bottom: 16px; }

/* ---------- KPI band ---------- */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 2px;
}
.kpi {
  padding: 2px 18px 2px 0;
  border-right: 1px solid var(--border);
  min-width: 0;
}
.kpi:last-child { border-right: 0; }
@media (max-width: 760px) { .kpi { border-right: 0; } }

.kpi-label {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 14px;
  color: var(--text-dim);
  margin-bottom: 6px;
}
.kpi-value {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-size: 28px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.kpi-value.empty { font-size: 20.5px; color: var(--text-faint); font-weight: 600; }
.kpi-sub { font-size: 13.5px; color: var(--text-faint); margin-top: 5px; }

.delta { font-size: 14px; font-weight: 600; }
.delta.up { color: var(--pass); }
.delta.down { color: var(--fail); }
.delta.flat { color: var(--text-faint); }

.kpi-spark { margin-top: 6px; height: 30px; }
.kpi-spark svg { width: 100%; height: 30px; overflow: visible; }

/* A small circular gauge, the way Semrush renders Authority Score. */
.gauge { display: flex; align-items: center; gap: 9px; }
.gauge svg { width: 34px; height: 34px; flex-shrink: 0; }

/* ---------- Chart legend ---------- */
.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin-top: 12px;
}
.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--text-dim);
  cursor: pointer;
  user-select: none;
}
.legend-swatch {
  width: 13px;
  height: 13px;
  border-radius: 3px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid currentColor;
}
.legend-swatch svg { width: 9px; height: 9px; color: #fff; }
.legend-item.off { color: var(--text-faint); }
.legend-item.off .legend-swatch { background: transparent !important; }
.legend-item.off .legend-swatch svg { display: none; }

/* ---------- Horizontal distribution bars ---------- */
.dist-row {
  display: grid;
  grid-template-columns: 54px 1fr 56px 42px;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--text-dim);
  padding: 3px 0;
}
.dist-track {
  height: 13px;
  border-radius: 3px;
  background: var(--bg-panel-2);
  overflow: hidden;
}
.dist-fill { height: 100%; background: var(--brand); border-radius: 3px; }
.dist-row .num { text-align: right; color: var(--text); font-weight: 600; }
.dist-row .count { text-align: right; color: var(--info); }

/* ---------- Empty state ---------- */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 44px 20px;
  text-align: center;
}
.empty-state svg { width: 46px; height: 46px; color: var(--text-faint); opacity: 0.7; }
.empty-state-title { font-size: 16px; font-weight: 700; color: var(--text); }
.empty-state-desc { font-size: 14.5px; color: var(--text-faint); max-width: 280px; line-height: 1.5; }

/* ---------- Promo strip ---------- */
.promo {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px 28px;
  background:
    radial-gradient(720px 240px at 88% 50%, rgba(28, 70, 242, 0.14), transparent 70%),
    var(--bg-panel);
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}
.promo-copy { flex: 1; min-width: 260px; max-width: 460px; }
.promo h2 {
  margin: 0 0 10px;
  font-size: 25px;
  line-height: 1.25;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
}
.promo p { margin: 0 0 18px; font-size: 15px; color: var(--text-dim); line-height: 1.55; }

/* ---------- Responsive ---------- */
@media (max-width: 1040px) {
  .sidebar { position: static; height: auto; }
  .rail { position: static; height: auto; }
}
@media (max-width: 860px) {
  .app-shell { flex-direction: column; }
  .rail {
    flex-direction: row;
    width: 100%;
    height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
    padding: 8px 10px;
  }
  .rail-spacer { display: none; }
  .sidebar { width: 100%; height: auto; border-right: 0; border-bottom: 1px solid var(--border); }
  .main { padding: 16px 14px 48px; }
  .topbar { padding: 0 14px; }
}

/* ---- Corrections after the first visual pass ---- */

/* Four KPIs in one card wrapped badly at 150px minimum; 118px keeps them on
   one line at desktop width, and the row-gap makes the wrap readable when
   they do have to stack. */
.kpi-row {
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  row-gap: 18px;
  column-gap: 2px;
}

.empty-state { padding: 30px 20px; }

/* The theme toggle lives in the icon rail now, so its two icons need the
   same show/hide rule the old standalone button had. */
#themeToggle .icon-sun { display: none; }
:root[data-theme="light"] #themeToggle .icon-sun { display: block; }
:root[data-theme="light"] #themeToggle .icon-moon { display: none; }

/* Semrush marks the current tool with a soft fill, not a hard accent bar. */
.nav-item.active { box-shadow: none; border-left: 0; }

/* Semrush uses sentence case for its section headings; an older rule was
   upper-casing these and it read as shouting next to the tool names. */
.nav-group-label { text-transform: none; }

/* Values must line up even when one label wraps to two lines. */
.kpi-label { align-items: flex-start; min-height: 2.6em; }

/* Chrome's native search "×" sat underneath our own search button. */
.tool-search input::-webkit-search-cancel-button { display: none; }

/* A <span> is inline, so height:100% collapsed it and the coloured portion
   of every distribution bar was invisible. */
.dist-fill { display: block; }
.dist-track { display: block; }

/* ============================================================
   DASHBOARD: account KPIs and project cards
   ============================================================ */

.section-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: 4px;
}
.section-head[hidden] { display: none; }
.section-head h2 {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}
.section-head-meta { font-size: 14px; color: var(--text-faint); }

.plan-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-panel-2);
  font-size: 14px;
  color: var(--text-dim);
}
.plan-chip[hidden] { display: none; }
.plan-chip b { color: var(--text); font-weight: 600; }

/* A quota bar under a KPI: how much of the plan's allowance is spent. */
.quota-bar {
  height: 4px;
  border-radius: 2px;
  background: var(--bg-panel-2);
  overflow: hidden;
  margin-top: 8px;
}
.quota-bar > span { display: block; height: 100%; background: var(--brand); border-radius: 2px; }
.quota-bar.near > span { background: var(--warn); }
.quota-bar.full > span { background: var(--fail); }

/* ---------- Project cards ---------- */
.project-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 16px;
}
.project-grid:empty { display: none; }

.project-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-panel);
  padding: 16px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  cursor: pointer;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
  text-align: left;
  font: inherit;
  color: inherit;
  width: 100%;
}
.project-card:hover { border-color: var(--brand); box-shadow: 0 2px 10px rgba(28, 70, 242, 0.08); }
.project-card:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.project-card-head { display: flex; align-items: flex-start; gap: 12px; }
.project-card-name {
  font-size: 16.5px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.01em;
  line-height: 1.3;
}
.project-card-url {
  font-size: 14px;
  color: var(--text-faint);
  margin-top: 2px;
  word-break: break-all;
}
.project-card-score { margin-left: auto; flex-shrink: 0; text-align: center; }
.project-card-score .gauge { flex-direction: column; gap: 2px; }
.project-card-score .gauge svg { width: 44px; height: 44px; }
.project-card-score .kpi-value { font-size: 16.5px; }
.project-card-score-label { font-size: 12px; color: var(--text-faint); margin-top: 2px; }

/* The metric grid inside a card. */
.project-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px 10px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.project-stat { min-width: 0; }
.project-stat-label {
  font-size: 12.5px;
  color: var(--text-faint);
  margin-bottom: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.project-stat-value {
  font-size: 18.5px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.01em;
  display: flex;
  align-items: baseline;
  gap: 5px;
}
.project-stat-value .delta { font-size: 13px; }
/* "Never run" must never look like a real measurement of zero. */
.project-stat-value.unset { font-size: 14px; font-weight: 500; color: var(--text-faint); }

.project-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.btn-tiny {
  padding: 5px 10px;
  font-size: 13.5px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg-panel-2);
  color: var(--text-dim);
  cursor: pointer;
  font-family: inherit;
}
.btn-tiny:hover { border-color: var(--brand); color: var(--brand); }
.btn-tiny.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn-tiny.primary:hover { background: var(--brand-hover); color: #fff; }

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

/* "Not run yet" was rendering at full KPI size in a project card's score
   slot, where it read as a headline rather than an absence. */
.project-card-score .kpi-value.empty { font-size: 14px; font-weight: 500; }
.project-card { align-content: start; }

/* The divider between KPI cells sat flush against the next cell's label,
   which read as cramped. Pad both sides and let the grid gap be zero, so the
   rule always has air either side of it. */
.kpi-row { column-gap: 0; }
.kpi { padding: 2px 22px; }
.kpi:first-child { padding-left: 0; }
.kpi:last-child { padding-right: 0; }
@media (max-width: 760px) {
  .kpi { padding-left: 0; padding-right: 14px; }
}

/* ============================================================
   PROJECT WORKSPACE
   ============================================================ */

/* The project's own header in the sidebar, above its tabs. Clicking it goes
   back to the project list, which is the only way out of a project. */
.project-nav-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 10px;
  margin-bottom: 6px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--bg-panel);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.project-nav-head:hover { border-color: var(--brand); }
.project-nav-name {
  flex: 1;
  min-width: 0;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.project-nav-switch { font-size: 13px; color: var(--brand); flex-shrink: 0; }

/* While a project is open the generic SEO tool groups step aside. */
.nav-group[data-project-hidden="1"] { display: none; }

.project-head-url {
  display: inline-block;
  margin-top: 4px;
  font-size: 14.5px;
  color: var(--text-dim);
  text-decoration: none;
}
.project-head-url:hover { color: var(--brand); text-decoration: underline; }

/* ---------- Data tables ---------- */
.table-scroll { overflow-x: auto; }

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14.5px;
}
.data-table th {
  text-align: left;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-faint);
  padding: 0 10px 8px 0;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.data-table td {
  padding: 9px 10px 9px 0;
  border-bottom: 1px solid var(--border);
  color: var(--text-dim);
  vertical-align: top;
}
.data-table tr:last-child td { border-bottom: 0; }
.data-table td strong { color: var(--text); font-weight: 600; }
.data-table th.num, .data-table td.num { text-align: right; padding-right: 0; }
.data-table a { color: var(--info); text-decoration: none; word-break: break-all; }
.data-table a:hover { text-decoration: underline; }

.sev-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: 1px;
}

/* Period buttons live in the widget meta slot, which is a flex row already. */
.widget-meta .btn-tiny { padding: 3px 9px; font-size: 13px; }

/* Inside a project tile the card is only ~300px wide, so the dashboard's
   118px KPI minimum forced a second row for the third metric. */
.widget-grid:not(.cols-2) .kpi-row {
  grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
}
.widget-grid:not(.cols-2) .kpi { padding: 2px 12px; }
.widget-grid:not(.cols-2) .kpi:first-child { padding-left: 0; }
.widget-grid:not(.cols-2) .kpi-value { font-size: 24px; }

.platform-status {
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  border: 1px solid var(--border);
}
.platform-status.ready { color: var(--pass); border-color: var(--pass); }
.platform-status.soon { color: var(--brand); border-color: var(--brand); }

/* ============================================================
   EMOJI MENUS, PROJECT PICKER, INLINE TOOL FORMS
   ============================================================ */


/* ---------- Project picker ---------- */
.project-picker { position: relative; margin-bottom: 8px; }

.project-nav-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--bg-panel);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.project-nav-head:hover { border-color: var(--brand); }
.project-nav-caret { color: var(--text-faint); font-size: 12.5px; flex-shrink: 0; }

.project-menu {
  position: absolute;
  top: calc(100% + 5px);
  left: 0;
  right: 0;
  z-index: 40;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.16);
  padding: 5px;
  max-height: 340px;
  overflow-y: auto;
}
.project-menu[hidden] { display: none; }

.project-menu-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 9px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.project-menu-item:hover { background: var(--bg-hover); }
.project-menu-item.current { background: var(--bg-hover); }
.project-menu-text { min-width: 0; display: flex; flex-direction: column; }
.project-menu-name {
  font-size: 14.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.project-menu-url {
  font-size: 13px;
  color: var(--text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.project-menu-sep { height: 1px; background: var(--border); margin: 5px 0; }
.project-menu-empty { padding: 10px; font-size: 14px; color: var(--text-faint); }

/* ---------- Inline tool forms ---------- */
.tool-form .form-row { margin: 0; }
.tool-form .hint { margin: 10px 0 0; }

/* Expanding the affected pages under a finding, rather than a "…and 9 more". */
.finding-pages { margin-top: 7px; }
.finding-pages summary {
  cursor: pointer;
  font-size: 13.5px;
  color: var(--info);
  list-style: none;
}
.finding-pages summary::-webkit-details-marker { display: none; }
.finding-pages summary::before { content: '▸ '; }
.finding-pages[open] summary::before { content: '▾ '; }
.finding-pages a {
  display: block;
  font-size: 13.5px;
  padding: 3px 0 3px 14px;
  word-break: break-all;
}

.intent-chip {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--border);
  font-size: 13px;
  color: var(--text-dim);
  white-space: nowrap;
}

.raw-json {
  margin: 0;
  padding: 12px;
  background: var(--bg-panel-2);
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text-dim);
}

/* ---------- Rank refresh mode ---------- */
.refresh-modes { display: flex; flex-direction: column; gap: 10px; }

.refresh-mode {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 0.12s ease, background-color 0.12s ease;
}
.refresh-mode:hover { border-color: var(--brand); }
.refresh-mode.active { border-color: var(--brand); background: var(--bg-panel-2); }
.refresh-mode input { margin-top: 3px; flex-shrink: 0; accent-color: var(--brand); }
.refresh-mode > span { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.refresh-mode strong { font-size: 14.5px; color: var(--text); font-weight: 600; }


/* ---------- Project history ---------- */
.history-day { margin-bottom: 18px; }
.history-day:last-child { margin-bottom: 0; }

.history-date {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-faint);
  padding-bottom: 7px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
}

.history-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--border);
}
.history-item:last-child { border-bottom: 0; }

.history-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.history-title { font-size: 15px; font-weight: 600; color: var(--text); }
.history-detail {
  font-size: 14px;
  color: var(--text-dim);
  word-break: break-all;
}
.history-meta { font-size: 13px; color: var(--text-faint); }

.history-score {
  flex-shrink: 0;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--text);
  min-width: 26px;
  text-align: right;
}
.history-time {
  flex-shrink: 0;
  font-size: 13px;
  color: var(--text-faint);
  min-width: 40px;
  text-align: right;
}

/* Filter chips sit in the widget's meta slot and need to wrap on narrow screens. */
.widget-meta { flex-wrap: wrap; justify-content: flex-end; }

/* File and range inputs were falling back to the browser default, which is
   white in dark mode. */
input[type="file"] {
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-size: 14.5px;
  color: var(--text-dim);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
input[type="file"]::file-selector-button {
  margin-right: 10px;
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg-panel);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}
input[type="file"]::file-selector-button:hover { border-color: var(--brand); color: var(--brand); }

input[type="range"] {
  width: 100%;
  accent-color: var(--brand);
  background: transparent;
}

/* ============================================================
   ICONS
   ------------------------------------------------------------
   Thin-stroke line icons in place of emoji: one visual language
   across every platform, and they inherit `color`, so an active
   or hovered item tints its icon for free.
   ============================================================ */

.icon { display: block; flex-shrink: 0; }

.rail-icon,
.nav-item-icon,
.project-nav-icon,
.project-menu-icon,
.widget-icon,
.history-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--text-faint);
}

.rail-icon { color: var(--text-dim); }
.rail-item:hover .rail-icon { color: var(--text); }
.rail-item.active .rail-icon { color: var(--brand); }

.nav-item-icon { width: 16px; color: var(--text-faint); }
.nav-item:hover .nav-item-icon { color: var(--text-dim); }
.nav-item.active .nav-item-icon { color: var(--brand); }

.project-nav-icon { color: var(--text-dim); }
.project-menu-icon { color: var(--text-faint); }
.project-menu-item.current .project-menu-icon { color: var(--brand); }

.widget-icon { color: var(--text-dim); }
.history-icon { margin-top: 1px; color: var(--text-faint); }

.empty-icon {
  display: flex;
  justify-content: center;
  color: var(--text-faint);
  opacity: 0.55;
}

/* Filter chips pair an icon with a label. */
.btn-tiny { display: inline-flex; align-items: center; gap: 5px; }
.btn-tiny .icon { width: 13px; height: 13px; }

/* The score and time columns had no gap, so "81" and "today" ran together. */
.history-score { min-width: 34px; padding-right: 10px; }
.history-time { min-width: 46px; }
.history-open {
  flex-shrink: 0;
  width: 16px;
  display: flex;
  justify-content: flex-end;
  color: var(--text-faint);
  opacity: 0;
  transition: opacity 0.12s ease;
}
.history-item.openable { cursor: pointer; margin: 0 -8px; padding-left: 8px; padding-right: 8px; border-radius: 6px; }
.history-item.openable:hover { background: var(--bg-hover); }
.history-item.openable:hover .history-open { opacity: 1; }
.history-item.openable:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.history-item.loading { opacity: 0.55; }

/* A full tool report is rendered inside a widget, and brings its own panels. */
.report-host > div > .panel:first-child { margin-top: 0; }
.report-host .panel { border: 0; padding: 0; background: transparent; }
.report-host .panel + .panel { margin-top: 22px; padding-top: 22px; border-top: 1px solid var(--border); }
.widget.report-host { padding-top: 18px; }

/* The audit-history table jammed the score against the date. */
.data-table td.num + td { padding-left: 14px; }

/* ============================================================
   SITE AUDIT SCREEN
   ============================================================ */

.sa-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 20px;
  font-size: 14px;
  color: var(--text-dim);
  margin: -8px 0 16px;
}
.sa-meta-domain { color: var(--text); font-weight: 600; }
.sa-meta strong { color: var(--text); font-weight: 600; }

.sa-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
}
.sa-tab {
  border: 0;
  background: transparent;
  color: var(--text-dim);
  font: inherit;
  font-size: 15px;
  padding: 9px 14px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
}
.sa-tab:hover { color: var(--text); }
.sa-tab.active { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }

/* Two panels sharing one card, as on the reference. */
.sa-split { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
@media (max-width: 720px) { .sa-split { grid-template-columns: 1fr; } }
.sa-split-col { min-width: 0; }

.gauge-half { margin: 4px auto 0; }
.gauge-half-label { text-align: center; font-size: 13.5px; color: var(--text-faint); }
.sa-gauge-delta { text-align: center; font-size: 13.5px; margin-top: -6px; }

.sa-bullets { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.sa-bullet { display: flex; align-items: center; gap: 8px; font-size: 14.5px; color: var(--text-dim); }
.sa-bullet strong { margin-left: auto; color: var(--text); }
.sa-bullet-note { font-size: 13.5px; color: var(--text-faint); line-height: 1.5; }
.sa-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

.sa-bench-toggle {
  border: 0;
  background: transparent;
  color: var(--brand);
  font: inherit;
  font-size: 14.5px;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.sa-bench-list {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  background: var(--bg-panel-2);
}
.sa-bench-list[hidden] { display: none; }
.sa-bench-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 14px;
  color: var(--text-dim);
  padding: 4px 0;
}
.sa-bench-row strong { color: var(--text); }

.sa-pages-total { display: flex; align-items: baseline; gap: 10px; margin: 4px 0 12px; }
.sa-pages-count { font-size: 32px; font-weight: 700; letter-spacing: -0.02em; }

.sa-stack { display: flex; height: 12px; border-radius: 3px; overflow: hidden; gap: 2px; }
.sa-stack-seg { display: block; height: 100%; }

.sa-legend { margin-top: 14px; display: flex; flex-direction: column; gap: 7px; }
.sa-legend-row { display: flex; align-items: center; gap: 8px; font-size: 14.5px; color: var(--text-dim); }
/* The colour that ties a legend row to its slice. Without it the legend is a
   list of numbers next to a chart nobody can map onto it. */
.sa-legend-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  display: inline-block;
}
.sa-legend-label { flex: 1; min-width: 0; }
.sa-legend-n { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.sa-legend-pct { color: var(--text-faint); font-variant-numeric: tabular-nums; min-width: 38px; text-align: right; }
/* A band with nothing in it still earns its row — "0 pages over 3s" is a
   result, and hiding it makes the legend look like the chart is incomplete. */
.sa-legend-row.zero { opacity: 0.55; }
.sa-legend-row.zero .sa-legend-n { color: var(--text-faint); font-weight: 500; }
.sa-count-link {
  margin-left: auto;
  border: 0;
  background: transparent;
  color: var(--info);
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
}
.sa-count-link:hover { text-decoration: underline; }

.beta-badge {
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--warn);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: lowercase;
}

.sa-note {
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--warn) 14%, transparent);
  font-size: 14px;
  color: var(--text-dim);
}
.sa-note.pass { background: color-mix(in srgb, var(--pass) 14%, transparent); }

.sa-ai-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 14px;
  font-size: 14px;
}
.sa-issue-link {
  border: 0;
  background: transparent;
  color: var(--info);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  padding: 0;
}
.sa-issue-link:hover { text-decoration: underline; }

/* Hover explainer, as on the reference. */
/* `.sa-hover` / `.sa-tooltip` lived here: a CSS-only hover box, absolutely
   positioned and anchored `left: 0` to its trigger with a fixed 330px width.

   Removed rather than left in place, because the rule encodes a bug. It can
   only work while its trigger sits on the LEFT of a container wide enough to
   hold it; a trigger on the right has nowhere to put the box, and both audits
   grew exactly that — the On Page score headers pushed it off the viewport,
   and the site audit's AI Search footer laid it over the agent list beside it.
   A hover box cannot fix that without measuring the viewport and flipping,
   which is what the JS engine behind `data-tip` already does and which these
   explainers are far too long for anyway.

   All four call sites now open a panel on click instead — the same interaction
   as "How to fix", so there is one way to open an explanation rather than two.
   See EXPLAINERS in public/project.js. Leaving the dead rule here would have
   invited the next person to reuse it. */

.sa-bots { display: flex; flex-direction: column; gap: 2px; }
.sa-bot-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--border);
  font-size: 14.5px;
}
.sa-bot-row:last-child { border-bottom: 0; }
.sa-bot-name { color: var(--text); display: flex; align-items: center; gap: 7px; }
.sa-bot-purpose {
  font-size: 12px;
  color: var(--text-faint);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 6px;
}
.sa-bot-ok { color: var(--pass); font-size: 14px; font-weight: 600; }
.sa-bot-blocked { color: var(--fail); font-size: 14px; font-weight: 600; }
/* Allowed at the root, blocked from some pages — neither pass nor fail. */
.sa-bot-partial { color: var(--warn); font-size: 14px; font-weight: 600; }
.sa-more {
  margin-top: 8px;
  border: 0;
  background: transparent;
  color: var(--info);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  padding: 0;
}

.sa-big-number { font-size: 32px; font-weight: 700; letter-spacing: -0.02em; margin: 2px 0 6px; }
.sa-big-number.fail { color: var(--fail); }
.sa-big-number.warn { color: var(--warn); }

/* ---- Issue rows ---- */
.sa-issue-list { display: flex; flex-direction: column; }
.sa-issue {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  /* Two different edges, deliberately.
     
     The MARGIN pulls the row out to the card's padding edge, so the hover
     highlight and the dividers run the full width the way a table row does.
     The PADDING then sets the text in further than the card's own padding,
     so the content is not pressed against the border it now touches.
     `--issue-inset` is shared with the band header below, or the sticky
     "Errors" title and the rows beneath it would sit on different verticals. */
  padding: var(--s4) var(--issue-inset);
  margin: 0 calc(var(--card-pad) * -1);
  border-bottom: 1px solid var(--border);
  font-size: 14.5px;
  flex-wrap: wrap;
  transition: background-color 0.14s ease;
}
.sa-issue:last-child { border-bottom: 0; }
.sa-issue.full { align-items: flex-start; }
.sa-issue-sev { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; margin-top: 5px; }
.sa-issue-sev.critical { background: var(--fail); }
.sa-issue-sev.high { background: #e8743b; }
.sa-issue-sev.medium { background: var(--warn); }
.sa-issue-sev.low { background: var(--info); }
.sa-issue-label {
  flex: 1;
  min-width: 180px;
  color: var(--text);
  display: flex;
  flex-direction: column;
  /* A column flex box stretches its children to full width by default, so the
     inline "AI Search" pill was being pulled into a full-width blue bar across
     the row. Children size to their content now. */
  align-items: flex-start;
  gap: 3px;
}
/* Title and its badges on one line; the explanation sits under both. */
.sa-issue-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  line-height: 1.35;
}
/* The gap above owns the spacing now — the badge's own margin doubled it. */
.sa-issue-title .ai-badge { margin-left: 0; }
.sa-issue-count { color: var(--info); font-weight: 600; white-space: nowrap; }

.ai-badge {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--brand) 16%, transparent);
  color: var(--brand);
  font-size: 12px;
  font-weight: 700;
  margin-left: 6px;
}

.sa-howto {
  border: 0;
  background: transparent;
  color: var(--text-dim);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}
.sa-howto:hover { color: var(--brand); }

.sa-fix-pop {
  flex-basis: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.sa-fix-pop[hidden] { display: none; }
@media (max-width: 700px) { .sa-fix-pop { grid-template-columns: 1fr; } }
.sa-fix-col { padding: 14px 16px; font-size: 14px; line-height: 1.6; color: var(--text-dim); }
.sa-fix-col strong { display: block; color: var(--text); margin-bottom: 6px; }
.sa-fix-col p { margin: 0; }
.sa-fix-col.fix { background: color-mix(in srgb, var(--pass) 8%, transparent); }

.sa-issue-pages { flex-basis: 100%; margin-top: 6px; }

/* The affected-URL count, now a way in rather than a list dumped in place. */
.sa-issue-open {
  border: 1px solid var(--border);
  background: none;
  border-radius: 999px;
  padding: 4px 12px;
  font-size: var(--fs-sm);
  font-weight: 550;
  color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
}
.sa-issue-open:hover { border-color: var(--brand); color: var(--brand); }
/* Keeps the column from collapsing on rows that have no URLs to show, so the
   "How to fix" buttons above and below it stay in line. */
.sa-issue-open-placeholder { display: inline-block; min-width: 132px; }

/* The "opens elsewhere" mark. Deliberately quiet until hovered: it sits on
   every row of a long table, and at full strength it reads as a column of
   decoration. */
.sa-ext-link {
  display: inline-flex;
  align-items: center;
  margin-left: 6px;
  color: var(--text-faint);
  vertical-align: -2px;
}
.sa-ext-link:hover { color: var(--brand); }
/* NOT display:flex.
   A <td> given `display:flex` stops being a table-cell, so it no longer shares
   the row's baseline or its border box — which is why the row rule under this
   column broke away from the one under ILR and the two never met. The cell
   stays a cell; the contents are laid out inline inside it. */
.sa-url-cell { min-width: 0; }
.sa-url-cell .sa-url-link { display: inline; overflow-wrap: anywhere; }
.sa-url-cell .sa-ext-link { display: inline-flex; vertical-align: -2px; }
/* Inline-flex so the mark stays on the URL's last line instead of wrapping
   onto one of its own under a long address. */
.sa-pp-url a { display: inline-flex; align-items: center; gap: 6px; }
.sa-ext-icon { color: var(--text-faint); flex: none; }
.sa-pp-url a:hover .sa-ext-icon { color: var(--brand); }

/* ---- One issue, every instance of it ---- */
.sa-idt-back {
  border: 0;
  background: none;
  padding: 4px 0;
  margin-bottom: var(--s3);
  font: inherit;
  font-weight: 600;
  font-size: var(--fs-sm);
  color: var(--text-dim);
  cursor: pointer;
}
.sa-idt-back:hover { color: var(--brand); }
.sa-idt-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s4); }
.sa-idt-h {
  margin: 0;
  font-size: var(--fs-xl);
  font-weight: 700;
  letter-spacing: -0.01em;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.sa-idt-sub { margin: 6px 0 var(--s4); font-size: var(--fs-sm); color: var(--text-dim); }
.sa-idt-controls { display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s3); }
.sa-idt-controls input { flex: 1; max-width: 340px; }
.sa-idt-count { font-size: var(--fs-xs); color: var(--text-faint); }

.sa-idt-table { table-layout: auto; }
.sa-idt-table th,
.sa-idt-table td { padding: 11px 14px; vertical-align: top; }
/* Inset from the card edge, matching the compare tables. Content flush
   against the border is the "mepet" look. */
.sa-idt-table th:first-child,
.sa-idt-table td:first-child { padding-left: 18px; }
.sa-idt-table th:last-child,
.sa-idt-table td:last-child { padding-right: 18px; }
.sa-idt-table thead th:first-child { border-top-left-radius: var(--radius-sm); }
.sa-idt-table thead th:last-child { border-top-right-radius: var(--radius-sm); }
.sa-idt-table thead th { background: var(--bg-panel-2); }
.sa-idt-page { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sa-idt-title { font-weight: 550; color: var(--text); }
.sa-idt-url { font-size: var(--fs-sm); display: flex; align-items: baseline; min-width: 0; }
.sa-idt-note { font-size: var(--fs-xs); color: var(--text-faint); font-style: italic; }
.sa-idt-target { font-size: var(--fs-sm); color: var(--text-dim); overflow-wrap: anywhere; }
.sa-idt-detail { font-size: var(--fs-sm); color: var(--text-dim); }
.sa-idt-pager {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s4);
  font-size: var(--fs-sm);
  color: var(--text-dim);
}
.sa-idt-pager button[disabled] { opacity: 0.4; cursor: default; }
.sa-idt-urls { display: flex; flex-direction: column; gap: 3px; font-size: var(--fs-xs); }
.sa-idt-urls span { display: flex; align-items: baseline; min-width: 0; }
.sa-idt-date { font-size: var(--fs-sm); color: var(--text-dim); white-space: nowrap; }

/* Include / exclude conditions on a named column. */
.sa-idt-filters {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--s3);
  margin-bottom: var(--s3);
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}
.sa-idt-filter { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.sa-idt-filter select { flex: 0 0 auto; }
.sa-idt-filter input { flex: 1; min-width: 160px; }
.sa-idt-filter-x {
  border: 0;
  background: none;
  color: var(--text-faint);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.sa-idt-filter-x:hover { color: var(--fail); }
.sa-idt-filter-actions { display: flex; gap: var(--s3); align-items: center; }

/* The Errors / Warnings / Notices band headers behave like the ones in
   Compare Crawls: the band you are inside stays named at the top of the
   screen, and is pushed out by the next band. Same offset as those, below the
   audit's own sticky header. */
.sa-issue-band { overflow: visible; }
.sa-issue-band .widget-head {
  position: sticky;
  top: calc(var(--topbar-h) + var(--sa-sticky-h, 92px));
  z-index: 8;
  background: var(--bg-panel);
  margin: calc(var(--card-pad) * -1) calc(var(--card-pad) * -1) 0;
  /* Same inset as the rows below it, so the title and the issue names line up. */
  padding: var(--s3) var(--issue-inset);
  border-bottom: 1px solid var(--border);
  /* The negative margin takes this out to the card's padding edge, which sits
     just inside the border — so a square background here paints over the
     inside of the card's rounded corners and the top corners read as missing.
     One pixel less than the card's radius, because this box starts inside the
     1px border. */
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
}

/* ---- The issue row, clickable as a whole ---- */
.sa-issue.openable { cursor: pointer; }
/* The same hover the data tables use (`.data-table tbody tr:hover td`), so a
   row of issues and a row of results feel like the same control. The colour
   was never the problem here — the geometry was: an inset, rounded highlight
   sitting beside a straight full-width divider. Square and edge to edge, and
   the standard token does the rest. */
.sa-issue.openable:hover { background: var(--bg-hover); }
@media (prefers-reduced-motion: reduce) { .sa-issue { transition: none; } }
.sa-issue-checked {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  white-space: nowrap;
  min-width: 120px;
  text-align: right;
}

/* The severity mark. Shape carries the meaning; colour reinforces it. */
.sa-sev {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 18px;
  height: 18px;
}
.sa-sev svg { width: 15px; height: 15px; }
.sa-sev.critical, .sa-sev.high { color: var(--fail); }
.sa-sev.medium { color: var(--warn); }
.sa-sev.low { color: var(--info); }
/* The bolt reads better filled; the outlines stay outlines. */
.sa-sev.critical svg, .sa-sev.high svg { fill: currentColor; stroke-width: 0; }

/* ---- Page summary: one issue expanded at a time ----

   Everything in a row hangs off one left rule: the caret sits at 0, the icon
   and label follow it, and the expanded table's first column starts at the
   same place as the label above it. The earlier version indented the table by
   an arbitrary 26px, so its header sat between the caret and the label and
   the whole block looked misaligned. */
.sa-acc { display: flex; flex-direction: column; }
.sa-acc-item { border-bottom: 1px solid var(--border); }
.sa-acc-item:last-child { border-bottom: 0; }
.sa-acc-item.open { background: color-mix(in srgb, var(--bg-hover) 45%, transparent); }
.sa-acc-head {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 14px var(--s3);
  cursor: pointer;
  font-size: 14.5px;
}
.sa-acc-head:hover { background: var(--bg-hover); }
/* One chevron, turned rather than swapped. A shape that rotates into place
   says "this opened"; two different glyphs just say "something changed". */
.sa-acc-caret {
  color: var(--text-faint);
  width: 14px;
  height: 14px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.16s ease, color 0.16s ease;
}
.sa-acc-caret svg { width: 14px; height: 14px; stroke-width: 2.2; }
.sa-acc-item.open .sa-acc-caret { color: var(--text); transform: rotate(90deg); }
.sa-acc-head:hover .sa-acc-caret { color: var(--text); }
@media (prefers-reduced-motion: reduce) { .sa-acc-caret { transition: none; } }
.sa-acc-label { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sa-acc-label strong { font-weight: 600; line-height: 1.35; }
.sa-acc-label .kpi-sub { line-height: 1.45; }
.sa-acc-n {
  color: var(--info);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  min-width: 34px;
  text-align: right;
}
/* Revealed on hover, the way the reference does it: present when you reach
   for it, absent from the resting state of a list you are only scanning. */
.sa-acc-all {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--text-dim);
  cursor: pointer;
  opacity: 0;
  white-space: nowrap;
  transition: opacity 0.12s ease;
}
.sa-acc-head:hover .sa-acc-all,
.sa-acc-all:focus-visible { opacity: 1; }
.sa-acc-all:hover { color: var(--brand); text-decoration: underline; }
.sa-acc-item.open .sa-acc-all { opacity: 1; }
/* The table's first column starts exactly under the issue label above it.
   --acc-indent is the sum of the head's leading furniture: its own padding,
   the caret, the severity icon and the two gaps between them. Written as one
   number so the two stay in step if any of those change. */
.sa-acc { --acc-indent: 68px; }
.sa-acc-table {
  margin: 0 var(--s3) var(--s4) calc(var(--acc-indent) - 18px);
  width: calc(100% - var(--acc-indent) - var(--s3) + 18px);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.sa-acc-table th,
.sa-acc-table td { padding: 9px 14px; font-size: var(--fs-sm); }
.sa-acc-table th:first-child,
.sa-acc-table td:first-child { padding-left: 18px; }
.sa-acc-table th:last-child,
.sa-acc-table td:last-child { padding-right: 18px; }
.sa-acc-table thead th { background: var(--bg-panel-2); }
.sa-acc-table tbody tr:last-child td { border-bottom: 0; }

/* The issue list uses the same rhythm, so the two read as one system.
   Padding is deliberately NOT set here: it belongs to the base rule, which
   pairs it with the negative margin that makes the row bleed to the card
   edge. Re-declaring only the padding here broke that pair. */
.sa-issue { gap: var(--s3); }
.sa-issue-label { gap: 5px; }
.sa-issue-label strong { font-weight: 600; line-height: 1.35; }

.sa-change { font-size: 13px; font-weight: 600; padding: 2px 8px; border-radius: 999px; }
.sa-change.worse { color: var(--fail); background: color-mix(in srgb, var(--fail) 14%, transparent); }
.sa-change.new { color: var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent); }
.sa-change.same { color: var(--text-faint); }
.sa-change.improved { color: var(--pass); background: color-mix(in srgb, var(--pass) 14%, transparent); }
.sa-change.fixed { color: var(--pass); background: color-mix(in srgb, var(--pass) 18%, transparent); }
.sa-change.neutral { color: var(--text-dim); background: color-mix(in srgb, var(--text-dim) 12%, transparent); }

/* ---- Issues tab filters ---- */
.sa-issue-filters { display: flex; flex-direction: column; gap: var(--s2); margin-bottom: var(--s4); }
.sa-issue-filter-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.sa-issue-filter-row .sa-search { flex: 0 0 240px; margin-right: var(--s2); }
.sa-issue-filter-row .sa-search input { width: 100%; }

.sa-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-panel);
  color: var(--text-dim);
  font-size: var(--fs-sm);
  font-weight: 550;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.sa-chip:hover { background: var(--bg-hover); color: var(--text); }
.sa-chip.active {
  border-color: var(--brand);
  color: var(--text);
  background: color-mix(in srgb, var(--brand) 10%, transparent);
}
.sa-chip.ai.active { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 16%, transparent); }
.sa-chip-n { color: var(--text-faint); font-weight: 500; font-variant-numeric: tabular-nums; }
.sa-chip.active .sa-chip-n { color: var(--brand); }
.sa-caret { font-size: 10px; color: var(--text-faint); }
/* The triggered dropdown already carries margin-left:auto, so anything after
   it sits on the right without needing its own. */
.sa-chip-x { color: var(--text-faint); font-weight: 600; }
.sa-chip.focus:hover .sa-chip-x { color: var(--text); }

/* The dropdown is positioned rather than inline so a long menu does not push
   the list below it around as it opens. */
.sa-triggered { position: relative; margin-left: auto; }
.sa-triggered-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 30;
  min-width: 210px;
  padding: var(--s1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-panel);
  box-shadow: 0 12px 28px rgb(0 0 0 / 22%);
}
.sa-triggered-menu button {
  display: flex;
  justify-content: space-between;
  gap: var(--s4);
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: 5px;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: var(--fs-sm);
  text-align: left;
  cursor: pointer;
}
.sa-triggered-menu button:hover { background: var(--bg-hover); }

/* A check that ran and found nothing, so the list can say so rather than
   leaving the reader unable to tell it apart from a check we never ran. */
.sa-issue.quiet { opacity: 0.62; }
/* Holds the column a "How to fix" button would occupy, so rows with nothing
   to fix still line up with the ones that do. */
.sa-howto-placeholder { display: inline-block; }
.sa-issue.quiet .sa-issue-count { color: var(--text-faint); }
.sa-issue-na {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 7px;
  white-space: nowrap;
}

/* ---- Crawlability report ---- */
.sa-donut-row { display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap; }
.sa-donut-side { flex: 1; min-width: 150px; }
.sa-donut-figure { font-size: var(--fs-2xl); font-weight: 700; line-height: 1.1; }
.sa-donut-figure.warn { color: var(--warn); }
.sa-donut-figure.pass { color: var(--pass); }

.sa-waste { display: flex; flex-direction: column; gap: 2px; }
.sa-waste-row {
  display: grid;
  grid-template-columns: 1fr auto 130px;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  padding: 5px 6px;
  border: 0;
  border-radius: 5px;
  background: none;
  color: var(--text-dim);
  font: inherit;
  font-size: var(--fs-sm);
  text-align: left;
}
.sa-waste-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sa-waste-n { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.sa-waste-bar { height: 8px; border-radius: 2px; background: var(--bg-panel-2); overflow: hidden; }
.sa-waste-bar > span { display: block; height: 100%; }

.sa-histogram {
  display: flex;
  align-items: flex-end;
  gap: var(--s2);
  height: 150px;
  padding-top: var(--s2);
}
.sa-histogram-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
}
.sa-histogram-bar { width: 100%; max-width: 40px; background: var(--brand); border-radius: 3px 3px 0 0; }
.sa-histogram-label { margin-top: 6px; font-size: var(--fs-xs); color: var(--text-faint); }

/* Overlapping circles, sized by set — a picture of the relationship rather
   than a precise Venn, which is why the counts sit beside it in words. */
.sa-venn { position: relative; height: 150px; display: flex; align-items: center; justify-content: center; }
.sa-venn-a,
.sa-venn-b { position: absolute; border-radius: 50%; }
.sa-venn-a { background: color-mix(in srgb, var(--brand) 35%, transparent); transform: translateX(-14px); }
.sa-venn-b { background: color-mix(in srgb, var(--pass) 55%, transparent); transform: translateX(18px); }

.sa-basis-note {
  margin-top: var(--s3);
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  color: var(--text-dim);
  font-size: var(--fs-xs);
}

/* Anything that answers "which ones?" when you click it. */
.clickable { cursor: pointer; }
button.sa-waste-row.clickable:hover,
button.sa-legend-row.clickable:hover { background: var(--bg-hover); color: var(--text); }
.sa-histogram-col.clickable:hover .sa-histogram-bar { filter: brightness(1.18); }
circle.clickable:hover { filter: brightness(1.15); }
/* Every legend row, clickable or not. A row with a count of zero is still a
   <button> for markup consistency, and without this it kept the browser's
   default button chrome — a raised grey box sitting among flat rows. */
button.sa-legend-row { width: 100%; border: 0; background: none; font: inherit; text-align: left; padding: 4px 6px; }

/* The audit's own actions, pushed to the end of the meta row so the button
   you press weekly is at the top of the page rather than below every chart. */
.sa-meta-actions { margin-left: auto; display: flex; align-items: center; gap: var(--s2); }
.sa-rerun { padding: 5px 14px; font-size: var(--fs-sm); white-space: nowrap; }
.btn-icon {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-panel);
  color: var(--text-dim);
  cursor: pointer;
}
.btn-icon:hover { background: var(--bg-hover); color: var(--text); }
.btn-icon.active { border-color: var(--brand); color: var(--brand); }
.sa-crawl-settings { margin: var(--s4) 0; }

.sa-meta-export {
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-size: var(--fs-sm);
  font-weight: 550;
  text-decoration: none;
  white-space: nowrap;
}
.sa-meta-export:hover { background: var(--bg-hover); color: var(--text); border-color: var(--brand); }

/* ---- Indexation ---- */
.sa-sitemap-target {
  margin-top: var(--s4);
  padding-top: var(--s3);
  border-top: 1px solid var(--border);
  font-size: var(--fs-sm);
  word-break: break-all;
}
.sa-sitemap-target .kpi-sub { display: block; margin-bottom: 2px; }
.sa-source-tag {
  display: inline-block;
  margin-left: var(--s2);
  padding: 1px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--text-dim) 14%, transparent);
  color: var(--text-dim);
  font-size: var(--fs-xs);
  white-space: nowrap;
}
/* A guessed location is a real caveat: submitting the wrong URL succeeds
   silently and indexes nothing. */
.sa-source-tag.warn { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); }
.sa-period-toggle { display: flex; gap: var(--s2); margin-bottom: var(--s4); }
.url-cell { max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Internal Linking report ---- */
.sa-linking-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--grid-gap); align-items: start; }
.sa-linking-col { display: flex; flex-direction: column; gap: var(--grid-gap); min-width: 0; }
@media (max-width: 1100px) { .sa-linking-grid { grid-template-columns: 1fr; } }

.sa-ilr-head {
  display: grid;
  grid-template-columns: 90px 18px 90px 1fr;
  gap: var(--s2);
  font-size: var(--fs-xs);
  color: var(--text-faint);
  margin-bottom: var(--s2);
}
.sa-ilr-head span:nth-child(2) { grid-column: 3; }
.sa-ilr-row {
  display: grid;
  grid-template-columns: 90px 18px 90px 1fr;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) 0;
}
.sa-ilr-bar { position: relative; height: 30px; border-radius: 4px; background: var(--bg-panel-2); overflow: hidden; }
.sa-ilr-bar > span { position: absolute; inset: 0 auto 0 0; }
.sa-ilr-bar.rank > span { background: color-mix(in srgb, var(--brand) 45%, transparent); }
.sa-ilr-bar.pages > span { background: color-mix(in srgb, var(--brand) 75%, transparent); }
.sa-ilr-bar > em {
  position: relative;
  display: block;
  padding: 6px 8px;
  font-style: normal;
  font-size: var(--fs-xs);
  font-weight: 650;
  color: var(--text);
}
.sa-ilr-arrow { color: var(--text-faint); text-align: center; }
.sa-ilr-label {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--brand);
  text-align: left;
  cursor: pointer;
}
.sa-ilr-label .kpi-sub { display: block; font-weight: 450; }
.sa-ilr-label:hover { text-decoration: underline; }

.sa-linkissue-band { margin-bottom: var(--s4); }
.sa-linkissue-bandhead {
  font-size: var(--fs-sm);
  font-weight: 650;
  padding-bottom: var(--s2);
  border-bottom: 2px solid var(--border);
  margin-bottom: var(--s1);
}
.sa-linkissue-band.errors .sa-linkissue-bandhead { border-bottom-color: var(--fail); }
.sa-linkissue-band.warnings .sa-linkissue-bandhead { border-bottom-color: var(--warn); }
.sa-linkissue-band.notices .sa-linkissue-bandhead { border-bottom-color: var(--brand); }
.sa-linkissue-row {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 7px 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-sm);
}
.sa-linkissue-row:last-child { border-bottom: 0; }
.sa-linkissue-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sa-linkissue-none { color: var(--pass); font-size: var(--fs-xs); }
.sa-linkissue-count {
  padding: 2px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.sa-linkissue-count:hover { background: var(--bg-hover); border-color: var(--brand); }

/* ---- HTTPS report: a checklist rather than a chart, because every row is a
   yes/no with a specific fix behind it. ---- */
.sa-check-group { margin-top: var(--s5); }
.sa-check-group-title { font-size: var(--fs-lg); font-weight: 650; margin-bottom: var(--s3); }
.sa-check-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--s3); }
.sa-check {
  display: flex;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-panel);
}
.sa-check-icon {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
}
.sa-check.pass .sa-check-icon { color: var(--pass); }
.sa-check.fail .sa-check-icon { color: var(--warn); }
.sa-check.unchecked .sa-check-icon { color: var(--text-faint); }
.sa-check.unchecked { opacity: 0.66; }
.sa-check-body { min-width: 0; }
.sa-check-label { font-size: var(--fs-sm); color: var(--text); }
.sa-check-label.link {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--brand);
  text-align: left;
  cursor: pointer;
}
.sa-check-label.link:hover { text-decoration: underline; }

/* The overview trend charts are a shortcut into Progress. */
.sa-trend-chart { cursor: pointer; border-radius: var(--radius-sm); }
.sa-trend-chart:hover { background: color-mix(in srgb, var(--text) 4%, transparent); }
.sa-trend-chart:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* Compare Crawls — the General summary above the issue diff */
.sa-cmp-section {
  font-size: var(--fs-lg);
  font-weight: 650;
  letter-spacing: -0.01em;
  margin: var(--s6) 0 var(--s3);
}
.sa-cmp-section:first-of-type { margin-top: var(--s4); }
.sa-general-table td:first-child { font-weight: 550; }
.sa-general-table td.strong { font-weight: 650; color: var(--text); }
.sa-general-sub {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 450;
  color: var(--text-faint);
  margin-top: 2px;
}

/* The site audit's own header rides above the scrolling body, under the app
   topbar. --sa-sticky-h is measured after render so the section headers below
   know where to stop. */
.sa-sticky {
  position: sticky;
  top: var(--topbar-h);
  z-index: 12;
  background: var(--bg);
  padding-top: var(--s3);
  margin-top: calc(var(--s3) * -1);
}
.sa-sticky .sa-tabs { margin-bottom: 0; }
.sa-body { padding-top: 18px; }

/* Compare Crawls column widths.

   `table-layout: fixed` rather than letting the browser size to content: with
   auto layout the label column and the Change chips negotiated for width
   between them, the table grew past its container, and the last column —
   New — was clipped off the right edge. The scrollbars are hidden across this
   interface, so nothing hinted that anything was missing.

   Both tables share these widths, which is what keeps the numbers in the
   General table aligned with the numbers in the three severity tables below
   it. */
.sa-general-table,
.sa-cmp-table { table-layout: fixed; width: 100%; }
.sa-cmp-col-label { width: auto; }
.sa-cmp-col-n { width: 96px; }
.sa-cmp-col-change { width: 144px; }
@media (max-width: 1200px) {
  .sa-cmp-col-n { width: 70px; }
  .sa-cmp-col-change { width: 112px; }
}
/* Full width. An earlier version capped the table at 1100px to stop the
   numbers drifting to the far right of a wide screen, which traded one
   problem for a worse one: the table stopped short of the card and left a
   band of dead space beside every row. The measure columns are wide enough
   to read as one block on their own. */
/* Fixed layout will not shrink a cell below its longest unbreakable word, so
   a long issue label has to be allowed to wrap. */
.sa-general-table td:first-child,
.sa-cmp-table td:first-child { white-space: normal; overflow-wrap: anywhere; }
/* Breathing room. These tables sit bare inside the card, so without their own
   inset the first label and the last number end up flush against the card's
   border on both sides. */
.sa-general-table th,
.sa-general-table td,
.sa-cmp-table th,
.sa-cmp-table td { padding: 11px 14px; }
.sa-general-table th:first-child,
.sa-general-table td:first-child,
.sa-cmp-table th:first-child,
.sa-cmp-table td:first-child { padding-left: 18px; }
.sa-general-table th:last-child,
.sa-general-table td:last-child,
.sa-cmp-table th:last-child,
.sa-cmp-table td:last-child { padding-right: 18px; }
/* The header band reads as a deliberate strip rather than a full-bleed edge. */
.sa-general-table thead th:first-child,
.sa-cmp-table thead th:first-child { border-top-left-radius: var(--radius-sm); }
.sa-general-table thead th:last-child,
.sa-cmp-table thead th:last-child { border-top-right-radius: var(--radius-sm); }
.sa-cmp-table thead th { padding-top: 13px; padding-bottom: 13px; }
.sa-general-table th.num,
.sa-general-table td.num,
.sa-cmp-table th.num,
.sa-cmp-table td.num { white-space: nowrap; }

/* Per-severity issue tables. The header of the section you are in stays at
   the top and is pushed out by the next one.

   The General table above them sits bare too — it used to be wrapped in a
   bordered, tinted panel while these were not, so the same six columns had
   two different frames on one screen. */
.sa-cmp-table { margin-bottom: var(--s6); }
.sa-general-table { margin-bottom: var(--s8); }
.sa-general-table thead th { background: var(--bg-panel-2); }
.sa-cmp-table thead th {
  position: sticky;
  top: calc(var(--topbar-h) + var(--sa-sticky-h, 92px));
  z-index: 8;
  background: var(--bg-panel-2);
  border-bottom: 2px solid var(--sev-accent, var(--border));
}
.sa-cmp-table thead th:first-child {
  font-size: var(--fs-lg);
  font-weight: 650;
  text-transform: none;
  letter-spacing: -0.01em;
  color: var(--text);
}
/* Icon, label and "Learn more" on one baseline with real space between them.
   The icon replaced an 8px square that the label sat directly against, so
   without this the two touch. */
.sa-cmp-name {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex-wrap: wrap;
  row-gap: 2px;
}
.sa-cmp-name-text { min-width: 0; }
.sa-cmp-name .sa-learn { margin-left: 0; }

.sa-cmp-quiet td { color: var(--text-faint); }
.sa-cmp-quiet td .sa-sev { opacity: 0.4; }
.sa-cmp-na {
  margin-left: 8px;
  font-size: var(--fs-xs);
  color: var(--text-faint);
  font-style: italic;
}
.sa-learn {
  margin-left: 10px;
  padding: 0;
  border: 0;
  background: none;
  font-size: var(--fs-xs);
  font-weight: 550;
  color: var(--text-dim);
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
  cursor: pointer;
}
.sa-learn:hover { color: var(--brand); }

/* The two crawl selectors in the widget header. */
.sa-compare-pickers {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
}
.sa-compare-pick {
  padding: 5px 26px 5px 10px;
  font-size: var(--fs-sm);
  font-weight: 550;
  max-width: 240px;
}
.sa-compare-vs {
  font-size: var(--fs-xs);
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* Fixed/New: a movement of zero is a dash, so the eye finds the real ones. */
.sa-moved { font-weight: 600; font-variant-numeric: tabular-nums; }
.sa-moved.zero { color: var(--text-faint); font-weight: 450; }
td:nth-child(5) > .sa-moved:not(.zero) { color: var(--pass); }
td:nth-child(6) > .sa-moved:not(.zero) { color: var(--warn); }

/* ---- Statistics ----------------------------------------------------------

   Two columns, fixed. `auto-fit` reflowed to three on a wide screen, which
   made the cards narrow enough that the histogram labels collided.
*/
.sa-stats-grid {
  display: grid;
  gap: var(--grid-gap);
  /* Stretch, not start: cards in a row share the tallest one's height, so a
     four-band section and a six-band section leave no ragged gap between
     them. */
  align-items: stretch;
}
/* Tiles are a list of numbers and pack four across. Graphs need width for an
   axis and its labels, so they stay at two. */
.sa-stats-grid.tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.sa-stats-grid.graphs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1400px) { .sa-stats-grid.tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 1050px) { .sa-stats-grid.tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) {
  .sa-stats-grid.tiles,
  .sa-stats-grid.graphs { grid-template-columns: 1fr; }
}
/* The card fills its stretched cell rather than floating at the top of it. */
.sa-stats-grid .widget { display: flex; flex-direction: column; }

/* At four across the cards are narrow enough that a long band name wraps.
   Aligning the row to the top rather than the middle keeps the count level
   with the first line of its label instead of floating between two. */
.sa-stats-grid.tiles .sa-statline { align-items: start; }
.sa-stats-grid.tiles .sa-statline-n { min-width: 32px; }
.sa-stats-grid.tiles .sa-statline-p { min-width: 40px; }
.sa-stats-grid.tiles .sa-statline-dot { margin-top: 5px; }

.sa-stats-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); flex-wrap: wrap; }
.sa-viewswitch { display: inline-flex; border: 1px solid var(--border); border-radius: 999px; padding: 2px; gap: 2px; }
.sa-viewbtn {
  border: 0;
  background: none;
  padding: 4px 14px;
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-dim);
  cursor: pointer;
}
.sa-viewbtn:hover { color: var(--text); }
.sa-viewbtn.on { background: var(--brand); color: var(--brand-text); }

/* The headline: the one number the section is about. */
.sa-stat-headline { margin-bottom: var(--s4); }
.sa-stat-figure {
  display: block;
  font-size: var(--fs-3xl);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.sa-stat-figure.good { color: var(--pass); }
.sa-stat-figure.warn { color: var(--warn); }
.sa-stat-figure.bad { color: var(--fail); }
.sa-stat-figure.neutral { color: var(--text); }
.sa-stat-sub { display: block; margin-top: 2px; font-size: var(--fs-sm); color: var(--text-dim); }

/* Tile view: a plain list, no boxes. */
.sa-statlist { display: flex; flex-direction: column; }
.sa-statline,
.sa-statlegend-row {
  display: grid;
  grid-template-columns: 9px 1fr auto auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 5px 6px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  font: inherit;
  text-align: left;
}
.sa-statline.clickable,
.sa-statlegend-row.clickable { cursor: pointer; }
.sa-statline.clickable:hover,
.sa-statlegend-row.clickable:hover { background: var(--bg-hover); }
.sa-statline-dot { width: 9px; height: 9px; border-radius: 50%; }
.sa-statline-l { font-size: var(--fs-sm); color: var(--text-dim); min-width: 0; }
.sa-statline.clickable:hover .sa-statline-l { color: var(--text); }
.sa-statline-n {
  font-size: var(--fs-sm);
  font-weight: 650;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  min-width: 44px;
  text-align: right;
}
.sa-statline-p {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  min-width: 46px;
  text-align: right;
}
/* A band with nothing in it stays listed — "zero 5xx" is the answer people
   came for — but it recedes so the bands that exist read first. */
.sa-statline.zero .sa-statline-l,
.sa-statline.zero .sa-statline-n,
.sa-statlegend-row.zero .sa-statline-l,
.sa-statlegend-row.zero .sa-statline-n { color: var(--text-faint); font-weight: 500; }
.sa-statline.zero .sa-statline-dot,
.sa-statlegend-row.zero .sa-statline-dot { opacity: 0.3; }

.sa-statlegend { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.sa-statlegend-row { grid-template-columns: 9px 1fr auto; }

/* Form: one 100% stacked bar. 2px surface gaps between segments. */
.sa-stackbar {
  display: flex;
  height: 30px;
  border-radius: 6px;
  overflow: hidden;
  gap: 2px;
  background: var(--bg-panel-2);
  margin-bottom: var(--s3);
}
.sa-stackbar-seg { display: block; min-width: 3px; }
.sa-stackbar-seg[data-sa-pages-filter] { cursor: pointer; }
.sa-stackbar-seg:hover { filter: brightness(1.12); }

/* Form: paired magnitude bars. */
.sa-pairbars { display: flex; flex-direction: column; gap: var(--s3); }
.sa-pairbar {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: 'l n' 'track track';
  gap: 4px 10px;
  width: 100%;
  border: 0;
  background: none;
  padding: 4px 6px;
  border-radius: var(--radius-sm);
  font: inherit;
  text-align: left;
}
.sa-pairbar.clickable { cursor: pointer; }
.sa-pairbar.clickable:hover { background: var(--bg-hover); }
.sa-pairbar-l { grid-area: l; font-size: var(--fs-sm); color: var(--text-dim); }
.sa-pairbar-n { grid-area: n; font-size: var(--fs-sm); font-weight: 650; color: var(--text); font-variant-numeric: tabular-nums; }
.sa-pairbar-track { grid-area: track; height: 14px; border-radius: 4px; background: var(--bg-panel-2); overflow: hidden; }
.sa-pairbar-fill { display: block; height: 100%; border-radius: 4px; }

/* Form: depth levels, stepping right as they go deeper. */
.sa-levels { display: flex; flex-direction: column; gap: 3px; }
.sa-level {
  display: grid;
  grid-template-columns: 96px 1fr auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 4px 6px;
  padding-left: calc(6px + var(--indent, 0px));
  border: 0;
  background: none;
  border-radius: var(--radius-sm);
  font: inherit;
  text-align: left;
}
.sa-level.clickable { cursor: pointer; }
.sa-level.clickable:hover { background: var(--bg-hover); }
.sa-level-l { font-size: var(--fs-xs); color: var(--text-dim); white-space: nowrap; }
.sa-level-track { height: 12px; border-radius: 4px; background: var(--bg-panel-2); overflow: hidden; }
.sa-level-fill { display: block; height: 100%; border-radius: 4px; }
.sa-level-n { font-size: var(--fs-sm); font-weight: 650; color: var(--text); font-variant-numeric: tabular-nums; min-width: 40px; text-align: right; }
.sa-level.zero .sa-level-l, .sa-level.zero .sa-level-n { color: var(--text-faint); font-weight: 500; }

/* Form: histogram with a value scale. */
.sa-histo { display: grid; grid-template-columns: auto 1fr; gap: 8px; }
.sa-histo-axis {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 150px;
  font-size: 10px;
  color: var(--text-faint);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.sa-histo-plot {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 150px;
  border-bottom: 1px solid var(--border);
  border-top: 1px dashed var(--border);
}
.sa-histo-col {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: stretch;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  position: relative;
}
.sa-histo-col.clickable { cursor: pointer; }
.sa-histo-col.clickable:hover .sa-histo-bar { filter: brightness(1.15); }
.sa-histo-bar { display: block; border-radius: 4px 4px 0 0; }
.sa-histo-x {
  position: absolute;
  bottom: -18px;
  left: 0;
  right: 0;
  font-size: 10px;
  color: var(--text-faint);
  text-align: center;
  white-space: nowrap;
}
.sa-histo { padding-bottom: 22px; }

/* Form: independent 0-100% tracks for overlapping bands. */
.sa-tracks { display: flex; flex-direction: column; gap: var(--s3); }
.sa-track {
  width: 100%;
  border: 0;
  background: none;
  padding: 4px 6px;
  border-radius: var(--radius-sm);
  font: inherit;
  text-align: left;
  display: block;
}
.sa-track.clickable { cursor: pointer; }
.sa-track.clickable:hover { background: var(--bg-hover); }
.sa-track-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 5px; }
.sa-track-l { flex: 1; min-width: 0; font-size: var(--fs-sm); color: var(--text-dim); }
.sa-track-p { font-size: var(--fs-xs); color: var(--text-faint); font-variant-numeric: tabular-nums; }
.sa-track-n { font-size: var(--fs-sm); font-weight: 650; color: var(--text); font-variant-numeric: tabular-nums; }
.sa-track-rail { display: block; height: 8px; border-radius: 4px; background: var(--bg-panel-2); overflow: hidden; }
.sa-track-fill { display: block; height: 100%; border-radius: 4px; }
.sa-track.zero .sa-track-l, .sa-track.zero .sa-track-n { color: var(--text-faint); font-weight: 500; }

/* Form: a single ratio against the whole. */
.sa-meter-rail { height: 22px; border-radius: 6px; background: var(--bg-panel-2); overflow: hidden; }
.sa-meter-fill { display: block; height: 100%; border-radius: 6px; }
.sa-meter-scale {
  display: flex;
  justify-content: space-between;
  font-size: var(--fs-xs);
  color: var(--text-faint);
  margin: 4px 0 var(--s3);
}

.sa-statfigure { margin-top: var(--s2); }

/* ---- Core Web Vitals ---- */
.sa-vitals-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  flex-wrap: wrap;
  margin: var(--s4) 0;
}
.sa-vitals-when { font-size: var(--fs-sm); color: var(--text-dim); }
.sa-vitals-actions { display: flex; align-items: center; gap: var(--s3); }
.sa-vitals-run { padding: 6px 16px; font-size: var(--fs-sm); }
.sa-vitals-err { color: var(--fail); }
.sa-vitals-targets { display: flex; flex-direction: column; gap: 4px; margin: var(--s3) 0; }
.sa-vitals-target {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  overflow-wrap: anywhere;
}
.sa-vitals-target span { display: block; font-size: var(--fs-xs); color: var(--fail); }

.sa-vitals-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: var(--s3);
}
/* The three that decide the assessment sit forward; FCP and TTFB are
   diagnostics and recede, so the card cannot be misread as five equal
   Core Web Vitals — there are three. */
.sa-vital {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--s3);
  background: var(--bg-panel-2);
}
.sa-vital.core { background: var(--bg-panel-2); border-color: var(--border); }
.sa-vital:not(.core) { background: transparent; opacity: 0.85; }
.sa-vital-head { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; }
.sa-vital-short { font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.04em; color: var(--text-dim); }
.sa-vital-core {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--brand);
  border: 1px solid color-mix(in srgb, var(--brand) 45%, transparent);
  border-radius: 999px;
  padding: 0 6px;
}
.sa-vital-value {
  font-size: var(--fs-2xl);
  font-weight: 700;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.sa-vital-name { font-size: var(--fs-sm); font-weight: 550; color: var(--text); margin-top: 2px; }
.sa-vital-why { font-size: var(--fs-xs); color: var(--text-faint); margin-top: 3px; line-height: 1.4; }
.sa-vital-none { color: var(--text-faint); }
.sa-vitals-table th, .sa-vitals-table td { padding: 10px 14px; }
.sa-vitals-table th:first-child, .sa-vitals-table td:first-child { padding-left: 18px; }

/* ---- JS Impact ---- */
.sa-legend-name { flex: 1; min-width: 0; }
.sa-url-link,
.sa-struct-pagelink {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  color: var(--brand);
  text-align: left;
  cursor: pointer;
  word-break: break-all;
}
.sa-url-link:hover,
.sa-struct-pagelink:hover { text-decoration: underline; }

.sa-js-stats { display: flex; flex-direction: column; gap: var(--s1); }
.sa-js-stat {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: 'v l' 'v n';
  align-items: center;
  column-gap: var(--s3);
  padding: var(--s2) var(--s2);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  font: inherit;
  text-align: left;
  width: 100%;
}
.sa-js-stat.clickable { cursor: pointer; }
.sa-js-stat.clickable:hover { background: var(--bg-hover); }
.sa-js-stat-v {
  grid-area: v;
  font-size: var(--fs-xl);
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  min-width: 74px;
}
.sa-js-stat-l { grid-area: l; font-size: var(--fs-sm); font-weight: 550; color: var(--text); }
.sa-js-stat-n { grid-area: n; font-size: var(--fs-xs); color: var(--text-faint); }
.sa-js-caveat { margin-top: var(--s5); }

/* ---- Progress: one chart, pick what goes on it ---- */
.sa-prog-chart-wrap {
  position: relative;
  padding: var(--s4) var(--s4) var(--s3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-panel);
}
.sa-prog-chart { position: relative; }
.sa-prog-hit { cursor: crosshair; }
.sa-prog-blank {
  height: 200px;
  display: grid;
  place-items: center;
  color: var(--text-faint);
  font-size: var(--fs-sm);
}
.sa-prog-tip {
  position: absolute;
  z-index: 5;
  min-width: 190px;
  max-width: 280px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-panel);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.16);
  font-size: var(--fs-xs);
  pointer-events: none;
}
.sa-prog-tip-when {
  font-weight: 650;
  color: var(--text);
  margin-bottom: 5px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--border);
}
.sa-prog-tip-row { display: flex; align-items: center; gap: 6px; padding: 2px 0; }
.sa-prog-tip-label { color: var(--text-dim); flex: 1; min-width: 0; }
.sa-prog-tip-val { font-weight: 650; font-variant-numeric: tabular-nums; color: var(--text); }
.sa-prog-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }

.sa-prog-legend {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: var(--s3);
  padding-top: var(--s3);
  border-top: 1px solid var(--border);
}
.sa-prog-legend-label {
  font-size: var(--fs-xs);
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-right: 4px;
}
.sa-prog-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px 4px 7px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-panel-2);
  font-size: var(--fs-xs);
  font-weight: 550;
  color: var(--text-dim);
  cursor: pointer;
}
.sa-prog-chip:hover { border-color: var(--fail); color: var(--text); }
.sa-prog-x { color: var(--text-faint); font-size: 13px; line-height: 1; }
.sa-prog-chip:hover .sa-prog-x { color: var(--fail); }

.sa-prog-picker {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s5);
  margin-top: var(--s5);
}
@media (max-width: 1100px) { .sa-prog-picker { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .sa-prog-picker { grid-template-columns: 1fr; } }
.sa-prog-group-title { font-size: var(--fs-md); font-weight: 650; margin-bottom: 6px; }
.sa-prog-rule { height: 3px; border-radius: 2px; margin-bottom: var(--s3); }
.sa-prog-options { display: flex; flex-wrap: wrap; gap: 6px; }
.sa-prog-opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--text-dim);
  cursor: pointer;
  text-align: left;
  line-height: 1.3;
}
.sa-prog-opt:hover { border-color: var(--text-faint); color: var(--text); }
.sa-prog-radio {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 1.5px solid var(--text-faint);
  flex: none;
}
.sa-prog-opt.on {
  border-color: var(--opt-colour);
  color: var(--text);
  font-weight: 600;
  background: color-mix(in srgb, var(--opt-colour) 8%, transparent);
}
.sa-prog-opt.on .sa-prog-radio { border-color: var(--opt-colour); background: var(--opt-colour); }
/* A check that has never fired here. Still offered — "never once broken" is
   an answer — but dimmed, so the list reads as what has happened first. */
.sa-prog-opt.flat:not(.on) { color: var(--text-faint); border-style: dashed; }

/* ---- Thematic reports ---- */
.sa-themes { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; }
.sa-theme {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.sa-theme-label { font-size: 14.5px; font-weight: 600; color: var(--text); }
.sa-theme-score { display: flex; align-items: center; gap: 8px; font-size: 22px; }
.sa-theme-score strong { font-weight: 700; letter-spacing: -0.02em; }
.sa-theme-value { font-size: 16.5px; font-weight: 600; color: var(--text-dim); }
.sa-theme-note { font-size: 13px; color: var(--text-faint); line-height: 1.5; flex: 1; }
.sa-theme .btn-tiny { align-self: flex-start; }

/* `hidden` is only `display:none` at the UA level, so any rule that sets
   display (flex, grid) silently defeats it — which is why the "Show all"
   bot list and the benchmark list were visible while still marked hidden. */
[hidden] { display: none !important; }

/* ============================================================
   TYPE AND SPACING SYSTEM
   ------------------------------------------------------------
   Replaces the previous ad-hoc pass. Two problems were making the
   interface feel unsettled regardless of the font size: nearly
   every component had picked its own padding (16, 18, 14, 11, 7),
   so no two edges lined up; and vertical gaps between unrelated
   things were often larger than the gaps inside a single group,
   which is the specific thing that makes a page read as noisy
   rather than dense.

   Everything below is driven by two scales. Sizes step in a way
   the eye can distinguish; spacing is a 4px grid. A component
   that needs a value picks the nearest token instead of inventing
   one, so edges align across unrelated widgets by construction.
   ============================================================ */

:root {
  /* Type. 14px base, 16px section heading — the two anchors;
     everything else is derived so the ratios hold if the base moves. */
  --fs-2xs: 11px;
  --fs-xs: 12px;
  --fs-sm: 13px;
  --fs-base: 14px;
  --fs-md: 15px;
  --fs-lg: 16px;   /* h3 / widget title */
  --fs-xl: 18px;
  --fs-2xl: 22px;  /* page title */
  --fs-3xl: 28px;  /* KPI values */
  --fs-4xl: 34px;  /* single hero number */

  /* Spacing, 4px grid. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 20px;
  --s6: 24px;
  --s8: 32px;
  --s10: 40px;

  /* One card padding and one grid gap for the whole interface. */
  --card-pad: var(--s5);
  /* How far an edge-to-edge list row sets its content in. Wider than the card
     padding: a row that bleeds to the border needs more breathing room inside
     it than a block that stops at the padding. */
  --issue-inset: var(--s8);
  --grid-gap: var(--s4);
  --section-gap: var(--s6);
}

/* ---- Base ------------------------------------------------- */

html, body {
  font-size: var(--fs-base);
  line-height: 1.5;
  /* Manrope carries the interface; the rest of the stack is what
     renders before it arrives and if it never does. */
  font-family: Manrope, -apple-system, BlinkMacSystemFont,
    "Segoe UI", Inter, Roboto, Helvetica, Arial, sans-serif;
  /* Manrope's default figures are proportional; tabular ones keep
     columns of numbers from shifting as values change. */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 { line-height: 1.3; letter-spacing: -0.01em; }
h3 { font-size: var(--fs-lg); font-weight: 700; margin: 0; }

/* ---- Shell ------------------------------------------------ */

:root { --rail-w: 76px; --sidebar-w: 236px; }
.main { padding: var(--s8) var(--s8) var(--s10); }
.rail-item { font-size: var(--fs-xs); width: 60px; padding: var(--s2) var(--s1); }
.nav-item { padding: var(--s2) var(--s3); font-size: var(--fs-base); }
.nav-group-label {
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: var(--s1);
}
.nav-group + .nav-group { margin-top: var(--s5); }

/* ---- Page header ------------------------------------------ */

.page-title, .dash-title { font-size: var(--fs-2xl); font-weight: 700; margin: 0; }
.page-desc { font-size: var(--fs-base); line-height: 1.55; margin-top: var(--s1); }

/* ---- Cards and grids -------------------------------------- */

.widget { padding: var(--card-pad); }
.widget-grid { gap: var(--grid-gap); }
.widget-grid + .widget-grid,
.widget-grid + .widget,
.widget + .widget-grid { margin-top: var(--grid-gap); }

/* The heading sits closer to its own content than to the card edge
   above it — the rule that makes a group read as a group. */
.widget-head { margin-bottom: var(--s4); gap: var(--s2); }
.widget-title { font-size: var(--fs-lg); }
.widget-body { font-size: var(--fs-base); line-height: 1.6; }

.kpi-row { gap: var(--s1); }
.kpi { padding-right: var(--s5); }
.kpi-label { font-size: var(--fs-sm); margin-bottom: var(--s1); }
.kpi-value { font-size: var(--fs-3xl); }
.kpi-sub { font-size: var(--fs-sm); }
.hint { font-size: var(--fs-sm); line-height: 1.55; }

/* ---- Controls --------------------------------------------- */

.btn, .btn-secondary { font-size: var(--fs-base); padding: var(--s2) var(--s4); }
.btn-tiny { font-size: var(--fs-sm); padding: 5px var(--s3); }
input[type="text"], input[type="url"], input[type="password"], input[type="number"],
input[type="email"], input[type="search"], select, textarea {
  font-size: var(--fs-base);
  padding: var(--s2) var(--s3);
}
label { font-size: var(--fs-sm); }

/* ---- Tables ----------------------------------------------- */

.data-table { font-size: var(--fs-base); }
.data-table th {
  font-size: var(--fs-xs);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding-bottom: var(--s2);
}
.data-table td { padding: var(--s3) var(--s3) var(--s3) 0; }

/* ---- Site Audit ------------------------------------------- */

.sa-meta { font-size: var(--fs-sm); gap: var(--s2) var(--s5); margin: var(--s2) 0 var(--s5); }
.sa-tabs { margin-bottom: var(--s5); gap: 0; }
.sa-tab { font-size: var(--fs-base); padding: var(--s3) var(--s4); }
.sa-split { gap: var(--s6); }

.gauge-half { margin: 0 auto; }
.sa-gauge-delta { display: none; } /* the caption lives inside the gauge */

/* Number, delta and the stacked bar on one row. */
.sa-pages-head {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  gap: var(--s3);
  margin-bottom: var(--s4);
}
.sa-pages-count { font-size: var(--fs-3xl); font-weight: 700; letter-spacing: -0.02em; line-height: 1; }
.sa-pages-delta { font-size: var(--fs-sm); color: var(--text-faint); white-space: nowrap; }
.sa-pages-head .sa-stack { height: 12px; }

.sa-legend { margin-top: 0; gap: var(--s1); }
.sa-legend-row { font-size: var(--fs-base); padding: var(--s1) 0; }
.sa-dot { width: 8px; height: 8px; }
.sa-count-link { font-size: var(--fs-base); }

.sa-bullets { margin-top: var(--s4); gap: var(--s2); }
.sa-bullet { font-size: var(--fs-base); }
.sa-bullet-note { font-size: var(--fs-sm); line-height: 1.5; }
.sa-bench-toggle { font-size: var(--fs-base); }

.sa-bots { gap: 0; }
.sa-bot-row { padding: var(--s2) 0; font-size: var(--fs-base); gap: var(--s3); }
.sa-bot-ok, .sa-bot-blocked, .sa-bot-partial { font-size: var(--fs-sm); }
.sa-bot-purpose { font-size: var(--fs-2xs); padding: 0 5px; }

.sa-note { font-size: var(--fs-sm); padding: var(--s3) var(--s4); margin-top: var(--s4); }
.sa-ai-footer { font-size: var(--fs-sm); margin-top: var(--s4); }
.sa-issue-link { font-size: var(--fs-sm); }

/* Same again: type scale only. `padding: var(--s3) 0` here was the rule that
   actually won, so every earlier attempt to set the row's inset did nothing
   and the text ended up hard against the card border. */
.sa-issue { font-size: var(--fs-base); gap: var(--s3); }
.sa-issue-label { font-size: var(--fs-base); }
.sa-issue-count, .sa-howto { font-size: var(--fs-sm); }

/* The hero number and its qualifier are one unit: 4px between them,
   a full step to whatever follows. Previously the number floated
   alone above a chart with equal space on both sides, so it read as
   belonging to neither. */
.sa-big-number { font-size: var(--fs-4xl); line-height: 1.05; margin: 0; }
.sa-big-sub { font-size: var(--fs-sm); color: var(--text-faint); margin: var(--s1) 0 var(--s3); }
.sa-trend-split { margin-top: var(--s6); }
.sa-band-count { font-size: var(--fs-sm); color: var(--text-faint); margin-left: auto; }
.sa-issue-band + .sa-issue-band { margin-top: var(--grid-gap); }

.sa-theme { padding: var(--s4); gap: var(--s2); }
.sa-theme-label { font-size: var(--fs-base); }
.sa-theme-score { font-size: var(--fs-xl); gap: var(--s2); }
.sa-theme-score svg { width: 20px; height: 20px; }
.sa-theme-note { font-size: var(--fs-xs); line-height: 1.45; }
.sa-theme-value { font-size: var(--fs-lg); }


/* Bot name over its chip: on one line "Google-Extended" plus the chip
   plus the verdict does not fit the column, and every way of forcing
   it costs a whole word. */
.sa-bot-row { flex-wrap: nowrap; }
.sa-bot-name { flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; }
.sa-bot-label { line-height: 1.25; white-space: nowrap; }
.sa-bot-purpose { flex-shrink: 0; white-space: nowrap; }
.sa-bot-ok, .sa-bot-blocked, .sa-bot-partial { white-space: nowrap; flex-shrink: 0; }

/* Cards in a row share a bottom edge; the shorter one spreads its
   content rather than piling it above an empty half. */
.sa-body .widget-grid.cols-2 { align-items: stretch; }
.sa-split-col { display: flex; flex-direction: column; }
.sa-split-col > .gauge-half { margin-top: auto; margin-bottom: auto; }

/* ---- Project cards ---------------------------------------- */

.project-stats { gap: var(--s4) var(--s3); padding-top: var(--s4); }
.project-stat-label {
  font-size: var(--fs-xs);
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.3;
  min-height: 2.6em;
  margin-bottom: var(--s1);
  display: flex;
  align-items: flex-end;
}
.project-stat-value { font-size: var(--fs-xl); }
.project-card-actions { padding-top: var(--s4); gap: var(--s2); }

/* "No data" must not be typeset like a measurement — the generic
   widget-grid rule outranks `.kpi-value.empty` on specificity, so it
   needs matching weight to win. */
.widget-grid .kpi-value.empty,
.widget-grid:not(.cols-2) .kpi-value.empty {
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--text-faint);
  white-space: nowrap;
}

/* ---- Promo strip ------------------------------------------ */

/* The copy column was capped at 460px inside a 1100px card, so on a wide
   monitor two thirds of the strip was empty gradient — the largest piece of
   nothing on the dashboard. Letting the copy run to a comfortable measure and
   trimming the padding turns it back into a banner rather than a void. */
.promo { padding: var(--s6); gap: var(--s6); }
.promo-copy { max-width: 620px; }
.promo h2 { font-size: var(--fs-2xl); margin-bottom: var(--s2); }
.promo p { font-size: var(--fs-base); margin-bottom: var(--s4); }

/* ---- Section headings ------------------------------------- */

/* A section heading is a break between groups, so it takes the section step
   above it and the grid step below — the asymmetry is what tells the eye the
   heading belongs to the cards under it and not the card above it. */
.section-head { margin-top: var(--section-gap); gap: var(--s2); }
.section-head h2 { font-size: var(--fs-lg); }
.section-head-meta { font-size: var(--fs-sm); }
.project-grid { gap: var(--grid-gap); margin-top: var(--s3); }
.widget-grid + .promo, .project-grid + .widget-grid { margin-top: var(--section-gap); }

/* Cards in a row are equal height, so the shorter one ends up with slack.
   Pinning the actions to the bottom edge puts that slack in one place and
   lines the buttons up across the row, instead of leaving each card's footer
   floating at whatever height its own content happened to end. */
.project-card { padding: var(--card-pad); gap: var(--s4); }
.project-card-actions { margin-top: auto; }
.project-card-name { font-size: var(--fs-lg); }
.project-card-url { font-size: var(--fs-sm); }

/* Thematic report cards stretch to the tallest in the row, so the ones with a
   shorter note left their button floating mid-card. Pinning the action to the
   bottom lines every button up along one edge. */
.sa-theme .btn-tiny { margin-top: auto; align-self: flex-start; }
.sa-theme-label { font-size: var(--fs-base); }
.sa-theme-note { margin-bottom: var(--s1); }

/* Buttons and form controls do not inherit the page font — the UA stylesheet
   sets its own, which is why every button was still rendering in Arial while
   the rest of the interface had moved to Manrope. */
button, input, select, textarea, .btn, .btn-secondary, .btn-tiny {
  font-family: inherit;
}

/* ============================================================
   TOOLTIPS AND PANELS
   ============================================================ */

.info-dot { cursor: help; }
.info-dot:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.zw-tip {
  position: absolute;
  z-index: 200;
  max-width: 320px;
  padding: var(--s2) var(--s3);
  background: var(--text);
  color: var(--bg-panel);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  line-height: 1.45;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
  pointer-events: none; /* never swallow the hover that produced it */
}
/* A small pointer so the tooltip is visibly attached to what it explains. */
.zw-tip::after {
  content: '';
  position: absolute;
  left: 50%;
  margin-left: -5px;
  border: 5px solid transparent;
  border-top-color: var(--text);
  top: 100%;
}
.zw-tip.below::after {
  top: auto;
  bottom: 100%;
  border-top-color: transparent;
  border-bottom-color: var(--text);
}

.zw-panel-backdrop {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(15, 18, 26, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s6);
}
body.zw-panel-open { overflow: hidden; }

.zw-panel {
  width: 100%;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
}
.zw-panel-head {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s4) var(--s5);
  border-bottom: 1px solid var(--border);
}
.zw-panel-title { font-size: var(--fs-lg); font-weight: 700; color: var(--text); }
.zw-panel-close {
  margin-left: auto;
  border: 0;
  background: transparent;
  color: var(--text-faint);
  font-size: 22px;
  line-height: 1;
  padding: 0 var(--s1);
  cursor: pointer;
}
.zw-panel-close:hover { color: var(--text); }
/* The body scrolls, the header stays — a long list never pushes the close
   button off screen. */
.zw-panel-body { padding: var(--s5); overflow-y: auto; }
.zw-panel-lead {
  margin: 0 0 var(--s4);
  font-size: var(--fs-sm);
  color: var(--text-dim);
  line-height: 1.55;
}
.zw-panel-lead strong { color: var(--text); }
.zw-panel-note {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  line-height: 1.45;
  padding: 0 0 var(--s3);
  margin-top: -2px;
}
.zw-panel .sa-bot-row { border-bottom: 0; padding-bottom: var(--s1); }

/* The Errors / Warnings blocks are a number with a line under it, not two
   charts stacked in a card. Tightened so the number leads and the sparkline
   sits close enough to read as its footnote. */
.sa-big-number { margin-top: var(--s1); }
.sa-big-sub { margin: 2px 0 var(--s2); }
.sa-trend-split { margin-top: var(--s6); margin-bottom: 0; }

/* Eight thematic reports in a fixed 4 x 2 grid. Previously the column count
   fell out of whatever width was left over, so the same eight cards made
   seven-and-one on a wide monitor — a stranded card on its own row. Four is a
   divisor of eight, so both rows are always full. */
.sa-themes { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s3); }
@media (max-width: 900px) { .sa-themes { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Four to a row leaves each card room for a full-size score. */
.sa-theme { padding: var(--s4); }
.sa-theme-label { font-size: var(--fs-base); line-height: 1.3; overflow-wrap: break-word; }
.sa-theme-score { font-size: var(--fs-xl); gap: var(--s2); }
.sa-theme-score svg { width: 18px; height: 18px; flex-shrink: 0; }
.sa-theme-value { font-size: var(--fs-lg); }
.sa-theme-note { font-size: var(--fs-xs); }

/* ---- Score breakdown -------------------------------------- */

.sa-why {
  margin-top: var(--s3);
  border: 0;
  background: transparent;
  padding: 0;
  color: var(--info);
  font: inherit;
  font-size: var(--fs-sm);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  align-self: flex-start;
}
.sa-why:hover { color: var(--text); }

.sa-score-row {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--border);
}
.sa-score-row:last-child { border-bottom: 0; }
.sa-score-label { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sa-score-label .kpi-sub { font-size: var(--fs-xs); }
.sa-score-cost {
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--fail);
  white-space: nowrap;
}
/* The two summary rows are the arithmetic closing, so they sit apart from the
   itemised list above them. */
.sa-score-row.total { border-top: 1px solid var(--border); border-bottom: 0; padding: var(--s3) 0 0; }
.sa-score-cost.final { color: var(--text); }
.zw-panel-note-block {
  margin: var(--s4) 0 0;
  font-size: var(--fs-sm);
  color: var(--text-faint);
  line-height: 1.5;
}
.sa-legend-row.cross { border-top: 1px solid var(--border); margin-top: var(--s2); padding-top: var(--s2); }
.sa-legend-row.cross .info-dot { transform: scale(0.85); }

/* A partial crawl has to say so in the header: every count below it is a count
   of what was crawled, not of the site. */
.sa-meta-warn { color: var(--warn); display: inline-flex; align-items: center; gap: 6px; }
.sa-meta-warn .info-dot { border-color: currentColor; color: currentColor; }

/* The max column is the point of the new model — it shows the ceiling on what
   a check can cost, which is what makes "this issue is everywhere but only
   worth 4 points" legible rather than arbitrary. */
.sa-score-max {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  white-space: nowrap;
  min-width: 62px;
  text-align: right;
}
.sa-fatal-badge {
  display: inline-block;
  /* The label is a flex column, so an inline-block child stretches to full
     width and reads as an empty input. */
  align-self: flex-start;
  margin: 2px 0 0;
  padding: 1px 6px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: var(--fs-2xs);
  color: var(--text-faint);
  vertical-align: middle;
}
.sa-score-label > strong { display: inline; }

/* A crawl that reached nothing gets a blank, not a flattering 100. */
.sa-noscore { margin: auto 0; text-align: center; padding: var(--s5) 0; }
.sa-noscore-mark { font-size: 42px; font-weight: 700; color: var(--text-faint); line-height: 1; }
.sa-noscore .kpi-sub { margin-top: var(--s3); line-height: 1.5; }

/* ---- Crawled Pages table ----------------------------------- */

/* The table was a two-line cell per row — URL above title — which made 48
   pages nearly a thousand pixels of scrolling. One line per page, with the
   title in its own column, is both denser and easier to scan down. */
.sa-page-table td { padding: var(--s2) var(--s3) var(--s2) 0; vertical-align: middle; }
.sa-page-table th { padding-bottom: var(--s2); white-space: nowrap; }
.sa-ilr-col { width: 56px; }
.sa-ilr { font-weight: 700; color: var(--text); }
.sa-url-cell { max-width: 380px; }
.sa-url-cell a {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sa-title-cell {
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-dim);
}

/* ---- One page in detail ------------------------------------ */

.sa-pp-head { display: flex; align-items: flex-start; gap: var(--s3); margin-bottom: var(--s5); }
.sa-pp-back {
  border: 1px solid var(--border);
  background: var(--bg-panel);
  border-radius: var(--radius-sm);
  width: 30px;
  height: 30px;
  font-size: 15px;
  line-height: 1;
  color: var(--text-dim);
  cursor: pointer;
  flex-shrink: 0;
}
.sa-pp-back:hover { color: var(--text); border-color: var(--text-faint); }
.sa-pp-title { min-width: 0; }
.sa-pp-url { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.sa-pp-url a { font-size: var(--fs-xl); font-weight: 700; word-break: break-all; }

/* Summary column fixed, issues column takes the rest — the issue list is the
   part that varies in length and deserves the room. */
.sa-pp-body { display: grid; grid-template-columns: 300px 1fr; gap: var(--grid-gap); align-items: start; }
@media (max-width: 900px) { .sa-pp-body { grid-template-columns: 1fr; } }

.sa-pp-stat { padding: var(--s3) 0; border-bottom: 1px solid var(--border); }
.sa-pp-stat:last-child { border-bottom: 0; padding-bottom: 0; }
.sa-pp-label { font-size: var(--fs-sm); color: var(--text-dim); margin-bottom: var(--s1); }
.sa-pp-value { font-size: var(--fs-base); color: var(--text); word-break: break-word; }
.sa-pp-value a { word-break: break-all; }
.sa-pp-ilr { display: flex; align-items: center; gap: var(--s3); font-size: var(--fs-2xl); font-weight: 700; }
.sa-pp-bar { flex: 1; height: 6px; background: var(--bg-panel-2); border-radius: 3px; overflow: hidden; }
.sa-pp-bar > span { display: block; height: 100%; background: var(--brand); }

/* A snapshot missing newer fields explains itself rather than showing a
   column of dashes that reads as a broken query. */
.sa-stale {
  margin: 0 0 var(--s4);
  padding: var(--s3) var(--s4);
  border: 1px solid var(--border);
  border-left: 3px solid var(--warn);
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  font-size: var(--fs-sm);
  color: var(--text-dim);
  line-height: 1.55;
}

/* ---- How-to-fix panel -------------------------------------- */

/* Two columns, as in the reference: what the issue is on the left, the steps
   on the right. It is a panel rather than an inline expander because the steps
   run to four or five lines and unfolding them in place pushed the rest of the
   issue list off the screen. */
.sa-fix-panel { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s5); }
@media (max-width: 720px) { .sa-fix-panel { grid-template-columns: 1fr; } }
.sa-fix-panel strong { display: block; font-size: var(--fs-base); color: var(--text); margin-bottom: var(--s3); }
.sa-fix-panel p { margin: 0 0 var(--s3); line-height: 1.6; color: var(--text-dim); }
.sa-fix-about { padding-right: var(--s2); }
.sa-fix-how {
  background: var(--bg-panel-2);
  border-radius: var(--radius-sm);
  padding: var(--s4);
}
.sa-fix-how ol { margin: 0; padding-left: var(--s5); color: var(--text-dim); line-height: 1.6; }
.sa-fix-how li { margin-bottom: var(--s3); }
.sa-fix-how li:last-child { margin-bottom: 0; }
.sa-fix-cat { font-size: var(--fs-sm); color: var(--text-faint); margin: 0; }
.sa-fix-cat span { color: var(--text-dim); }

/* The one line that is about the page you came from, above the general
   explanation — so the panel answers "what is wrong here" before "what is this
   issue". */
.sa-fix-scope {
  margin: 0 0 var(--s4);
  padding: var(--s3) var(--s4);
  border-left: 3px solid var(--brand);
  background: var(--bg-panel-2);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--text);
  line-height: 1.55;
  word-break: break-word;
}

/* A tooltip carrying a date and a value, rather than a sentence — the chart
   points. Light card on both themes so it reads as a data callout rather than
   a hint, matching the reference. */
.zw-tip.rich {
  background: var(--bg-panel);
  color: var(--text);
  border: 1px solid var(--border);
  padding: var(--s3) var(--s4);
  max-width: none;
  white-space: nowrap;
}
.zw-tip.rich::after { border-top-color: var(--bg-panel); }
.zw-tip.rich.below::after { border-bottom-color: var(--bg-panel); }
.zw-tip-when { color: var(--text-dim); margin-bottom: var(--s2); }
.zw-tip-row { display: flex; align-items: center; gap: var(--s2); }
.zw-tip-row strong { margin-left: var(--s5); font-weight: 700; }
.zw-tip-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

/* A chart point is a hover target, so say so. */
.sa-big-sub + svg [data-tip-html],
svg [data-tip-html] { cursor: pointer; }

/* ---- Thematic report ---------------------------------------- */

.sa-theme-report > .btn-tiny:first-child { margin-bottom: var(--s4); }
.sa-report-title {
  font-size: var(--fs-2xl);
  font-weight: 700;
  margin: 0 0 var(--s1);
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
}
.sa-report-name { letter-spacing: -0.01em; }
/* The separator borrows the reference layout: "Title / Score: ◔ 87%". It is
   deliberately quiet so the two halves read as one line rather than two
   competing headings. */
.sa-report-sep { color: var(--text-faint); font-weight: 400; }
.sa-report-score { display: inline-flex; align-items: center; gap: var(--s2); }
.sa-score-label { font-size: var(--fs-lg); font-weight: 500; color: var(--text-dim); }
.sa-score-value { font-size: var(--fs-2xl); font-weight: 700; letter-spacing: -0.01em; }
/* The sentence explaining what the percentage counts, on its own line under
   the score rather than trailing it — a number needs to be findable before
   it needs to be explained. */
.sa-report-note { margin: 0 0 var(--s5); font-size: var(--fs-sm); color: var(--text-dim); }
.widget-grid.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1100px) { .widget-grid.cols-3 { grid-template-columns: 1fr; } }

.sa-donut { margin: var(--s3) auto var(--s4); }
.sa-count-plain { color: var(--info); font-weight: 600; }

/* Horizontal bars for markup-type coverage. */
.sa-bar-row { margin-bottom: var(--s4); }
.sa-bar-row:last-child { margin-bottom: 0; }
.sa-bar-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s3);
  margin-bottom: var(--s2);
  font-size: var(--fs-sm);
}
.sa-bar-val { color: var(--text-faint); white-space: nowrap; }
.sa-bar-val strong { color: var(--info); margin-left: var(--s2); }
.sa-bar { height: 8px; background: var(--bg-panel-2); border-radius: 4px; overflow: hidden; }
.sa-bar > span { display: block; height: 100%; background: var(--brand); }

.sa-basis {
  margin-left: auto;
  border: 0;
  background: transparent;
  padding: 0;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--info);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.sa-items-table td { vertical-align: middle; }
.sa-items-bar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; min-width: 120px; }
.sa-items-bar > span { display: block; height: 100%; }

/* ---- Invalid structured data ------------------------------- */

.sa-invalid-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s5);
  flex-wrap: wrap;
}
.sa-invalid-head .sa-report-title { margin-bottom: var(--s3); }
.sa-invalid-ratio {
  display: flex;
  align-items: center;
  gap: var(--s3);
  font-size: var(--fs-sm);
  color: var(--text-dim);
}
.sa-ratio-fail strong { color: var(--fail); }
.sa-ratio-ok strong { color: var(--pass); }
.sa-ratio-hidden { color: var(--text-faint); }
.sa-ratio-bar { display: flex; width: 110px; height: 8px; border-radius: 4px; overflow: hidden; background: var(--bg-panel-2); }
.sa-ratio-bar .fail { background: var(--fail); }
.sa-ratio-bar .ok { background: var(--pass); }

.sa-invalid-bar {
  display: flex;
  align-items: center;
  gap: var(--s4);
  margin: var(--s4) 0;
  flex-wrap: wrap;
}
.sa-invalid-tabs { display: flex; gap: var(--s2); margin-left: auto; }

.sa-row-actions { display: flex; gap: var(--s2); justify-content: flex-end; }
.sa-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 26px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-panel);
  color: var(--text-dim);
  cursor: pointer;
  padding: 0;
}
.sa-icon-btn:hover { color: var(--text); border-color: var(--text-faint); }
.sa-icon-btn.active { color: var(--text); background: var(--bg-panel-2); }

/* The raw block, monospaced and scrollable — the whole point is reading the
   character the parser choked on. */
.sa-code {
  margin: 0;
  padding: var(--s4);
  background: var(--bg-panel-2);
  border-radius: var(--radius-sm);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs-xs);
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 46vh;
  overflow: auto;
  color: var(--text-dim);
}

/* ---- Site structure ---------------------------------------- */

.sa-view-toggle { display: inline-flex; gap: 2px; margin-left: var(--s3); }
.sa-structure-table td { padding: var(--s2) var(--s3) var(--s2) 0; vertical-align: middle; }
.sa-struct-root { font-weight: 600; }
.sa-struct-name { display: inline-flex; align-items: center; gap: var(--s2); }
.sa-struct-icon { color: var(--brand); display: inline-flex; }
.sa-struct-toggle {
  border: 0;
  background: transparent;
  color: var(--text-faint);
  cursor: pointer;
  width: 16px;
  padding: 0;
  font-size: 11px;
  line-height: 1;
}
.sa-struct-toggle.placeholder { cursor: default; }
.sa-struct-toggle:hover { color: var(--text); }
.sa-struct-issues { color: var(--warn); font-weight: 600; }
.zw-tip-n { margin-left: var(--s3); }

/* The items table was inheriting the default row padding, which at eleven rows
   made a simple frequency list nearly 600px tall, and the two count columns
   sat far from the labels they belong to. Item takes a fixed share, the counts
   pair up beside it, and the bar gets the remaining width. */
.sa-items-table { table-layout: fixed; width: 100%; }
.sa-items-table th,
.sa-items-table td { padding: var(--s2) var(--s3) var(--s2) 0; }
.sa-items-table th:first-child,
.sa-items-table td:first-child { padding-left: var(--s3); }
.sa-items-table col.item { width: 34%; }
.sa-items-table th:nth-child(2),
.sa-items-table td:nth-child(2),
.sa-items-table th:nth-child(3),
.sa-items-table td:nth-child(3) { width: 84px; }
.sa-items-table td:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sa-items-table .sa-items-bar { height: 7px; }

/* ---- Crawled-pages filters --------------------------------- */

.sa-filter-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-bottom: var(--s4);
  flex-wrap: wrap;
}
.sa-search input { width: 260px; }
.sa-filter-count {
  display: inline-block;
  min-width: 16px;
  padding: 0 4px;
  margin-left: 4px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.25);
  font-size: var(--fs-2xs);
}
.sa-clear-filters {
  border: 0;
  background: transparent;
  color: var(--text-faint);
  font: inherit;
  font-size: var(--fs-sm);
  cursor: pointer;
}
.sa-clear-filters:hover { color: var(--text); }

/* The builder floats over the table rather than pushing it down, so the rows
   you are filtering stay in view while you set the conditions. */
.sa-filter-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 60;
  min-width: 560px;
  padding: var(--s4);
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.22);
}
.sa-filter-row { display: flex; align-items: center; gap: var(--s2); margin-bottom: var(--s3); }
.sa-filter-row select { flex: 1; min-width: 0; }
.sa-filter-row input { flex: 1; min-width: 0; }
.sa-filter-row > select:first-child { flex: 1.4; }
.sa-filter-is { color: var(--text-faint); font-size: var(--fs-sm); flex-shrink: 0; }
.sa-add-condition {
  border: 0;
  background: transparent;
  padding: 0;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--info);
  cursor: pointer;
}
.sa-struct-loose td { color: var(--text-faint); }


/* ---------------------------------------------------------------------------
   Scrollbars
   ---------------------------------------------------------------------------
   A scrollable region still scrolls; it just stops drawing a chrome scrollbar
   over the content. The tab strip was the visible offender — a stubby
   up/down scrollbar sat at the end of the row on a container that only ever
   scrolled by a pixel or two — but a wide table or a long dropdown had the
   same thing, and a scrollbar that appears for two pixels of overflow reads
   as a rendering fault rather than an affordance.

   Deliberately not `overflow: hidden`: content that genuinely overflows must
   still be reachable by wheel, trackpad, touch and keyboard. This hides the
   bar, not the scrolling. */
.sa-tabs,
.table-scroll,
.sa-body,
.sa-triggered-menu,
.finding-pages,
.sa-filter-panel,
.project-menu,
.sa-histogram {
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* old Edge */
}
.sa-tabs::-webkit-scrollbar,
.table-scroll::-webkit-scrollbar,
.sa-body::-webkit-scrollbar,
.sa-triggered-menu::-webkit-scrollbar,
.finding-pages::-webkit-scrollbar,
.sa-filter-panel::-webkit-scrollbar,
.project-menu::-webkit-scrollbar,
.sa-histogram::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* ==========================================================================
   On Page audit
   --------------------------------------------------------------------------
   Reuses the site audit's furniture wholesale — .sa-sticky, .sa-tabs,
   .sa-issue, .sa-issue-filters, .sa-chip, .sa-cmp-table, .sa-statlist,
   .gauge-half — so the two tools read as one product rather than two things
   that happen to share an app. Only what has no site-audit equivalent is
   defined here: the page hero, the two-column overview, the score-reasoning
   strip, and the issue detail view.

   The .sa-issue full-bleed margin/padding split is inherited deliberately.
   It took several passes to get the hover highlight running edge to edge
   without the text touching the card border, and re-deriving it on a second
   surface would have re-introduced the same problem.
   ========================================================================== */

/* ---- overview hero ---- */

.op-hero {
  padding: var(--s5) 0 var(--s6);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--s6);
}
.op-hero-url {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  word-break: break-all;
  margin-bottom: var(--s2);
}
.op-hero-url a { color: var(--text-dim); text-decoration: none; }
.op-hero-url a:hover { color: var(--brand); text-decoration: underline; }
.op-hero-score { display: flex; align-items: baseline; gap: 10px; }
.op-hero-n { font-size: 54px; font-weight: 680; line-height: 1; letter-spacing: -0.03em; }
.op-hero-n.good { color: var(--pass); }
.op-hero-n.mid  { color: var(--warn); }
.op-hero-n.bad  { color: var(--fail); }
.op-hero-n.none { color: var(--text-faint); }
.op-hero-of { font-size: var(--fs-base); color: var(--text-dim); }
.op-hero-sub { margin-top: 6px; font-size: var(--fs-sm); color: var(--text-faint); }

/* ---- two columns ----
   An explicit column pair, not `widget-grid cols-2`. The grid flows widgets
   row by row, which would have put the Ads score beside the SEO score and
   then the keyword card beside the issues chart — the user asked for things
   stacked *under* their own score, and that needs real columns. */
/* One grid holding both columns' cards interleaved, so each pair shares a row.

   `align-items: start` was the bug: it shrink-wraps every card to its own
   content, which is exactly what let the SEO card and the Ads card beside it
   end at different heights and knocked every boundary down the page out of
   line with its neighbour. The default `stretch` is what makes a row's cards
   equal, and equal rows are what make the two columns finish together. */
.op-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5);
}
.op-cols > .widget { min-width: 0; }
@media (max-width: 900px) { .op-cols { grid-template-columns: minmax(0, 1fr); } }

/* ---- score reasoning ---- */

.op-bands { margin-top: var(--s5); }
.op-bands-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-dim);
  margin-bottom: var(--s3);
}
.op-band-row {
  display: grid;
  grid-template-columns: 74px 1fr 44px;
  align-items: center;
  gap: 10px;
  margin-bottom: 7px;
  font-size: var(--fs-sm);
}
.op-band-name { color: var(--text-dim); }
.op-band-bar {
  height: 6px;
  border-radius: 999px;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  overflow: hidden;
}
.op-band-bar > span { display: block; height: 100%; background: var(--brand); }
.op-band-pct { text-align: right; font-weight: 600; }
.op-band-share {
  grid-column: 1 / -1;
  font-size: 12px;
  color: var(--text-faint);
  margin: -3px 0 6px 84px;
}

.op-ceilings {
  margin-top: var(--s4);
  padding: var(--s4);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--fail) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--fail) 24%, transparent);
  font-size: var(--fs-sm);
}
.op-ceilings ul { margin: 6px 0 0; padding-left: 18px; }
.op-ceilings li { margin-bottom: 3px; }

/* The rating strip that heads the SEO and Ads tabs. */
.op-strip {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: var(--s6);
  align-items: center;
}
.op-strip-gauge { display: flex; justify-content: center; }
.op-strip-body { min-width: 0; }
.op-strip-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  margin-bottom: 4px;
}
.op-strip-counts { font-size: var(--fs-sm); color: var(--text-dim); margin-bottom: var(--s4); }
@media (max-width: 720px) {
  .op-strip { grid-template-columns: 1fr; }
  .op-band-share { margin-left: 0; }
}

.op-filterbar { padding-top: var(--s4); padding-bottom: var(--s4); }

/* ---- findings ---- */

.op-issue { align-items: flex-start; }
.op-issue.quiet { opacity: 0.62; }
.op-issue-cat {
  flex: none;
  font-size: var(--fs-sm);
  color: var(--text-faint);
  white-space: nowrap;
  padding-top: 1px;
}

/* Severity is drawn by `sevIcon`, shared with the site audit, so the two
   tools mark the same thing the same way. The coloured dot that used to sit
   here carried STATUS in the same slot, which made a passing critical check
   read as a green error. Status is a word now — see `.op-status`. */
.op-issue > .sa-sev { margin-top: 2px; }

.op-status {
  font-size: 11px;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.op-status-pass { color: var(--pass); background: color-mix(in srgb, var(--pass) 14%, transparent); }
.op-status-warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 16%, transparent); }
.op-status-fail { color: var(--fail); background: color-mix(in srgb, var(--fail) 16%, transparent); }
.op-status-info { color: var(--text-dim); background: var(--bg-hover); }

.op-sev {
  font-size: 11px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.op-sev-critical { color: var(--fail); background: color-mix(in srgb, var(--fail) 16%, transparent); }
.op-sev-high     { color: var(--fail); background: color-mix(in srgb, var(--fail) 10%, transparent); }
.op-sev-medium   { color: var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent); }
.op-sev-low      { color: var(--text-dim); background: color-mix(in srgb, var(--text-dim) 12%, transparent); }

.op-tag {
  font-size: 11px;
  font-weight: 500;
  padding: 1px 7px;
  border-radius: 999px;
  color: var(--text-dim);
  background: var(--bg-hover);
  white-space: nowrap;
}
.op-tag-warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent); }

/* ---- issue detail view ---- */

.op-detail-rec {
  margin: var(--s4) 0 0;
  padding: var(--s4);
  border-left: 3px solid var(--brand);
  background: var(--bg-panel-2);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: var(--fs-base);
}
.op-detail-value {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: var(--s5);
}
.op-detail-value-n { font-size: 34px; font-weight: 650; line-height: 1; }
.op-detail-kv {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
  margin-top: var(--s5);
}
.op-detail-kv > div {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  font-size: var(--fs-sm);
}
.op-detail-kv span { color: var(--text-dim); }
.op-detail-kv b { font-weight: 600; }

.op-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s6);
  margin-top: var(--s6);
  padding-top: var(--s6);
  border-top: 1px solid var(--border);
}
@media (max-width: 860px) { .op-detail-grid { grid-template-columns: 1fr; } }
.op-detail-block h5 {
  margin: 0 0 8px;
  font-size: var(--fs-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}
.op-detail-block p { margin: 0 0 8px; font-size: var(--fs-sm); line-height: 1.65; color: var(--text-dim); }
.op-detail-block ol { margin: 0; padding-left: 18px; }
.op-detail-block li { font-size: var(--fs-sm); line-height: 1.65; margin-bottom: 6px; }
.op-detail-meta { color: var(--text-faint) !important; }
.op-detail-meta span { color: var(--text-dim); }

.op-detail-items { margin-top: var(--s6); }
.op-detail-items h5 {
  margin: 0 0 8px;
  font-size: var(--fs-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}
.op-detail-items ul {
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: 320px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.op-detail-items li {
  padding: 7px 11px;
  border-bottom: 1px solid var(--border);
  word-break: break-all;
}
.op-detail-items li:last-child { border-bottom: 0; }
.op-detail-source {
  margin: var(--s6) 0 0;
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
  font-size: var(--fs-sm);
  color: var(--text-faint);
}
.op-detail-source a { color: var(--info); }

/* ---- keywords ---- */

.op-kw-headline { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4); }
.op-kw-term { font-size: var(--fs-lg); font-weight: 600; word-break: break-word; }
.op-kw-score { font-size: 30px; font-weight: 650; line-height: 1; white-space: nowrap; }
.op-kw-score small { font-size: var(--fs-sm); color: var(--text-faint); font-weight: 400; }

.op-placements {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: 6px;
  margin-top: var(--s4);
}
.op-placement {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  font-size: var(--fs-sm);
}
.op-placement span { color: var(--text-dim); }
.op-placement b { color: var(--fail); font-weight: 600; }
.op-placement.hit { border-color: color-mix(in srgb, var(--pass) 40%, var(--border)); }
.op-placement.hit b { color: var(--pass); }
.op-kw-coverage { margin-top: 8px; font-size: var(--fs-sm); color: var(--warn); line-height: 1.5; }
.op-kw-secondaries { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s4); }
.op-kw-chip {
  font-size: var(--fs-sm);
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-panel-2);
  color: var(--text-dim);
}
.op-kw-chip.on { border-color: color-mix(in srgb, var(--pass) 40%, var(--border)); color: var(--text); }
.op-kw-chip b { font-weight: 600; margin-left: 4px; }

/* ---- tables ---- */

.op-yes { color: var(--pass); font-weight: 500; }
.op-no  { color: var(--text-faint); }
.op-up   { color: var(--pass); font-weight: 600; }
.op-down { color: var(--fail); font-weight: 600; }
.op-flat { color: var(--text-faint); }
.op-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--text-dim); }
.op-track-note { display: block; margin-top: 3px; color: var(--text-faint); font-family: inherit; font-size: 12px; }
.op-url { max-width: 360px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.op-row.clickable { cursor: pointer; }
.op-row.clickable:hover { background: var(--bg-hover); }
.op-row.on { background: color-mix(in srgb, var(--brand) 8%, transparent); }
.op-pages-table td { vertical-align: middle; }

.op-cell {
  font-size: 12px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  text-transform: capitalize;
}
.op-cell-pass { color: var(--pass); background: color-mix(in srgb, var(--pass) 14%, transparent); }
.op-cell-warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent); }
.op-cell-fail { color: var(--fail); background: color-mix(in srgb, var(--fail) 14%, transparent); }
.op-cell-info { color: var(--info); background: color-mix(in srgb, var(--info) 14%, transparent); }

.op-cmp-summary {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  padding: var(--s4) 0 0;
  line-height: 1.6;
}

/* ---- statistics bars ---- */

.op-statbars { margin-top: var(--s4); }
.op-statbar {
  display: grid;
  grid-template-columns: 1fr 90px 52px;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  font-size: var(--fs-sm);
}
.op-statbar-l { color: var(--text-dim); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.op-statbar-track {
  height: 6px;
  border-radius: 999px;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  overflow: hidden;
}
.op-statbar-track > span { display: block; height: 100%; }
.op-statbar-n { text-align: right; font-weight: 600; }

/* ---- method ---- */

.op-method-prose p { margin: 0 0 var(--s4); font-size: var(--fs-sm); line-height: 1.7; color: var(--text-dim); }
.op-method-prose ul { margin: 0 0 var(--s4); padding-left: 18px; }
.op-method-prose li { font-size: var(--fs-sm); line-height: 1.7; color: var(--text-dim); margin-bottom: 4px; }
.op-method-prose strong { color: var(--text); }
.op-method-list { font-size: 12px; color: var(--text-faint); line-height: 1.6; }

.op-nonchecks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--s4);
}
.op-noncheck {
  padding: var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
}
.op-noncheck-topic { font-weight: 600; font-size: var(--fs-sm); margin-bottom: 5px; }
.op-noncheck-why { font-size: var(--fs-sm); color: var(--text-dim); line-height: 1.6; }
.op-noncheck-src { display: inline-block; margin-top: 8px; font-size: var(--fs-sm); color: var(--info); }

@media (max-width: 720px) {
  .op-hero-n { font-size: 40px; }
  .op-url { max-width: 190px; }
  .op-issue-cat { display: none; }
}

/* ==========================================================================
   Spacing corrections
   --------------------------------------------------------------------------
   Four defects found by measuring the rendered page at 390px rather than by
   looking at it, which is how three of them had survived this long.
   ========================================================================== */

/* 1. Table cells had NO left padding, so the first column's text sat hard
      against the border of the scroll box containing it.

      The cause was three competing `.data-table td` rules across the
      stylesheet — 9px 12px, then 9px 10px 9px 0, then 12px 12px 12px 0 — with
      the last one winning. A zero left edge is right for a BORDERLESS table
      sitting directly in a card, where the first column should line up with
      the card's own text column. It is wrong the moment the table is inside
      `.table-scroll`, which draws a border and a background around it.

      So the fix is scoped to that container rather than changing the base
      rule: a bordered box gets breathing room on both edges, and a borderless
      table keeps the flush alignment it was designed for. `.num` cells zero
      their right padding for the same reason and need it back here too, or
      the last column touches the opposite border. */
.table-scroll .data-table th,
.table-scroll .data-table td { padding-left: var(--s3); }
.table-scroll .data-table th:last-child,
.table-scroll .data-table td:last-child { padding-right: var(--s3); }
.table-scroll .data-table th.num,
.table-scroll .data-table td.num { padding-right: var(--s3); }

@media (max-width: 720px) {
  /* 2. `.sa-meta-actions` carries `margin-left: auto` to push the buttons to
        the right of the meta row. When that row wraps on a narrow screen the
        button group lands on its own line and `auto` distributes the leftover
        space as a left indent — measured at 55.7px — so the buttons appeared
        arbitrarily pushed in from the edge. On its own line it should simply
        start at the left. */
  .sa-meta-actions { margin-left: 0; width: 100%; flex-wrap: wrap; }

  /* 3. Eight tabs wrapped onto three rows, which buried the content and made
        the strip read as three unrelated groups. A single horizontally
        scrollable strip is what a phone expects, and it keeps the tab order
        legible as one sequence. Scrollbar hidden because the strip's own
        overflow is the affordance. */
  .sa-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .sa-tabs::-webkit-scrollbar { display: none; }
  .sa-tab { flex: none; }

  /* 4. On a 390px screen the card was spending 40px of the 390 on its own
        padding before any content, and a full-bleed issue row spent another
        64px on its inset. Both are correct at desktop width and simply too
        generous here. Driving them through the tokens keeps the full-bleed
        rows in sync — `.sa-issue` computes its negative margin from
        `--card-pad`, so changing the padding alone would have knocked the
        hover highlight out of alignment with the card edge. */
  :root {
    --card-pad: var(--s4);
    --issue-inset: var(--s5);
  }
}

/* Explainer panels ("How it works"), rendered inside the shared modal. */
.zw-panel-body .op-method-prose p:last-child { margin-bottom: 0; }
.zw-panel-body .op-method-prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
}

/* A row in the Overview's "Fix these first" list. Same anatomy as an issue row
   on the SEO tab — deliberately, since it is the same object — but it carries
   the recommendation rather than the finding message, because at a glance the
   useful half is what to DO, not what was measured. */
.op-fixrow .kpi-sub { line-height: 1.5; }

/* ---- SEO / Ads tab: rating on the left, findings on the right ------------
   The rating card was full width and mostly empty — a gauge, three bars, and
   a wide stretch of nothing beside them — which pushed the findings, the
   actual reason for the tab, below the fold on every screen. Splitting it
   fixes both halves at once: the rating gets a column it fills, the findings
   get the vertical room they need, and the rating stays visible while you
   read down the list.

   `align-items: start` plus `position: sticky` is what keeps the left column
   pinned; without the former the grid stretches the item to full row height
   and sticky has nothing to move within. */
.op-seo-cols {
  display: grid;
  grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
  gap: var(--s5);
  align-items: start;
}
.op-seo-aside { position: sticky; top: calc(var(--topbar-h) + var(--sa-sticky-h, 92px) + var(--s4)); }
.op-seo-main { display: flex; flex-direction: column; gap: var(--s5); min-width: 0; }

/* In a narrow column the gauge sits above its explanation rather than beside
   it, and the "How it works" link moves under the title where it has room. */
.op-seo-aside .op-strip { grid-template-columns: 1fr; gap: var(--s4); }
.op-seo-aside .op-strip-head { flex-wrap: wrap; }

@media (max-width: 1100px) {
  .op-seo-cols { grid-template-columns: 1fr; }
  .op-seo-aside { position: static; }
  .op-seo-aside .op-strip { grid-template-columns: 200px 1fr; }
}
@media (max-width: 720px) {
  .op-seo-aside .op-strip { grid-template-columns: 1fr; }
}

/* The previews the old single-page report still owns. Its own panel chrome is
   redundant inside a card that already has a header. */
.report-host .panel {
  border: 0;
  background: none;
  padding: 0;
  margin: 0;
}
.report-host .actions-row { margin-top: var(--s4); }

/* ---- Issues vs Full audit, and the deduction ledger --------------------- */

/* The Issues / Full audit toggle lived here and is gone. It showed the same
   list with a different filter on, which the status dropdown already does —
   and "full audit" turned out to mean something else entirely: the page's own
   title, headings and images, which is now the Elements tab. */

/* The ledger. Deliberately reads like one: a starting figure, subtractions,
   a total. A ceiling is stated after it and outside it, because it overrides
   the total rather than being another line in it. */
.op-ded { margin-top: var(--s5); }
.op-ded-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-dim);
  margin-bottom: var(--s3);
}
.op-ded-rows { border-top: 1px solid var(--border); }
.op-ded-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  font-size: var(--fs-sm);
  border-bottom: 1px solid var(--border);
}
.op-ded-row span { color: var(--text-dim); min-width: 0; }
.op-ded-row em { font-style: normal; color: var(--text-faint); font-size: 12px; }
.op-ded-row b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.op-ded-minus { color: var(--fail); }
.op-ded-start span, .op-ded-start b { color: var(--text-faint); }
.op-ded-item { cursor: pointer; }
.op-ded-item:hover { background: var(--bg-hover); }
.op-ded-item:hover span { color: var(--text); }
.op-ded-rest span { color: var(--text-faint); }
.op-ded-total { border-bottom: 0; padding-top: 9px; }
.op-ded-total span, .op-ded-total b { color: var(--text); font-weight: 600; }
.op-ded-ceiling {
  margin: var(--s3) 0 0;
  padding: var(--s3);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--fail) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--fail) 22%, transparent);
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--text-dim);
}

/* ---- "how this page is now" evidence on an issue's own page ------------- */

.op-ev {
  margin-top: var(--s6);
  padding-top: var(--s5);
  border-top: 1px solid var(--border);
}
.op-ev h5 {
  margin: 0 0 var(--s3);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}
.op-ev-note { margin: var(--s3) 0 0; font-size: var(--fs-sm); color: var(--text-faint); }
.op-ev-text {
  padding: var(--s4);
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  font-size: var(--fs-base);
  line-height: 1.55;
  overflow-wrap: anywhere;
}
.op-ev-meta { margin-top: 6px; font-size: var(--fs-sm); color: var(--text-faint); }
.op-ev-list { margin: 0; padding: 0; list-style: none; border: 1px solid var(--border); border-radius: var(--radius-sm); max-height: 340px; overflow: auto; }
.op-ev-list li { padding: 7px 11px; border-bottom: 1px solid var(--border); overflow-wrap: anywhere; font-size: var(--fs-sm); }
.op-ev-list li:last-child { border-bottom: 0; }
.op-ev-list.mono li { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--text-dim); }

.op-ev-figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--s3); }
.op-ev-figures > div {
  padding: var(--s4);
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
}
.op-ev-figures span { display: block; font-size: 26px; font-weight: 650; line-height: 1.1; }
.op-ev-figures b { display: block; margin-top: 3px; font-size: var(--fs-sm); font-weight: 400; color: var(--text-dim); }

.op-ev-kv { display: grid; gap: 6px; }
.op-ev-kv > div { display: flex; justify-content: space-between; gap: 12px; padding: 8px 11px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-panel-2); font-size: var(--fs-sm); }
.op-ev-kv span { color: var(--text-dim); flex: none; }
.op-ev-kv b { font-weight: 500; text-align: right; overflow-wrap: anywhere; }

.op-ev-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.op-ev-chip { font-size: var(--fs-sm); padding: 3px 10px; border-radius: 999px; background: var(--bg-panel-2); border: 1px solid var(--border); color: var(--text-dim); }
.op-ev-chip b { color: var(--text); margin-left: 4px; }

/* The document outline, indented by level, with the jumps called out where
   they happen — the point being that "skips levels in 5 places" is a claim,
   and this is the evidence for it. */
.op-outline { border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; max-height: 420px; overflow-y: auto; }
.op-outline-row { display: flex; align-items: baseline; gap: 8px; padding: 6px 11px; border-bottom: 1px solid var(--border); font-size: var(--fs-sm); }
.op-outline-row:last-child { border-bottom: 0; }
.op-outline-row.skip { background: color-mix(in srgb, var(--warn) 9%, transparent); }
.op-outline-tag { flex: none; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; font-weight: 600; color: var(--text-faint); width: 22px; }
.op-outline-row.skip .op-outline-tag { color: var(--warn); }
.op-outline-text { color: var(--text-dim); overflow-wrap: anywhere; }
.op-outline-flag { margin-left: auto; flex: none; font-size: 11px; font-weight: 600; color: var(--warn); white-space: nowrap; }

/* Severity and status belong together beside the title, not spread across the
   row by the header's `justify-content`. Only "How to fix" pushes right. */
.op-idt-pills { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sa-idt-head .sa-howto { margin-left: auto; }

/* ---- evidence tables, paging, and the fuller issue detail --------------- */

/* The alt column is the point of this table, so the URL is the one that
   truncates. Full path on hover; the filename identifies an image to a person
   anyway, and a WordPress upload path is mostly noise. */
.op-ev-table { table-layout: fixed; width: 100%; }
/* The image column is the widest: a filename plus its path needs the room, and
   alt text is usually a short phrase. Loading takes only a word. */
.op-ev-table th:nth-child(1), .op-ev-src { width: 52%; }
.op-ev-table th:nth-child(2), .op-ev-alt { width: 34%; }
.op-ev-table th:nth-child(3), .op-ev-narrow { width: 96px; }
.op-ev-src { overflow: hidden; }
.op-ev-srcline { display: flex; align-items: center; gap: 6px; min-width: 0; }
.op-ev-open {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-sm);
  color: var(--text-faint);
  border: 1px solid transparent;
}
.op-ev-open:hover { color: var(--info); background: var(--bg-hover); border-color: var(--border); }
.op-ev-open:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.op-ev-file {
  display: block;
  min-width: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.op-ev-path {
  display: block;
  font-size: 11px;
  color: var(--text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  direction: rtl;
  text-align: left;
}
.op-ev-alt { overflow-wrap: anywhere; line-height: 1.5; }
.op-ev-emptyalt { color: var(--text-faint); font-style: italic; }
.op-ev-bad td { background: color-mix(in srgb, var(--fail) 7%, transparent); }

.op-pager {
  display: flex;
  align-items: center;
  gap: var(--s4);
  flex-wrap: wrap;
  margin-top: var(--s3);
  font-size: var(--fs-sm);
  color: var(--text-faint);
}
.op-pager-rows, .op-pager-nav { display: flex; align-items: center; gap: 4px; }
.op-pager-nav { margin-left: auto; }
.op-pager-of { padding: 0 6px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.op-pagebtn {
  font: inherit;
  font-size: 12.5px;
  min-width: 28px;
  padding: 3px 9px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--bg-panel-2);
  color: var(--text-dim);
  cursor: pointer;
}
.op-pagebtn:hover:not([disabled]) { background: var(--bg-hover); color: var(--text); }
.op-pagebtn.on { background: var(--brand); border-color: var(--brand); color: var(--brand-text); }
.op-pagebtn[disabled] { opacity: 0.4; cursor: default; }

.op-detail-impact {
  margin: var(--s5) 0 0;
  padding: var(--s4);
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--text-dim);
}
.op-detail-impact strong { color: var(--text); font-size: var(--fs-base); }
.op-detail-impact.quiet { background: none; border-style: dashed; color: var(--text-faint); }
.op-detail-impact-cap {
  display: block;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  color: var(--fail);
}
.op-detail-impact-cap strong { color: var(--fail); }

.op-detail-related { margin-top: var(--s6); }
.op-detail-related h5 {
  margin: 0 0 var(--s3);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}
.op-related-rows { display: flex; flex-wrap: wrap; gap: 6px; }
.op-related {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font: inherit;
  font-size: var(--fs-sm);
  padding: 5px 12px 5px 8px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-panel-2);
  color: var(--text-dim);
  cursor: pointer;
}
.op-related:hover { background: var(--bg-hover); color: var(--text); }

/* An audit stored before a check learned to list its items. Dashed rather than
   solid: this is an absence being explained, not a finding. */
.op-ev-stale {
  border-top-style: dashed;
}
.op-ev-stale p {
  margin: 0 0 var(--s4);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--text-faint);
  max-width: 70ch;
}

/* ---- Elements: what the page actually contains ------------------------- */

.op-el-row { padding: var(--s4) 0; border-bottom: 1px solid var(--border); }
.op-el-row:first-child { padding-top: 0; }
.op-el-row:last-child { border-bottom: 0; padding-bottom: 0; }
.op-el-head {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  flex-wrap: wrap;
  margin-bottom: 7px;
}
.op-el-label {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.op-el-meta { font-size: var(--fs-sm); color: var(--text-faint); }
.op-el-status { margin-left: auto; border: 0; background: none; padding: 0; cursor: pointer; }
.op-el-status:hover { filter: brightness(1.15); }
.op-el-status:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 999px; }

/* The value itself is the point of this tab, so it gets the weight — a real
   reading size on a panel, not a dimmed caption under a label. */
.op-el-value {
  padding: var(--s4);
  border-radius: var(--radius-sm);
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  font-size: var(--fs-base);
  line-height: 1.55;
  overflow-wrap: anywhere;
}
.op-el-value.none { color: var(--text-faint); font-style: italic; }

/* ---- SEO sub-views: Issues / Elements / Appearance ----------------------
   Pills, not another underlined tab row. The main bar is already underlined
   tabs, and a second identical bar under it reads as one confused navigation
   rather than a hierarchy. */
.op-subtabs {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
  margin-bottom: var(--s5);
}
.op-subtab {
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: 6px 15px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-panel);
  color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
}
.op-subtab:hover { background: var(--bg-hover); color: var(--text); }
.op-subtab.on { background: var(--brand); border-color: var(--brand); color: var(--brand-text); }
.op-subtab:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.op-subtab-n { opacity: 0.75; font-weight: 500; margin-left: 3px; }
.op-subtab-hint {
  font-size: var(--fs-sm);
  color: var(--text-faint);
  margin-left: var(--s2);
  min-width: 0;
}
@media (max-width: 720px) { .op-subtab-hint { flex-basis: 100%; margin-left: 0; } }

/* A fatal finding replaces the ledger rather than heading it — there is no
   arithmetic to show when the answer is a multiplication by zero. */
.op-ded-fatal { display: grid; gap: 8px; }
.op-ded-fatalrow {
  font: inherit;
  text-align: left;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--text-dim);
  padding: var(--s4);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--fail) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--fail) 26%, transparent);
  cursor: pointer;
}
.op-ded-fatalrow:hover { background: color-mix(in srgb, var(--fail) 14%, transparent); }
.op-ded-fatalrow strong { color: var(--fail); }

/* ── Suggestions: measured, never scored ────────────────────────────────────
   Visually distinct from an issue row on purpose. Issues carry a severity
   colour and a point cost; nothing here does, and borrowing the same red and
   amber would teach people these are faults to clear when they are prompts to
   read. Neutral ink, one accent on the measurement itself. */
.op-subtab-n.quiet {
  opacity: 0.55;
  font-weight: 500;
}
.op-sg-intro .kpi-sub { margin: 0; max-width: 78ch; }
.op-sg { display: grid; gap: 12px; }
.op-sg-measure {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--surface-2, color-mix(in srgb, currentColor 5%, transparent));
  border-left: 3px solid color-mix(in srgb, var(--accent, #6366f1) 55%, transparent);
}
.op-sg-num { font-weight: 600; font-size: 0.95rem; }
.op-sg-thresh { font-size: 0.82rem; opacity: 0.7; }
.op-sg-body { margin: 0; max-width: 78ch; line-height: 1.55; }
.op-sg-items { display: grid; gap: 6px; }
.op-sg-items-head {
  font-size: 0.76rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.6;
  margin-bottom: 2px;
}
.op-sg-item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--surface-2, color-mix(in srgb, currentColor 4%, transparent));
}
/* The offending text can be long; it wraps, the count never does. */
.op-sg-item-text { min-width: 0; line-height: 1.5; }
.op-sg-item-note {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  opacity: 0.7;
  white-space: nowrap;
}
.op-sg-more { font-size: 0.82rem; opacity: 0.6; padding: 2px 12px; }
.op-sg-source { margin: 0; font-size: 0.84rem; opacity: 0.8; line-height: 1.6; }

@media (max-width: 640px) {
  .op-sg-item { flex-direction: column; gap: 4px; }
  .op-sg-item-note { align-self: flex-start; }
}

/* Language switcher in the rail. Text rather than a flag: a flag stands for a
   country, not a language, and Bahasa Indonesia is not the flag of Indonesia
   any more than English is the flag of England. */
.rail-lang {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  border: 1.5px solid currentColor;
  border-radius: 5px;
  line-height: 1;
}

/* ── Account button and panel ────────────────────────────────────────────────
   The header avatar doubles as the way in when signed out, so it has to read
   as a control rather than as a portrait of somebody already logged in. */
.avatar.signin-cta {
  width: auto;
  padding: 0 14px;
  border-radius: 8px;
  background: var(--brand, #1C46F2);
  color: #fff;
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0;
}
.avatar.signin-cta:hover { background: #163BD0; }

.auth-me {
  padding: 12px 14px;
  border: 1px solid var(--line, #E3E6EF);
  border-radius: 9px;
  margin-bottom: 14px;
}
.auth-me-email { font-weight: 500; word-break: break-all; }
.auth-me-plan { font-size: 0.82rem; opacity: 0.7; margin-top: 2px; }
.auth-hint { font-size: 0.82rem; opacity: 0.75; margin: 0 0 14px; line-height: 1.5; }
.auth-wide { width: 100%; }
