/*
  Perimeter dashboard stylesheet.

  One hand-written sheet, no framework. Three type families each tied to a job:
  - Space Grotesk for headings/wordmark (a little technical, not a workhorse face)
  - Public Sans for prose/UI chrome (readable at small sizes, plain)
  - IBM Plex Mono for anything literal: hostnames, IPs, ports, fingerprints, timestamps
    (unambiguous 0/O and 1/l/I glyphs matter when you're reading a scan result)

  Color communicates severity, not brand. The palette itself stays quiet (ink/slate/paper);
  the five severity hues are the only saturated color on the page, and they are reserved
  for that single meaning everywhere they appear (bars, chips, left borders, sparkline).
*/

/*
  Self-hosted fonts (the same files as site/assets/fonts, OFL licences alongside): the
  dashboard's CSP allows no third-party stylesheet or font. Weights with no file here
  (Space Grotesk 500, Public Sans 500, IBM Plex Mono 600) fall back to the nearest one the
  browser's weight matching picks (600, 400 and 500).
*/
@font-face { font-family: "Space Grotesk"; font-weight: 600; font-display: swap; src: url("fonts/space-grotesk-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-weight: 700; font-display: swap; src: url("fonts/space-grotesk-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "Public Sans"; font-weight: 400; font-display: swap; src: url("fonts/public-sans-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Public Sans"; font-weight: 600; font-display: swap; src: url("fonts/public-sans-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 400; font-display: swap; src: url("fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 500; font-display: swap; src: url("fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2"); }

:root {
  accent-color: var(--accent);
  --bg: #f3f5f3;
  --surface: #ffffff;
  --surface-alt: #eaede9;
  --ink: #14191b;
  --ink-muted: #57636a;
  --ink-faint: #606b72;
  --border: #d7ddd8;
  --border-strong: #b9c2bc;
  --accent: #17646d;
  --accent-ink: #ffffff;
  --focus-ring: #1f8b96;

  --sev-critical: #a3241c;
  --sev-high: #b5480f;
  --sev-medium: #92620a;
  --sev-low: #3c6b2c;
  --sev-info: #47576b;

  --sev-critical-bg: #fbeae8;
  --sev-high-bg: #fcede2;
  --sev-medium-bg: #fbf1de;
  --sev-low-bg: #eaf1e6;
  --sev-info-bg: #eaedf1;

  --font-display: 'Space Grotesk', 'Segoe UI', sans-serif;
  --font-body: 'Public Sans', 'Segoe UI', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, Consolas, monospace;

  --radius: 6px;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2.25rem;
  --space-7: 3.5rem;

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #10161a;
    --surface: #182027;
    --surface-alt: #1c252c;
    --ink: #e7edf0;
    --ink-muted: #a0adb4;
    --ink-faint: #808d95;
    --border: #2b363e;
    --border-strong: #3c4a53;
    --accent: #4fb6bf;
    --accent-ink: #08181a;
    --focus-ring: #4fb6bf;

    --sev-critical: #e6685c;
    --sev-high: #e39257;
    --sev-medium: #d3ac53;
    --sev-low: #82b56c;
    --sev-info: #92a3b6;

    --sev-critical-bg: #2c1a19;
    --sev-high-bg: #2c2118;
    --sev-medium-bg: #2b2416;
    --sev-low-bg: #1c2818;
    --sev-info-bg: #1c2228;

    color-scheme: dark;
  }
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

a {
  color: var(--accent);
  text-underline-offset: 0.15em;
}

::selection {
  background: var(--accent);
  color: var(--accent-ink);
}


a:visited {
  color: var(--accent);
}

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.2;
  margin: 0 0 var(--space-3);
}

h1 { font-size: 1.7rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }

p {
  margin: 0 0 var(--space-3);
  max-width: 68ch;
}

.mono {
  font-family: var(--font-mono);
}

/* ---------- shell ---------- */

.shell-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

.wordmark {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  text-decoration: none;
  color: var(--ink);
}

.wordmark strong {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.wordmark span {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-faint);
}

.shell-nav {
  display: flex;
  gap: var(--space-4);
}

.shell-nav a {
  text-decoration: none;
  color: var(--ink-muted);
  font-weight: 500;
  padding: var(--space-1) 0;
  border-bottom: 2px solid transparent;
}

.shell-nav a:hover,
.shell-nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

.shell-main {
  max-width: 980px;
  margin: 0 auto;
  padding: var(--space-5);
}

.shell-footer {
  max-width: 980px;
  margin: 0 auto;
  padding: var(--space-5);
  color: var(--ink-faint);
  font-size: 0.8rem;
}

/* ---------- flash / notices ---------- */

.notice {
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--sev-medium);
  background: var(--surface);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  margin-bottom: var(--space-4);
}

.notice.notice-error {
  border-left-color: var(--sev-critical);
}

/* ---------- scan form ---------- */

.scan-form {
  display: flex;
  gap: var(--space-2);
  align-items: stretch;
  margin-bottom: var(--space-6);
}

.scan-form input[type="text"] {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
}

button, .btn {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1.3;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius);
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

button:hover, .btn:hover {
  filter: brightness(1.08);
}

.btn-quiet {
  background: transparent;
  color: var(--ink);
  border-color: var(--border-strong);
}

.btn-quiet:hover {
  background: var(--surface-alt);
  filter: none;
}

/* ---------- domain card grid ---------- */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.domain-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: var(--space-4);
  text-decoration: none;
  color: inherit;
  display: block;
}

.domain-card:hover {
  border-color: var(--border-strong);
  box-shadow: 0 2px 8px -4px rgba(20, 25, 27, 0.18);
}

.domain-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.domain-card-head h3 {
  font-family: var(--font-mono);
  font-size: 1rem;
  margin: 0;
  word-break: break-all;
}

.badge {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  color: var(--ink-muted);
  white-space: nowrap;
}

.badge-watch {
  border-color: var(--accent);
  color: var(--accent);
}

.domain-card-meta {
  color: var(--ink-faint);
  font-size: 0.82rem;
  margin-bottom: var(--space-1);
}

.domain-card-change {
  font-size: 0.82rem;
  color: var(--ink-muted);
  margin-top: var(--space-2);
}

.empty-note {
  color: var(--ink-faint);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  padding: var(--space-4);
}

.watched-unscanned {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-2);
  background: var(--surface);
}

.watched-unscanned .mono {
  font-size: 0.95rem;
}

.domain-card-score { display: flex; gap: 0.2rem; align-items: baseline; min-height: 2.25rem; margin: var(--space-3) 0 var(--space-1); font-variant-numeric: tabular-nums; }
.domain-card-number { font-family: var(--font-display); font-size: 2.25rem; font-weight: 700; line-height: 1; letter-spacing: -0.02em; }
.domain-card-max { color: var(--ink-muted); font-weight: 600; }
.domain-card-noscore { align-self: center; color: var(--ink-muted); font-weight: 600; }
.domain-card-issues { margin: var(--space-3) 0 var(--space-1); padding-top: var(--space-3); border-top: 1px solid var(--border); font-size: 0.9rem; font-weight: 500; }

/* ---------- sparkline ---------- */

.sparkline {
  width: 100%;
  height: 32px;
  display: block;
  overflow: visible;
}

.sparkline polyline {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
}

.sparkline polyline { stroke-linecap: round; stroke-linejoin: round; }

/* ---------- domain page ---------- */

.domain-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

.domain-head h1 {
  font-family: var(--font-mono);
  word-break: break-all;
}

.domain-head-actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
}

.history-strip {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  padding: var(--space-3) 0;
  margin-bottom: var(--space-5);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
}

.history-tick {
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 999px;
  background: var(--border-strong);
  display: inline-block;
  flex: none;
}

.history-tick.is-current {
  width: 0.9rem;
  height: 0.9rem;
  background: var(--accent);
}

.history-tick-link {
  text-decoration: none;
  display: inline-flex;
}

.report-section {
  border-top: 1px solid var(--border);
  padding: var(--space-5) 0;
}

.report-section:first-of-type {
  border-top: none;
  padding-top: 0;
}

.section-note {
  color: var(--ink-faint);
  font-size: 0.85rem;
}

.kv-list {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.35rem var(--space-4);
  font-size: 0.9rem;
}

.kv-list dt {
  color: var(--ink-muted);
}

.kv-list dd {
  margin: 0;
  font-family: var(--font-mono);
  word-break: break-word;
}

.tag {
  display: inline-block;
  font-size: 0.72rem;
  padding: 0.05rem 0.4rem;
  border-radius: 4px;
  background: var(--surface-alt);
  color: var(--ink-muted);
  margin-right: 0.3rem;
}

/* ---------- severity chips ---------- */

.sev-chip {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
}

.sev-chip.sev-critical { color: var(--sev-critical); background: var(--sev-critical-bg); }
.sev-chip.sev-high { color: var(--sev-high); background: var(--sev-high-bg); }
.sev-chip.sev-medium { color: var(--sev-medium); background: var(--sev-medium-bg); }
.sev-chip.sev-low { color: var(--sev-low); background: var(--sev-low-bg); }
.sev-chip.sev-info { color: var(--sev-info); background: var(--sev-info-bg); }

/* ---------- change timeline ---------- */

.change-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.change-item {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  font-size: 0.88rem;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.change-item .sev-chip {
  flex: none;
}

/* ---------- scanning partial ---------- */

.scanning-panel {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
  background: var(--surface-alt);
  margin-bottom: var(--space-5);
}

.scanning-dot {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 999px;
  background: var(--accent);
  animation: pulse 1.4s ease-in-out infinite;
  flex: none;
}

@keyframes pulse {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

.scanning-error {
  border-left: 3px solid var(--sev-critical);
}

/* ---------- watches table ---------- */

.watch-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
  margin-bottom: var(--space-6);
}

.watch-table th, .watch-table td {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
}

.watch-table th {
  color: var(--ink-muted);
  font-weight: 500;
  font-size: 0.8rem;
}

.watch-table td.mono {
  font-size: 0.85rem;
}

.watch-actions {
  display: flex;
  gap: var(--space-2);
}

.watch-actions form {
  margin: 0;
}

.watch-actions button, .watch-actions .btn {
  padding: 0.3rem 0.7rem;
  font-size: 0.8rem;
}

.status-dot {
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 999px;
  margin-right: 0.4rem;
  background: var(--ink-faint);
}

.status-dot.is-enabled {
  background: var(--sev-low);
}

.add-watch-form {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}

.add-watch-form input[type="text"] {
  font-family: var(--font-mono);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
}

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

.alert-row {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-3);
  font-size: 0.85rem;
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
}

.alert-row .mono {
  color: var(--ink-faint);
  font-size: 0.78rem;
}

/* ---------- not found ---------- */

.not-found {
  text-align: left;
  padding: var(--space-6) 0;
}

/* ---------- responsive ---------- */

@media (max-width: 640px) {
  .shell-header {
    flex-wrap: wrap;
    padding: var(--space-3) var(--space-4);
  }

  .wordmark {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }

  .wordmark span {
    font-size: 0.72rem;
  }

  .shell-main {
    padding: var(--space-4);
  }

  .scan-form {
    flex-direction: column;
  }

  .domain-head {
    flex-direction: column;
  }

  .kv-list {
    grid-template-columns: 1fr;
  }

  .watch-table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }
}

/* ---------- history block ---------- */
.history {
  margin: var(--space-4) 0 var(--space-5);
}
.history-caption {
  color: var(--ink-muted);
  font-size: 0.85rem;
  margin-bottom: var(--space-3);
  max-width: 68ch;
}
/* Fixed 0-100 scale with 0/50/100 guides, so a small change reads as small. The line is
   inset by half a tick so each point sits above its dot in the strip below. */
.history-chart {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-2);
}
.history-axis {
  grid-row: 1;
  grid-column: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  margin: -0.5em 0;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1;
  color: var(--ink-faint);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.history .sparkline {
  grid-row: 1;
  grid-column: 2;
  display: block;
  width: calc(100% - 22px);
  height: 96px;
  margin: 0 11px;
}
.sparkline .sparkline-guide {
  stroke: var(--border);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.sparkline .sparkline-guide.is-mid {
  stroke-dasharray: 3 4;
}
.sparkline polyline.is-dot {
  stroke-width: 8;
}
.history .history-strip {
  grid-row: 2;
  grid-column: 2;
  display: flex;
  justify-content: space-between;
  margin: var(--space-2) 0 0;
  padding: 0;
  border: 0;
}
.history-tick-link {
  display: inline-flex;
  padding: var(--space-1);
}
.history-tick {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: var(--surface);
  display: inline-block;
}
.history-tick.is-partial {
  border-style: dashed;
}
.history-tick.is-current {
  background: var(--accent);
  border-color: var(--accent);
}
.history-tick-link:hover .history-tick {
  border-color: var(--accent);
}

/* ---------- quieter trailing sections, tags with meaning ---------- */
.tag-danger {
  color: var(--sev-critical);
  border-color: var(--sev-critical);
}
.tag-warn {
  color: var(--sev-medium);
  border-color: var(--sev-medium);
}

/* ---------- watches ---------- */
.add-watch-form {
  flex-wrap: wrap;
}
.channel-picks {
  display: inline-flex;
  gap: var(--space-3);
  align-items: center;
}
.channel-pick {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  white-space: nowrap;
}
.alert-status {
  display: inline-block;
  padding: 0 var(--space-2);
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  margin-right: var(--space-1);
}
.alert-status.alert-sent { color: var(--sev-low); background: var(--sev-low-bg); }
.alert-status.alert-failed { color: var(--sev-critical); background: var(--sev-critical-bg); }
.alert-status.alert-skipped { color: var(--ink-muted); background: var(--surface-alt); }
.alert-meta {
  color: var(--ink-muted);
  font-size: 0.85rem;
}
@media (max-width: 640px) {
  .watch-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

.alert-status {
  border: 1px solid currentColor;
}

a.badge { text-decoration: none; }
a.badge:hover { border-color: var(--accent); }

/* ---------- collapsible change list ---------- */
.change-details {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.change-summary {
  cursor: pointer;
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-3);
  list-style: none;
}
.change-summary::-webkit-details-marker { display: none; }
.change-summary::before {
  content: "";
  display: inline-block;
  width: 0.5em;
  height: 0.5em;
  border-right: 2px solid var(--ink-muted);
  border-bottom: 2px solid var(--ink-muted);
  transform: rotate(-45deg);
  margin-right: var(--space-2);
  transition: transform 0.15s ease;
}
.change-details[open] > .change-summary::before {
  transform: rotate(45deg);
}
.change-summary-count {
  font-family: var(--font-display);
  font-weight: 600;
}
.change-details .change-timeline {
  margin: 0;
  padding: 0 var(--space-4) var(--space-3);
}

/* Hosted sign-in */
.auth-card { max-width: 28rem; margin: var(--space-7) auto; }
.auth-again { margin-top: var(--space-3); }
.signout { display: inline-flex; gap: var(--space-2); align-items: center; }
.signed-in { color: var(--ink-muted); }
.verification-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
