/* css/app.css
 *
 * The console: /lab, /specimens, /specimen, /runs, /run, /verify, /stake, /credits.
 *
 * Load order on every app page:
 *   css/tokens.css   the palette, the type scale, the spacing scale, the reset
 *   css/site.css     the shell (header, nav, token pills, footer) and the shared primitives
 *   css/app.css      this file
 *   css/viz.css      only on a page that mounts the lattice
 *
 * This file is ADDITIVE. It never redefines a class css/site.css already owns, because the site builder
 * owns that file and the shell has to look the same on every route. Everything new here is prefixed `app-`
 * or is a form control, which css/site.css has none of. The primitives reused from there are
 * .wrap .page-head .panel .panel__bar .panel__body .btn .btn--primary .btn--quiet .note .note--warn
 * .prose .label .num .mono .tag .grid .cell .table .table-scroll .toasts .rule .link .bracket.
 *
 * Two rules that shaped the file:
 *   * There are no box shadows on this site. Depth is a hairline, a gradient border and a backdrop blur.
 *   * --text-faint is 4.28:1 on --bg, under the 4.5 the layout gate wants for normal text, so nothing
 *     small is painted with it. Small secondary copy is --text-dim (5.2:1) or --text-muted (9.7:1).
 */

/* ------------------------------------------------------------------------------------ page scaffold */

.app-page {
  padding-bottom: var(--sp-11);
}

/* A page without a .page-head still has to clear the fixed header. */
.app-top {
  padding-top: calc(var(--header-h) + var(--sp-8));
}

.app-head__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-5);
  margin-top: var(--sp-4);
}

.app-section { margin-top: var(--sp-7); }
.app-section:first-child { margin-top: 0; }

/* Every single column grid names minmax(0, 1fr) on purpose. An implicit `auto` track is sized to the
   max content of its items, so one wide table inside one of these makes the whole page scroll sideways at
   360. That is exactly what the layout gate caught on /stake. */
.app-stack { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); align-content: start; }
.app-stack--tight { gap: var(--sp-4); }

.app-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  align-items: center;
}

.app-split { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); align-items: start; }

@media (min-width: 1060px) {
  .app-split { grid-template-columns: minmax(300px, 380px) minmax(0, 1fr); gap: var(--sp-6); }
}

.app-muted { color: var(--text-muted); font-size: var(--t-small); line-height: 1.7; }
.app-dim { color: var(--text-dim); }

/* ---------------------------------------------------------------------------------- panel headings */

.app-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-4);
  padding: 10px 14px;
  border-bottom: var(--hairline);
  color: var(--text-dim);
}

.app-bar__index {
  font-family: var(--font-mono);
  font-size: var(--t-nano);
  letter-spacing: var(--track-wide);
  color: var(--green-500);
}

.app-bar__title {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text);
}

.app-bar__note { margin-left: auto; color: var(--text-muted); font-size: var(--t-micro); }

.app-body { padding: var(--sp-5); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-4); align-content: start; }

/* ------------------------------------------------------------------------------------- form fields */

.field { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; min-width: 0; }

.field__label {
  font-family: var(--font-mono);
  font-size: var(--t-nano);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

.field__hint { font-size: var(--t-micro); line-height: 1.6; color: var(--text-muted); }

select,
input[type="text"],
input[type="search"],
input[type="number"],
textarea {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  background: var(--bg-deep);
  border: var(--hairline-bright);
  border-radius: var(--r-xs);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--t-small);
  line-height: 1.4;
  transition: border-color var(--dur-fast) var(--ease);
}

textarea { min-height: 96px; resize: vertical; line-height: 1.6; }

select:hover,
input:hover,
textarea:hover { border-color: var(--green-600); }

input::placeholder,
textarea::placeholder { color: var(--text-muted); }

/* css/site.css styles .btn but has no disabled state, and the console leans on one: the Record control is
   disabled with its reason in eleven of the seventeen rows of the state table. A control that is refusing
   to work has to look like it. */
.btn:disabled,
.btn[aria-disabled="true"] {
  cursor: not-allowed;
  color: var(--text-muted);
  border-color: var(--line);
  background: transparent;
}

.btn:disabled:hover,
.btn[aria-disabled="true"]:hover {
  color: var(--text-muted);
  border-color: var(--line);
  background: transparent;
}

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

.app-chips { display: flex; flex-wrap: wrap; gap: 6px; }

.app-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 12px;
  background: transparent;
  border: var(--hairline);
  border-radius: var(--r-xs);
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.app-chip:hover { color: var(--text); border-color: var(--line-bright); }
.app-chip[aria-pressed="true"] { color: var(--green-300); border-color: var(--green-600); background: color-mix(in srgb, var(--moss) 18%, transparent); }
.app-chip__cost { color: var(--text-dim); }
.app-chip[aria-pressed="true"] .app-chip__cost { color: var(--green-400); }

/* -------------------------------------------------------------------------------- the run state row */

.app-state {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border: var(--hairline);
  border-left: 2px solid var(--green-500);
  background: var(--bg-deep);
}

.app-state[data-tone="warn"] { border-left-color: var(--warn); }

.app-state__title {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--green-300);
}

.app-state[data-tone="warn"] .app-state__title { color: var(--warn); }
.app-state__copy { font-size: var(--t-small); line-height: 1.7; color: var(--text-muted); max-width: var(--measure); }
.app-state__copy strong { color: var(--text); font-weight: 600; }
.app-state__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

/* ------------------------------------------------------------------------------------- the lattice */

.app-viz {
  position: relative;
  width: 100%;
  min-height: 300px;
  height: clamp(300px, 50vh, 520px);
  border-bottom: var(--hairline);
  background: var(--bg-deep);
}

.app-viz--tall { height: clamp(320px, 60vh, 620px); }

.app-viz__caption {
  display: flex;
  flex-wrap: wrap;
  gap: 6px var(--sp-4);
  padding: 10px 14px;
  border-bottom: var(--hairline);
  font-family: var(--font-mono);
  font-size: var(--t-nano);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

.app-viz__controls { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 14px; }

/* ------------------------------------------------------------------------------- keys and values */

.app-kv {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-3) var(--sp-5);
  margin: 0;
}

@media (min-width: 620px) { .app-kv { grid-template-columns: minmax(140px, auto) minmax(0, 1fr); } }

.app-kv dt {
  font-family: var(--font-mono);
  font-size: var(--t-nano);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-muted);
  padding-top: 2px;
}

.app-kv dd {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-variant-numeric: tabular-nums;
  color: var(--text);
  overflow-wrap: anywhere;
}

.app-hash {
  display: block;
  padding: 10px 12px;
  border: var(--hairline);
  background: var(--bg-deep);
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  line-height: 1.7;
  color: var(--green-300);
  overflow-wrap: anywhere;
}

pre {
  margin: 0;
  padding: var(--sp-4);
  border: var(--hairline);
  background: var(--bg-deep);
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  line-height: 1.7;
  color: var(--text);
}

code { font-family: var(--font-mono); font-size: 0.94em; }

/* The metric table's third column is prose, so it must be allowed to wrap. */
.table td.is-wide,
.table th.is-wide { white-space: normal; }
.table th .label { display: block; margin-top: 2px; }

.app-metrics { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-4); }
.app-spark { display: block; width: 100%; max-width: 200px; margin-top: 6px; }

/* --------------------------------------------------------------------------------- lists and cards */

.app-cards { display: grid; gap: 1px; background: var(--line); border: var(--hairline); grid-template-columns: minmax(0, 1fr); }

@media (min-width: 640px) { .app-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .app-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.app-card {
  background: var(--bg);
  padding: var(--sp-5);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
  align-content: start;
}

.app-card__top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.app-card__id { font-family: var(--font-mono); font-size: var(--t-micro); letter-spacing: var(--track-wide); color: var(--green-400); }
.app-card__title { font-size: var(--t-h3); font-weight: 600; letter-spacing: -0.01em; color: var(--text); }
.app-card__text { font-size: var(--t-small); line-height: 1.65; color: var(--text-muted); }
.app-card__foot { margin-top: auto; display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }

.app-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  /* A link is a control unless it is a word inside a sentence, and the layout gate wants 40px on the
     smaller side of every control. A two word link like "36CR" is 33px wide without this. */
  min-width: 40px;
  justify-content: flex-start;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--green-300);
  text-decoration: none;
}

.app-link:hover { color: var(--text); }

.app-empty {
  padding: var(--sp-8) var(--sp-5);
  border: 1px dashed var(--line-bright);
  background: var(--bg-deep);
  color: var(--text-muted);
  font-size: var(--t-small);
  text-align: center;
}

.app-pager { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; justify-content: space-between; }

.app-rows { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1px; background: var(--line); border: var(--hairline); }

.app-rows__row {
  background: var(--bg);
  display: grid;
  gap: 6px;
  padding: 14px var(--sp-5);
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  color: inherit;
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease);
}

a.app-rows__row:hover { background: var(--surface); }
a.app-rows__row:hover .app-rows__cell--strong { color: var(--green-300); }

@media (min-width: 860px) {
  .app-rows__row { grid-template-columns: 70px minmax(0, 1.4fr) minmax(0, 1fr) 130px 120px; gap: var(--sp-4); }
}

.app-rows__cell {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.03em;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  min-width: 0;
  overflow-wrap: anywhere;
}

.app-rows__cell--id { color: var(--green-400); }
.app-rows__cell--strong { color: var(--text); }

/* ------------------------------------------------------------------------------------- the dialog */

.app-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-dialog);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  background: color-mix(in srgb, var(--bg-deep) 88%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.app-modal {
  width: 100%;
  max-width: 440px;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  border: var(--hairline-bright);
  background: var(--surface);
}

.app-modal__head {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: 14px var(--sp-5);
  border-bottom: var(--hairline);
}

.app-modal__head h2 { flex: 1 1 auto; font-size: var(--t-h3); }
.app-modal__body { padding: var(--sp-5); display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }

.app-wallet {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  width: 100%;
  min-height: 52px;
  padding: 8px 14px;
  background: var(--bg-deep);
  border: var(--hairline);
  border-radius: var(--r-xs);
  color: var(--text);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease);
}

.app-wallet:hover { border-color: var(--green-600); }
.app-wallet img { width: 26px; height: 26px; flex: 0 0 auto; border: var(--hairline); background: var(--surface-2); }
.app-wallet__who { flex: 1 1 auto; min-width: 0; font-size: var(--t-small); }

/* ------------------------------------------------------------------------------- the console strip */

.app-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  padding: 10px 14px;
  border: var(--hairline);
  background: var(--bg-deep);
}

.app-strip__label {
  font-family: var(--font-mono);
  font-size: var(--t-nano);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

.app-strip__spacer { flex: 1 1 auto; }

/* A toast the console raised because something went wrong. css/site.css owns the rest of .toasts. */
.toasts__item[data-kind="bad"] { border-color: var(--warn); color: var(--warn); }

/* ------------------------------------------------------------------- text that must not be shouted
 *
 * .app-link, .app-kv dt, .field__label and .app-bar__title all uppercase their contents, which is right
 * for a label and wrong for an identifier. A DOI printed `10.1126/SCIENCE.AEC2657` still resolves, because
 * DOI names are case insensitive, but it is not the published form, and on a page whose whole subject is
 * the identifier that is the thing that matters. Deposited titles are the depositors' own words and get the
 * same exemption. This class is the opt out, and it is the only way out of those rules in this file. */

.app-plain {
  text-transform: none;
  letter-spacing: normal;
}

/* On the tables that overflow at 320 to 390, which is the visual checker's finding 12: css/site.css now
   gives the shared `.table-scroll` a permanent slim scrollbar, a two layer fade and a `.scroll-hint`
   class, so there is nothing for this file to add and nothing here duplicates it. The console pages use
   that class as it is.

   The two rate columns of the credit table. They are the numbers the page exists to explain and they were
   forty pixels apart under two headers forty pixels apart, which reads as one column of four digits. */
.table .app-rate {
  min-width: 72px;
  padding-right: var(--sp-4);
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------- the colour legend */

.app-legend { padding: 0 14px 12px; display: grid; gap: 8px; }
.app-legend:empty { display: none; }

.app-legend__list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px var(--sp-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.app-legend__item { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }

.app-legend__swatch {
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
  border: 1px solid color-mix(in srgb, var(--text) 24%, transparent);
}

.app-legend__label {
  font-family: var(--font-mono);
  font-size: var(--t-nano);
  letter-spacing: var(--track-label);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------------- run log rows */

/* Who recorded a run. It is a label plus a truncated address, never a control and never copyable, so it
   cannot be mistaken for the coin's address, which is what SPEC section 2 rule 3 is protecting. */
.app-rows__sub { display: block; margin-top: 2px; color: var(--text-muted); font-size: var(--t-nano); letter-spacing: var(--track-label); }

/* A run whose result contradicts the first answer to its question. css/site.css owns .tag and .tag--on. */
.tag--warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 55%, transparent); }

/* The deposited title, verbatim, in a set the PDB writes half in sentence case and half in capitals. */
.app-card__summary { text-transform: none; }

/* The source block reads as a record rather than as prose, so its values keep the mono column. */
.app-kv--source dd { font-size: var(--t-micro); line-height: 1.65; }
.app-kv--source dd > span { display: grid; gap: 4px; }

/* ------------------------------------------------------------------------------------ small print */

.app-foot-note {
  margin-top: var(--sp-6);
  font-size: var(--t-micro);
  line-height: 1.7;
  color: var(--text-muted);
  max-width: var(--measure);
}
