/* Alephium Price Index — monochrome by design.
   Alephium's own identity is a white mark on black with Inter, so the palette
   here is neutral throughout and colour is reserved for meaning: confidence and
   disagreement are the only things allowed to be coloured. */

:root {
  --bg: #08090a;
  --surface: #0e1011;
  --surface-2: #14171a;
  --line: #1e2226;
  --line-soft: #16191c;
  --fg: #f2f4f5;
  --fg-2: #99a1a8;
  --fg-3: #626a71;
  --good: #d8dbde;
  --warn: #d2a12f;
  --bad: #cc6152;
  /* Direction is the only non-confidence meaning allowed colour on this page.
     Desaturated on purpose: a wall of 191 saturated green/red rows reads as
     decoration, and the point is that colour here carries information. */
  --up: #5aa87c;
  --down: #cc6152;
  --flat: #626a71;
  --focus: #6ea8fe;
  --radius: 12px;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --gutter: 16px;
}

/* Light is defined once and applied twice: when the OS asks for it and the
   reader has not overridden, and when the reader has explicitly chosen it.
   Keeping one declaration block means the two can never drift apart. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #fbfbfc; --surface: #fff; --surface-2: #f4f5f6;
    --line: #e3e6e8; --line-soft: #eef0f1;
    --fg: #0d1114; --fg-2: #5b636a; --fg-3: #858d94;
    --good: #1c2226; --warn: #9a7413; --bad: #a83f30;
    --up: #2f7d52; --down: #a83f30; --flat: #858d94;
  }
}
:root[data-theme="light"] {
  --bg: #fbfbfc; --surface: #fff; --surface-2: #f4f5f6;
  --line: #e3e6e8; --line-soft: #eef0f1;
  --fg: #0d1114; --fg-2: #5b636a; --fg-3: #858d94;
  --good: #1c2226; --warn: #9a7413; --bad: #a83f30;
  --up: #2f7d52; --down: #a83f30; --flat: #858d94;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  font-variant-numeric: tabular-nums;
}
h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.015em; }
p { margin: 0; }
a { color: inherit; }

.wrap { width: 100%; max-width: 1280px; margin: 0 auto; padding-inline: var(--gutter); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 10;
  background: var(--fg); color: var(--bg); padding: 10px 14px; border-radius: 0 0 8px 0;
}
.skip:focus { left: 0; }

:where(a, button, input, th[data-sort], tr[tabindex]):focus-visible {
  outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px;
}

/* ---------- header ---------- */
.top { border-bottom: 1px solid var(--line); background: var(--bg); }
.top-in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; padding-block: 22px; flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: 13px; min-width: 0; }
/* The mark is pale by design: measured 13.3:1 against the dark ground and
   1.49:1 against white, i.e. invisible in light mode. It sits on the same dark
   tile the app icon uses, which keeps the brand mark itself untouched and the
   two treatments consistent. On the dark theme the tile is indistinguishable
   from the header. */
.mark {
  width: 34px; height: 34px; flex: none; display: block;
  background: #0b0d0f; border-radius: 8px; padding: 3px;
  box-sizing: border-box;
}
.brand-txt h1 { font-size: 1.0625rem; }
.brand-txt p { color: var(--fg-2); font-size: .8125rem; margin-top: 2px; }

.ticker { display: flex; align-items: center; gap: 16px; font-size: .8125rem; color: var(--fg-2); }
/* #ticker is now a child of .ticker rather than being it, so it needs its own
   gap — otherwise the spans it renders butt together. */
#ticker { display: flex; align-items: center; gap: 16px; }
.ticker b { color: var(--fg); font-weight: 500; font-family: var(--mono); }
/* Theme switch. Three states rather than two, because "follow the system" is
   a real preference and a two-way toggle silently destroys it. */
.theme {
  display: inline-flex; align-items: center; gap: 2px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 8px; padding: 2px;
}
.theme button {
  background: none; border: 0; color: var(--fg-3); cursor: pointer;
  padding: 3px 7px; border-radius: 6px; line-height: 1; display: grid; place-items: center;
}
.theme button svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.theme button:hover { color: var(--fg-2); }
.theme button[aria-pressed="true"] { color: var(--fg); background: var(--surface); box-shadow: 0 1px 2px rgba(0,0,0,.18); }

.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--good); display: inline-block; margin-right: 6px; }
.dot.stale { background: var(--warn); }
.dot.down { background: var(--bad); }

/* ---------- stats ---------- */
.stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  /* The 1px gap IS the divider: cells sit on this background. It is also what
     an empty trailing cell shows, so it must read as part of the panel. */
  background: var(--line-soft);
  border: 1px solid var(--line); border-radius: var(--radius);
  margin-block: 26px; overflow: hidden;
}
/* A <dl> carries a default 1em block margin. Inside a gap-as-divider grid that
   margin shows through as a broad band between rows. */
.stat { background: var(--surface); padding: 15px 17px; margin: 0; }
.stat dt { color: var(--fg-3); font-size: .6875rem; text-transform: uppercase; letter-spacing: .07em; margin: 0 0 6px; }
.stat dd { margin: 0; font-size: 1.25rem; font-weight: 500; font-family: var(--mono); letter-spacing: -.02em; }
.stat small { display: block; color: var(--fg-3); font-size: .75rem; font-family: var(--sans); margin-top: 3px; }

/* ---------- panel ---------- */
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.panel-head {
  display: flex; gap: 14px; align-items: center; justify-content: space-between;
  padding: 13px 16px; border-bottom: 1px solid var(--line); flex-wrap: wrap;
}
.search { position: relative; flex: 1 1 240px; display: flex; align-items: center; }
.search svg {
  position: absolute; left: 11px; width: 15px; height: 15px; pointer-events: none;
  fill: none; stroke: var(--fg-3); stroke-width: 1.8; stroke-linecap: round;
}
.search input {
  width: 100%; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 8px; color: var(--fg); font: inherit; font-size: .875rem;
  padding: 8px 12px 8px 33px;
}
.search input::placeholder { color: var(--fg-3); }
.toggle { display: flex; align-items: center; gap: 8px; color: var(--fg-2); font-size: .8125rem; cursor: pointer; user-select: none; }
.toggle input { accent-color: var(--fg); width: 15px; height: 15px; }

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; font-size: .875rem; }
thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--surface); color: var(--fg-3);
  font-size: .6875rem; font-weight: 500; text-transform: uppercase; letter-spacing: .07em;
  text-align: right; padding: 10px 11px; white-space: nowrap;
  border-bottom: 1px solid var(--line); cursor: pointer;
}
thead th.c-tok { text-align: left; }
thead th.c-spark, td.c-spark { width: 104px; }
thead th span { border-bottom: 1px dotted var(--fg-3); cursor: help; }
thead th[aria-sort] { color: var(--fg); }
thead th[aria-sort="descending"]::after { content: " ↓"; }
thead th[aria-sort="ascending"]::after { content: " ↑"; }

tbody tr { border-bottom: 1px solid var(--line-soft); cursor: pointer; }
tbody tr:last-child { border-bottom: 0; }
tbody tr:hover, tbody tr:focus-visible { background: var(--surface-2); }
td { padding: 11px 11px; text-align: right; white-space: nowrap; }
td.c-tok { text-align: left; }

.tok { display: flex; align-items: center; gap: 10px; }
.tok img, .tok .ph {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  background: var(--surface-2); object-fit: cover;
}
.tok .ph { display: grid; place-items: center; font-size: .625rem; color: var(--fg-3); font-weight: 600; }
.tok b { font-weight: 500; }
.tok span {
  color: var(--fg-3); font-size: .75rem; display: block; margin-top: -2px;
  max-width: 19ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
td.c-tok { max-width: 240px; }
.tok > div { min-width: 0; }
.badge {
  font-size: .625rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--warn); border: 1px solid currentColor; border-radius: 4px;
  padding: 1px 4px; margin-left: 7px; vertical-align: 1px;
}
.num { font-family: var(--mono); }
.muted { color: var(--fg-3); }

.conf { display: inline-flex; align-items: center; gap: 8px; }
.conf i {
  width: 34px; height: 4px; border-radius: 2px; background: var(--line);
  overflow: hidden; display: block; flex: none;
}
.conf i b { display: block; height: 100%; background: currentColor; }
.conf.hi { color: var(--good); }
.conf.mid { color: var(--warn); }
.conf.lo { color: var(--bad); }
.conf em { font-style: normal; font-family: var(--mono); font-size: .8125rem; }

/* ---------- sparkline + change ---------- */
.spark { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.spark svg { display: block; flex: none; overflow: visible; width: 52px; }
.spark svg path { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.spark .chg { font-family: var(--mono); font-size: .8125rem; min-width: 5.5ch; text-align: right; }
.up { color: var(--up); }
.down { color: var(--down); }
.flat { color: var(--flat); }
.spark .none { color: var(--fg-3); font-size: .75rem; }

/* ---------- large chart ---------- */
.chart { margin-bottom: 22px; }
.chart-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
.chart-head h3 { margin: 0; }
.ranges { display: flex; gap: 2px; }
.ranges button {
  background: none; border: 1px solid transparent; color: var(--fg-3);
  font: inherit; font-size: .75rem; padding: 3px 9px; border-radius: 6px; cursor: pointer;
}
.ranges button:hover { color: var(--fg); }
.ranges button[aria-pressed="true"] { color: var(--fg); background: var(--surface-2); border-color: var(--line); }
.chart-box { position: relative; background: var(--surface-2); border: 1px solid var(--line); border-radius: 9px; padding: 12px; }
.chart-box svg { display: block; width: 100%; height: auto; max-width: 100%; }
.chart-box .line { fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linejoin: round; stroke-linecap: round; }
.chart-box .area { stroke: none; opacity: .09; }
.chart-box .grid { stroke: var(--line); stroke-width: 1; }
.chart-box .axis { fill: var(--fg-3); font-size: 10px; font-family: var(--mono); }
.chart-note { color: var(--fg-3); font-size: .75rem; margin-top: 9px; }
.chart-empty { display: grid; place-items: center; height: 190px; color: var(--fg-3); font-size: .8125rem; text-align: center; padding: 0 20px; }

.empty { padding: 34px; text-align: center; color: var(--fg-3); }

/* ---------- method ---------- */
.method { margin-block: 46px 34px; }
.method h2 { font-size: .6875rem; text-transform: uppercase; letter-spacing: .09em; color: var(--fg-3); margin-bottom: 16px; }
.method-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 22px 32px; }
.method h3 { font-size: .875rem; margin-bottom: 5px; }
.method p { color: var(--fg-2); font-size: .8125rem; line-height: 1.6; }
.method em { color: var(--fg); font-style: italic; }

/* ---------- footer ---------- */
.foot { padding-block: 22px 40px; border-top: 1px solid var(--line); color: var(--fg-3); font-size: .75rem; display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.foot-links { display: flex; gap: 18px; }
.foot a { color: var(--fg-2); text-decoration: none; border-bottom: 1px solid var(--line); }
.foot a:hover { color: var(--fg); }

/* ---------- detail dialog ---------- */
dialog {
  width: min(760px, calc(100vw - 32px)); max-height: 86vh; padding: 0;
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: auto; margin: auto;
}
dialog::backdrop { background: rgba(0,0,0,.66); backdrop-filter: blur(2px); }
.d-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 16px;
  padding: 19px 20px; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--surface); z-index: 1;
}
.d-head h2 { font-size: 1.0625rem; }
.d-head p { color: var(--fg-2); font-size: .8125rem; margin-top: 3px; }
#dClose { background: none; border: 0; color: var(--fg-3); font-size: 1.6rem; line-height: 1; cursor: pointer; padding: 0 4px; }
#dClose:hover { color: var(--fg); }
#dBody { padding: 20px; }
.kv { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: 15px; margin-bottom: 24px; }
.kv div dt { color: var(--fg-3); font-size: .6875rem; text-transform: uppercase; letter-spacing: .07em; margin-bottom: 4px; }
.kv div dd { margin: 0; font-family: var(--mono); font-size: .9375rem; }
#dBody h3 { font-size: .6875rem; text-transform: uppercase; letter-spacing: .09em; color: var(--fg-3); margin-bottom: 10px; }
#dBody table { font-size: .8125rem; }
#dBody thead th { position: static; cursor: default; background: none; }
#dBody thead th span { border: 0; cursor: default; }
#dBody tbody tr { cursor: default; }
#dBody tbody tr:hover { background: none; }
.dev-pos { color: var(--warn); }
.dev-neg { color: var(--bad); }
.note { color: var(--fg-3); font-size: .75rem; margin-top: 14px; line-height: 1.6; }

/* Secondary columns go first: Pools and Spread are both in the detail view, and
   Confidence must never be the thing that falls off the right edge — it is the
   column that tells you whether to trust the row. */
/* Measured: with all eight columns the table needs a ~1180px container, i.e. a
   ~1212px viewport. Hiding the two secondary columns below 1240 rather than
   1060 closes the band where the table used to overflow into a horizontal
   scrollbar on a 13-inch laptop. Both are still in the detail view. */
@media (max-width: 1240px) {
  .c-hide-s { display: none; }
  th, td { padding-inline: 9px; }
}

/* ---------- mobile: the table becomes cards ---------- */
@media (max-width: 720px) {
  .top-in { padding-block: 16px; }
  .ticker { width: 100%; justify-content: space-between; gap: 10px; font-size: .75rem; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  /* Five cards in two columns leave one empty. Let the last one take it rather
     than leave a hole — it also has the longest text. */
  .stat:last-child { grid-column: 1 / -1; }
  .panel-head { gap: 10px; }

  /* Scoped to the main table ON PURPOSE: the detail dialog has its own table,
     and an unscoped `table { display: block }` tore it apart. */
  #tbl thead { display: none; }
  #tbl, #tbl tbody, #tbl tr, #tbl td { display: block; width: 100%; }
  /* `#tbl td` outranks `.c-hide-s`, so the columns hidden at the wider
     breakpoint come back here unless they are hidden again by a selector at
     least as specific. */
  #tbl td.c-hide-s { display: none; }

  /* Named areas, because the visible cell count changes with the breakpoints
     above — a grid-row span would silently mis-align when Pools and Spread are
     hidden. */
  #tbl tbody tr {
    padding: 13px 15px;
    border-bottom: 1px solid var(--line-soft);
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "tok   alph"
      "tok   usd"
      "tok   spark"
      "depth conf";
    gap: 2px 14px;
    align-items: center;
  }
  #tbl td { padding: 0; text-align: right; }
  #tbl td.c-tok { grid-area: tok; text-align: left; align-self: center; }
  #tbl td:nth-child(2) { grid-area: alph; font-size: .9375rem; }
  #tbl td:nth-child(3) { grid-area: usd; color: var(--fg-2); font-size: .8125rem; }
  #tbl td.c-spark { grid-area: spark; }
  #tbl td:nth-child(5) { grid-area: depth; text-align: left; margin-top: 7px; }
  #tbl td:last-child   { grid-area: conf; margin-top: 7px; }

  /* Labels only where the number is ambiguous on its own. A price does not need
     one; a depth figure does. */
  #tbl td[data-l="Depth 1%"]::before,
  #tbl td[data-l="Confidence"]::before {
    content: attr(data-l) " ";
    color: var(--fg-3); font-size: .6875rem; text-transform: uppercase;
    letter-spacing: .06em; font-family: var(--sans); margin-right: 6px;
  }
  #tbl td[data-l="ALPH"]::after { content: " ALPH"; color: var(--fg-3); font-size: .75rem; }
  .tok span { max-width: 16ch; }

  .foot { flex-direction: column; }
  .method-grid { gap: 20px; }
  dialog { width: calc(100vw - 20px); max-height: 90vh; }
  #dBody { padding: 16px; }
  .kv { grid-template-columns: repeat(2, 1fr); gap: 13px; }
  /* The dialog table stays a table; it just gets tighter and may scroll. */
  #dBody table { font-size: .75rem; }
  #dBody td, #dBody th { padding: 8px 5px; white-space: nowrap; }
  #dBody .obs { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-inline: -16px; padding-inline: 16px; }
  #dBody .obs .c-tok span { max-width: 11ch; display: inline-block; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; }
}
