/* Self-hosted so no visitor request reaches a third party.
   Loading these from Google sent every visitor's IP address to Google before a
   single price was drawn, which is a disclosure the dashboard should not have
   to make for a cosmetic dependency.

   Both are single variable fonts covering the whole weight range, so the two
   families cost two requests and about 80 KB rather than six of each.

   Inter and JetBrains Mono are both SIL Open Font License 1.1; see
   public/fonts/LICENSE.md. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/inter-variable.woff2') format('woff2');
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/jetbrains-mono-variable.woff2') format('woff2');
}

:root {
  --bg: #0a0e14;
  --surface: #111820;
  --surface-raised: #161f2a;
  --border: #1e2a38;
  --border-strong: #2b3a4d;
  --text: #e6edf3;
  --muted: #8b98a9;
  --accent: #f59e0b;
  --up: #26d07c;
  --down: #ff5c5c;

  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo,
    Consolas, monospace;
  --sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;

  --radius: 10px;
  --gap: 16px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

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

/* A single visible focus treatment, so keyboard users can always see
   where they are without each component inventing its own. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 24px 20px 56px;
}

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

header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}

h1 {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

h1 .mark {
  color: var(--accent);
}

.status {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--muted);
}

.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--muted);
  flex-shrink: 0;
}

.status[data-state='live'] .dot {
  background: var(--up);
  box-shadow: 0 0 8px rgb(38 208 124 / 0.7);
}

.status[data-state='error'] .dot {
  background: var(--down);
  box-shadow: 0 0 8px rgb(255 92 92 / 0.7);
}

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

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--gap);
  margin: 24px 0;
  padding: 0;
  list-style: none;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  position: relative;
  overflow: hidden;
  transition: border-color 200ms ease, background-color 200ms ease;
}

/* The coin's colour reads as a stripe rather than as text, which keeps
   every label at full contrast against the dark surface. */
.card::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--coin, var(--accent));
}

.card:hover {
  border-color: var(--border-strong);
  background: var(--surface-raised);
}

.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.symbol {
  font-family: var(--mono);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--coin, var(--text));
}

.name {
  font-size: 0.75rem;
  color: var(--muted);
}

.price {
  font-family: var(--mono);
  font-size: 1.5rem;
  font-weight: 500;
  margin: 10px 0 6px;
  /* Keeps digits from shifting width as the price ticks. */
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.change {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--mono);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

.change[data-dir='up'] {
  color: var(--up);
}

.change[data-dir='down'] {
  color: var(--down);
}

.change[data-dir='flat'] {
  color: var(--muted);
}

/* Direction is carried by an arrow as well as by colour, so the reading
   does not depend on distinguishing red from green. */
.change svg {
  width: 11px;
  height: 11px;
}

.spark {
  display: block;
  width: 100%;
  height: 34px;
  margin-top: 12px;
}

.stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 12px;
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 0.72rem;
}

.stats dt {
  color: var(--muted);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  font-size: 0.66rem;
}

.stats dd {
  margin: 0;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* ---------- chart ---------- */

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
}

.panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}

h2 {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 600;
}

.hint {
  margin: 0 0 14px;
  font-size: 0.76rem;
  color: var(--muted);
  max-width: 62ch;
}

.ranges {
  display: flex;
  gap: 4px;
}

.ranges button {
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 11px;
  cursor: pointer;
  transition: color 200ms ease, border-color 200ms ease,
    background-color 200ms ease;
}

.ranges button:hover {
  color: var(--text);
  border-color: var(--border-strong);
}

.ranges button[aria-pressed='true'] {
  color: var(--bg);
  background: var(--accent);
  border-color: var(--accent);
}

.chart {
  display: block;
  width: 100%;
  height: 300px;
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  font-family: var(--mono);
  font-size: 0.75rem;
}

.legend li {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
}

/* Was an inline style attribute, which the Content Security Policy blocks.
   Driven by a data attribute instead so the policy needs no unsafe-inline. */
.legend-change[data-dir='up'] {
  color: var(--up);
}

.legend-change[data-dir='down'] {
  color: var(--down);
}

.swatch {
  width: 10px;
  height: 3px;
  border-radius: 2px;
  flex-shrink: 0;
}

/* ---------- states ---------- */

.note {
  padding: 40px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 0.88rem;
}

.note[data-tone='error'] {
  color: var(--down);
}

/* Reserves the final height up front so arriving data does not push the
   page around. */
.skeleton {
  background: linear-gradient(
    90deg,
    var(--surface) 25%,
    var(--surface-raised) 37%,
    var(--surface) 63%
  );
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  height: 186px;
}

@keyframes shimmer {
  0% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}

footer {
  margin-top: 28px;
  font-size: 0.74rem;
  color: var(--muted);
}

footer a {
  color: var(--muted);
  text-decoration-color: var(--border-strong);
  text-underline-offset: 3px;
}

footer a:hover {
  color: var(--text);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media (max-width: 560px) {
  .wrap {
    padding: 18px 14px 40px;
  }
  .chart {
    height: 230px;
  }
}

/* ---------- long-form pages (terms, privacy) ---------- */

/* Narrower than the dashboard: prose is read line by line, so it is capped
   near 70 characters rather than filling a dashboard-width column. */
.prose {
  max-width: 46rem;
}

.prose .breadcrumb {
  margin-bottom: 28px;
  font-family: var(--mono);
  font-size: 0.78rem;
}

.prose a {
  color: var(--accent);
  text-decoration-color: rgb(245 158 11 / 0.4);
  text-underline-offset: 3px;
}

.prose a:hover {
  text-decoration-color: var(--accent);
}

.prose h1 {
  margin: 0 0 6px;
  font-size: 1.7rem;
  letter-spacing: -0.02em;
}

.prose .meta {
  margin: 0 0 28px;
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--muted);
}

.prose .lede {
  font-size: 1.02rem;
  color: var(--text);
  padding-bottom: 22px;
  border-bottom: 1px solid var(--border);
}

.prose h2 {
  margin: 34px 0 10px;
  font-size: 1.08rem;
  letter-spacing: -0.01em;
}

.prose h3 {
  margin: 24px 0 8px;
  font-size: 0.94rem;
  font-weight: 600;
  color: var(--accent);
}

.prose p,
.prose li {
  color: #c3cedb;
}

.prose ul {
  padding-left: 20px;
}

.prose li {
  margin-bottom: 7px;
}

.prose strong {
  color: var(--text);
  font-weight: 600;
}

.prose code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
}

/* The summary list carries the points most people came to check, so it reads
   as a block rather than as body text. */
.prose .summary {
  list-style: none;
  padding: 16px 18px;
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.prose .summary li {
  margin: 0;
  padding: 5px 0 5px 22px;
  position: relative;
}

.prose .summary li::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 12px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--up);
}

/* The financial disclaimer is the one thing on these pages that someone could
   be harmed by missing, so it is given weight rather than left as a paragraph. */
.prose .callout {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 18px 20px;
  margin: 26px 0;
}

.prose .callout h2 {
  margin-top: 0;
  color: var(--accent);
}

.prose .callout p:last-child {
  margin-bottom: 0;
}

.prose .aside {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  font-size: 0.9rem;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  margin: 14px 0;
  font-size: 0.88rem;
}

.prose th,
.prose td {
  text-align: left;
  vertical-align: top;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
}

.prose th {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.prose td {
  color: #c3cedb;
}

.prose > footer {
  margin-top: 40px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 0.78rem;
}

/* A table of third parties should not force the page sideways on a phone. */
@media (max-width: 560px) {
  .prose table {
    display: block;
    overflow-x: auto;
  }
}

.legal-links {
  margin-top: 6px;
  font-family: var(--mono);
  font-size: 0.72rem;
}
