/* --------------------------------------------------------------------------- Filter bar --- */
/*
 * A plain GET form. No client state: the page a reader is looking at is the page they can paste,
 * which is the whole point of an artifact meant to be cited.
 */
/*
 * ── ONE CONTROL HEIGHT, DECLARED ONCE ───────────────────────────────────────────────────────────
 *
 * The bar had three different ones. A select was ~30px, the checkbox was a 13px native box, and
 * Apply inherited `.btn`'s marketing size — 15px sans with 14px of vertical padding, ~47px tall.
 * With `align-items: flex-end` the three sat on a shared bottom edge and nothing else about them
 * lined up, so a row of four controls read as four unrelated objects.
 *
 * Every control in this bar is now exactly --control-h tall and the row genuinely is a row.
 */
.filters {
  --control-h: 32px;

  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s3) var(--s4);
  margin: var(--s4) 0;
  padding: var(--s3) 0;
  border-top: var(--hair) solid var(--rule);
  border-bottom: var(--hair) solid var(--rule);
}

/* A labelled control: its name above it. */
.filters label {
  display: flex;
  flex-direction: column;
  gap: var(--s1);
}

.filters select {
  height: var(--control-h);
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--fg);
  background: var(--card);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r);
  padding: 0 8px;
}

/*
 * ── THE CHECKBOX IS A ROW, AND IT WAS A COLUMN ──────────────────────────────────────────────────
 *
 * `.filters label` stacks a control under its name, which is right for the three selects and wrong
 * for the only control whose name belongs BESIDE it. The checkbox rendered above its own caption,
 * floating over "WITH A TRADING VENUE ONLY" with no visible relationship to it — the box looked
 * like it belonged to the Sort by select to its left.
 *
 * Specificity note: `.filters label` is (0,1,1), so a bare `.filters__toggle` would lose to it.
 * Qualified with the element to make winning explicit rather than incidental.
 */
.filters label.filters__toggle {
  flex-direction: row;
  align-items: center;
  gap: var(--s2);
  min-height: var(--control-h);
  cursor: pointer;
}

/*
 * ── AND IT HAD TO BE DRAWN, NOT DECLARED ────────────────────────────────────────────────────────
 *
 * The old rule set `background: var(--card)` and a border on a native checkbox. A native control
 * ignores both without `appearance: none`, so on this dark ground it painted the platform default:
 * a white square, the brightest object on the page, on a bar of muted 13px mono.
 */
.filters input[type="checkbox"] {
  appearance: none;
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin: 0;
  padding: 0;
  display: grid;
  place-content: center;
  background: var(--card);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r);
  cursor: pointer;
}

/* The mark is a child rather than a background image, so it inherits the theme's ink and needs no
   second asset to keep in step with the tokens. */
.filters input[type="checkbox"]::before {
  content: "";
  width: 7px;
  height: 7px;
  background: var(--accent-ink);
  transform: scale(0);
  transition: transform 100ms ease;
}

.filters input[type="checkbox"]:checked { border-color: var(--accent-ink); }
.filters input[type="checkbox"]:checked::before { transform: scale(1); }

/*
 * Apply and Clear, kept together so they wrap as a pair and stay a pair when the bar becomes a
 * column. `.btn`'s own size is for a page's primary action; inside a filter bar it has to match the
 * controls it acts on.
 */
.filters__actions {
  display: flex;
  align-items: center;
  gap: var(--s2);
}

.filters .btn {
  height: var(--control-h);
  padding: 0 16px;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
}

/* The permalink rendered AS TEXT, so a screenshot carries its own citation. */
.as-of__perma { color: var(--fg-3); }

/* ------------------------------------------------------------------- Narrow transpose --- */
/*
 * P6: narrow carries the SAME data as wide. No truncated feature set, no "see full table on
 * desktop". The row transposes into stacked label/value pairs and every field survives.
 *
 * The labels come from the header row via `data-k` on each cell, so there is one markup and the
 * two layouts cannot drift apart. A horizontally scrolling table on a phone hides the comparison,
 * which on this site is the entire content.
 */
@media (max-width: 720px) {
  .rows thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  /*
   * ── THE LABEL GUTTER ────────────────────────────────────────────────────────────────────────
   *
   * One width for every label on the page, declared once here. Each transposed cell is its own
   * formatting context, so without a fixed gutter every value starts at a different x — the value
   * beside "AMM MID" indented three characters and the one beside "CHAINLINK TRV" indented
   * thirteen. A column of values that does not line up is not a column, and lining them up is the
   * entire reason the wide table is a table.
   */
  .rows { --k-col: 118px; }

  .rows tr {
    display: block;
    border-top: var(--hair) solid var(--rule);
    padding-block: var(--s2);
  }

  .rows td,
  .rows th {
    display: block;
    /*
     * `height: var(--row-h)` from 40-primitives.css has to be released here, and it is a HEIGHT
     * rather than a min-height, so it does not simply lose to taller content. Left on, every field
     * of every row was a 48px band on a phone and one ticker ran to 336px of mostly empty space.
     */
    height: auto;
    border: 0;
    padding-inline: 0;
    text-align: left;
  }

  /*
   * ── THE LABEL COMES FROM `data-k`, AND EVERY CELL MUST CARRY ONE ────────────────────────────
   *
   * The label/value pair is applied only to cells that HAVE the attribute. It used to be applied to
   * every `td` unconditionally, with `content: attr(data-k)` reading an attribute no view in the
   * app actually set — so under 720px every table on the site rendered as a column of bare values
   * with an empty label column beside them, and nothing anywhere threw. That is the whole of the
   * "narrow is broken" bug.
   *
   * Scoped to `[data-k]` now, so the two headerless key/value tables on /status (whose row header
   * IS the label) and the empty-state row on /latency lay out as plain blocks instead of growing a
   * phantom column.
   *
   * FLEX RATHER THAN GRID, and the reason is bare text. Several cells render a value with no
   * wrapping element at all — a venue name, a swap count, "Watched it land". In a grid each of
   * those becomes an anonymous item that auto-places into the LABEL column of the next row, which
   * puts the value under its own label instead of beside it. A flex line takes them in order.
   */
  .rows td[data-k],
  .rows th[data-k] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 var(--s3);
    padding-block: 5px;
  }

  .rows td[data-k]::before,
  .rows th[data-k]::before {
    content: attr(data-k);
    flex: 0 0 var(--k-col);
    font: 500 10px/1.2 var(--font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--fg-3);
  }

  /*
   * The second line of a cell — a company name under a ticker, the dollar reading under a bps chip,
   * the two sides of a book under its depth. It takes a line of its own and indents to the value
   * column, so it reads as a note on the value above rather than as another value.
   */
  .rows [data-k] .rows__sub {
    flex-basis: 100%;
    margin-left: calc(var(--k-col) + var(--s3));
    margin-top: 2px;
  }

  /*
   * ── STALL HISTORY IS THE ONE TABLE THE TRANSPOSE GETS WRONG ─────────────────────────────────
   *
   * The label/value transpose above is right for a table of a few rows: the dashboard's four, the
   * one-row venue table. Stall history is many rows of six fields, and at one stacked pair per
   * field it rendered as an unbroken column of label/value lines — every window six lines tall,
   * with nothing marking where one window ended and the next began, and no way to compare two
   * durations without scrolling between them. Twenty-five windows made 150 lines.
   *
   * A WINDOW IS ONE BLOCK. Duration leads at reading size because it is what the row is about, the
   * start and the session sit beside it as its dateline, and the three measurements wrap
   * underneath as small labelled pairs. Four lines instead of twelve, and the rule between rows
   * does the separating.
   *
   * Built on `order` rather than on markup, so the wide table keeps the column order its header
   * promises and the narrow one is purely a restatement of the same cells.
   */
  .rows--stalls tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px var(--s4);
    padding-block: var(--s3);
  }

  .rows--stalls tbody td[data-k] {
    width: auto;
    flex: 0 0 auto;
    gap: 0 var(--s1);
    padding-block: 0;
  }

  .rows--stalls tbody td[data-k]::before {
    flex: 0 0 auto;
    font-size: 9px;
    letter-spacing: 0.12em;
    color: var(--fg-4);
  }

  /* The dateline: duration first and largest, then when and which session. No labels — "8h 54m"
     and "overnight" say what they are, and a label on each would be three quarters of the line. */
  .rows--stalls tbody td[data-k="Duration"] {
    order: -3;
    flex-basis: 100%;
    font-size: 19px;
    font-weight: 500;
    color: var(--fg);
  }
  .rows--stalls tbody td[data-k="Start"] { order: -2; color: var(--fg-4); }
  .rows--stalls tbody td[data-k="Session"] { order: -1; color: var(--fg-4); }

  .rows--stalls tbody td[data-k="Duration"]::before,
  .rows--stalls tbody td[data-k="Start"]::before,
  .rows--stalls tbody td[data-k="Session"]::before { content: none; }

  /* The dateline gets its own line; the three measurements wrap onto the next. */
  .rows--stalls tbody td[data-k="Swaps"] { flex-basis: 100%; }
  .rows--stalls tbody td[data-k="Swaps"],
  .rows--stalls tbody td[data-k="Peak"],
  .rows--stalls tbody td[data-k="Oracle move"] { display: inline-flex; }
  .rows--stalls tbody td[data-k="Swaps"] { flex-basis: auto; }

  /* Qualified for the same reason as the right-alignment it overrides. See 40-primitives.css. */
  .rows th.rows__num,
  .rows td.rows__num { text-align: left; }

  /*
   * ── /latency IS STALL HISTORY WITH FIVE MORE COLUMNS ────────────────────────────────────────
   *
   * The generic label/value transpose above is right for a table of a few fields. This one has
   * eleven, so every window rendered as eleven stacked lines with nothing marking where one ended
   * and the next began — a hundred windows made eleven hundred lines of it. That is the exact
   * failure `.rows--stalls` was written for on the ticker page, and this is the bigger instance of
   * it: this table is the artifact the site exists to be cited for, and it is the one people open
   * from a phone after following a link out of a thread.
   *
   * A WINDOW IS ONE BLOCK. Which asset and how long it was frozen lead at reading size, the
   * interval sits under them as its dateline, and the seven measurements wrap underneath as small
   * labelled pairs. Five lines instead of eleven, and the rule between rows does the separating.
   *
   * Ordered rather than re-marked-up, so the wide table keeps the column order its header promises
   * and there is one source of truth for both layouts.
   */
  .rows--windows tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px var(--s4);
    padding-block: var(--s3);
  }

  .rows--windows tbody td[data-k],
  .rows--windows tbody th[data-k] {
    width: auto;
    flex: 0 0 auto;
    gap: 0 var(--s2);
    padding-block: 0;
  }

  /* Auto width, so a measurement is a label and its value sitting together rather than a value
     indented past a 118px gutter it does not need. */
  .rows--windows tbody td[data-k]::before,
  .rows--windows tbody th[data-k]::before {
    flex: 0 0 auto;
    font-size: 9px;
  }

  /* The headline. Neither needs a label: a ticker and "1.2h" say what they are. */
  .rows--windows tbody th[data-k="Ticker"] { order: -4; font-size: 15px; }
  .rows--windows tbody td[data-k="Duration"] { order: -3; font-size: 15px; color: var(--fg); }
  .rows--windows tbody th[data-k="Ticker"]::before,
  .rows--windows tbody td[data-k="Duration"]::before { content: none; }

  /*
   * The dateline: two full-width lines rather than two pairs sharing one. `flex-basis: 100%` is
   * what forces the break after the headline — flexbox assigns lines from the basis, so nothing
   * shorter would put these on a line of their own reliably. Their labels share a fixed gutter so
   * the two timestamps line up under each other and the interval reads as one fact.
   */
  .rows--windows tbody td[data-k="Start"],
  .rows--windows tbody td[data-k="End"] {
    flex-basis: 100%;
    color: var(--fg-4);
  }

  .rows--windows tbody td[data-k="Start"] { order: -2; }
  .rows--windows tbody td[data-k="End"] { order: -1; }

  .rows--windows tbody td[data-k="Start"]::before,
  .rows--windows tbody td[data-k="End"]::before { flex: 0 0 40px; }

  /* The empty state carries no data-k and is a single wide cell, not a measurement. */
  .rows--windows tbody td:not([data-k]) { flex-basis: 100%; }

  /*
   * ── THE FILTER BAR STACKS, AND THE CONTROLS STILL SIT IN IT ─────────────────────────────────
   *
   * `align-items: stretch` is what makes each select fill the width, which is what you want on a
   * phone. It also stretches the checkbox row and the buttons, so both opt back out: a 15px box has
   * no business being 320px wide, and Apply reads as the action rather than as a banner.
   */
  .filters { flex-direction: column; align-items: stretch; }
  .filters label.filters__toggle { align-self: flex-start; }
  .filters__actions { align-self: flex-start; }

  /*
   * ── THE SORT CONTROL SURVIVES THE TRANSPOSE ────────────────────────────────────────────────
   *
   * The instrument table sorts from its own header cells, and the rule above clips the whole
   * header row away on a narrow screen. Left at that, sorting would be a desktop-only feature on
   * the one page the whole site is about — and P6 says narrow carries the same data as wide.
   *
   * So the header row comes back, as a wrapped strip of the sortable columns only. Same markup,
   * one source of truth, and no second control to keep in step with the first. The columns that do
   * not sort stay hidden: their labels are already printed beside their values by the transpose,
   * and repeating them here would be a row of words that do nothing when clicked.
   *
   * Declared AFTER the clip above, at the same specificity, which is what lets it win. Keep the
   * two blocks in this order.
   */
  .rows--instrument thead {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    display: block;
    border-bottom: var(--hair) solid var(--rule);
  }

  .rows--instrument thead tr {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s1);
    border: 0;
    padding-block: var(--s2);
  }

  .rows--instrument thead th { display: none; }

  .rows--instrument thead th.rows__sortable {
    display: block;
    min-height: 0;
    padding: 0;
  }

  /*
   * ── ON A PHONE THESE ARE BUTTONS, SO THEY HAVE TO LOOK LIKE BUTTONS ───────────────────────────
   *
   * The transpose turns the header row into the table's only control, and it was drawn as four
   * bare words inside a TRANSPARENT border: nothing said they could be tapped, and the only one
   * with an outline was the one already active — the exact inverse of what an affordance is for.
   *
   * A visible hairline on all four is what makes them read as a set of options. 40px min-height
   * is the tap target the bare words never had (--row-h is 48px on this canvas for the same
   * reason), and 11px lifts the label off the 10px floor it shares with axis ticks, which matters
   * more here than in the wide table because here it is the thing you are aiming at.
   */
  .rows--instrument thead .th-sort {
    width: auto;
    min-height: 40px;
    padding: 8px 10px;
    font-size: 11px;
    border: var(--hair) solid var(--rule);
  }

  .rows--instrument thead .th-sort__arrow { font-size: 12px; }

  /* Colour is never the only signal: the active chip is the accent AND the only filled-weight
     label in the row, so the current sort survives a greyscale screenshot. */
  .rows--instrument thead .th-sort--on { border-color: var(--accent); font-weight: 600; }
}
