:root {
  color-scheme: dark;
  --canvas: #161512;
  --surface-1: #211f1c;
  --surface-2: #2a2723;
  --surface-hover: #302d28;
  --ink: #d8d4cf;
  --ink-strong: #f1eee8;
  --ink-muted: #8f8a83;
  --border: #3a362f;
  --border-strong: #4a463f;
  --accent: #7fa650;
  --accent-hover: #94bc67;
  --accent-contrast: #141310;
  --focus-ring: #a8d47a;
  --won: #6da63b;
  --lost: #d84b4b;
  --draw: #4d91d9;
  --hot: #e8a33d;
  --warm: #b8862f;
  --cold: #67615a;
  --won-surface: linear-gradient(160deg, #2c4d12, #1d3309);
  --lost-surface: linear-gradient(160deg, #5a1717, #3b0e0e);
  --hot-surface: linear-gradient(160deg, #4a3413, #2e2009);
  --opening-sheen:
    linear-gradient(135deg, rgba(127, 166, 80, .12),
      rgba(232, 163, 61, .045) 60%);
  --opening-border: #46523a;
  --opening-ink: #e0b867;
  --shadow-board: 0 4px 18px rgba(0, 0, 0, .5);
  --scroll-thumb: #4b463f;
  --scroll-track: transparent;
  --move-destination: rgba(30, 90, 30, .55);
  --sq-l: #f0d9b5;
  --sq-d: #b58863;

  /* Compatibility aliases while the older AtomicDB views are modernized. */
  --bg: var(--canvas);
  --panel: var(--surface-1);
  --panel2: var(--surface-2);
  --text: var(--ink);
  --fg: var(--ink);
  --dim: var(--ink-muted);
}

html[data-theme="light"] {
  color-scheme: light;
  --canvas: #f5f2ea;
  --surface-1: #fffdf8;
  --surface-2: #ebe6dc;
  --surface-hover: #e3ddd1;
  --ink: #24211d;
  --ink-strong: #171512;
  --ink-muted: #655f57;
  --border: #d5cec2;
  --border-strong: #aaa092;
  --accent: #4d762e;
  --accent-hover: #385c1f;
  --accent-contrast: #fffdf8;
  --focus-ring: #2f6f20;
  --won: #4f7c1f;
  --lost: #b42318;
  --draw: #2566a3;
  --hot: #9a5b08;
  --warm: #8b620f;
  --cold: #81796f;
  --won-surface: linear-gradient(160deg, #e5f0d9, #f4f8ee);
  --lost-surface: linear-gradient(160deg, #f8dfdb, #fff4f1);
  --hot-surface: linear-gradient(160deg, #f6e5c7, #fff8eb);
  --opening-sheen:
    linear-gradient(135deg, rgba(93, 132, 54, .13),
      rgba(171, 105, 15, .055) 60%);
  --opening-border: #bcccae;
  --opening-ink: #70470b;
  --shadow-board: 0 5px 20px rgba(67, 55, 38, .22);
  --scroll-thumb: #b7ada0;
  --scroll-track: transparent;
}

@media (prefers-color-scheme: light) {
  html:not([data-theme]) {
    color-scheme: light;
    --canvas: #f5f2ea;
    --surface-1: #fffdf8;
    --surface-2: #ebe6dc;
    --surface-hover: #e3ddd1;
    --ink: #24211d;
    --ink-strong: #171512;
    --ink-muted: #655f57;
    --border: #d5cec2;
    --border-strong: #aaa092;
    --accent: #4d762e;
    --accent-hover: #385c1f;
    --accent-contrast: #fffdf8;
    --focus-ring: #2f6f20;
    --won: #4f7c1f;
    --lost: #b42318;
    --draw: #2566a3;
    --hot: #9a5b08;
    --warm: #8b620f;
    --cold: #81796f;
    --won-surface: linear-gradient(160deg, #e5f0d9, #f4f8ee);
    --lost-surface: linear-gradient(160deg, #f8dfdb, #fff4f1);
    --hot-surface: linear-gradient(160deg, #f6e5c7, #fff8eb);
    --opening-sheen:
      linear-gradient(135deg, rgba(93, 132, 54, .13),
        rgba(171, 105, 15, .055) 60%);
    --opening-border: #bcccae;
    --opening-ink: #70470b;
    --shadow-board: 0 5px 20px rgba(67, 55, 38, .22);
    --scroll-thumb: #b7ada0;
    --scroll-track: transparent;
  }
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  min-height: 100%;
  background: var(--canvas);
}

body {
  min-height: 100vh;
  background: var(--canvas);
  color: var(--ink);
  font: 16px/1.5 "Segoe UI", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a {
  color: var(--accent);
  text-decoration: none;
}

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

button,
input,
select,
textarea {
  color: inherit;
  font: inherit;
}

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

.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

:root {
  /* The bar: the .9rem padding either side of a 2.75rem row, plus the border.
     Only used to centre the switch against it -- the height itself comes from
     the row, below. */
  --header-row: 2.75rem;
  --header-height: calc(var(--header-row) + 1.8rem + 1px);
}

header {
  display: flex;
  align-items: center;
  gap: 1.35rem;
  padding: .9rem 1.4rem;
  background: var(--surface-1);
  border-bottom: 1px solid var(--border);
}

header h1 {
  flex: 0 0 auto;
  font-size: 1.25rem;
  letter-spacing: .5px;
}

/* The old 2.75rem switch stood in the top bar and set its height. The new one
   is out of flow, so the brand holds the row open instead. Holding it from an
   item rather than as a min-height on the bar keeps the browser's own padding
   rounding, and with it the exact height the bar had before.

   Scoped to the page bar on purpose: the plain `header h1` above also reaches
   the map page's <header class="tree-hero">, and a min-height there would push
   the whole move tree down. */
body > header > h1 {
  display: flex;
  align-items: center;
  min-height: var(--header-row);
}

.atomicdb-brand {
  color: inherit;
}

.atomicdb-brand:hover {
  color: inherit;
  text-decoration: none;
}

header h1 span {
  color: var(--hot);
}

header nav {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  flex-wrap: wrap;
  gap: .3rem 1rem;
  min-width: 0;
}

header nav a {
  color: var(--ink-muted);
  white-space: nowrap;
}

header nav a:hover {
  color: var(--ink);
}

/* Light / dark switch.

   The same control OpenBench uses: a bare sun/moon icon pinned to the
   top-right corner of the viewport, showing the theme a click would switch
   *to*, and hidden until the bootstrap script marks the document as
   script-capable. Only the button is shared -- it is painted from this
   app's own palette, not OpenBench's.

   Taking it out of flow is what puts it in the corner rather than at the end
   of the nav. The header reserves its height below, so the bar is unchanged. */

.theme-toggle {
  display: none;
  position: fixed;
  /* Same corner as OpenBench. OpenBench has no header bar, so it sits 10px
     down; here it lines up with the brand and the nav instead. */
  top: calc((var(--header-height) - 2rem) / 2);
  right: 16px;
  z-index: 1000;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: none;
  border-radius: 4px;
  background-color: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 180ms ease;
}

html.theme-js .theme-toggle {
  display: inline-flex;
}

.theme-toggle svg {
  display: block;
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.9;
}

.theme-toggle .theme-toggle-moon,
html[data-theme="light"] .theme-toggle .theme-toggle-sun {
  display: none;
}

html[data-theme="light"] .theme-toggle .theme-toggle-moon {
  display: block;
}

.theme-toggle:hover {
  background: var(--surface-hover);
  color: var(--accent);
}

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

/* Zona de identidad: sesion y avisos, arriba a la derecha de todas las
   paginas de AtomicDB.

   El hueco de la derecha no es decorativo: el interruptor de tema es
   `position: fixed` contra la esquina del viewport, fuera del flujo, asi que
   sin esa reserva la zona quedaria DEBAJO de el.  Va en la misma unidad que
   usa el interruptor (2rem de ancho + 16px de margen). */
.identity {
  display: flex;
  /* En escritorio la identidad NO cede: es compacta por naturaleza y cuando
     el nav envuelve, el flex encogia al unico encogible — el nombre — y un
     "belzedar" de ocho letras salia truncado a 719px.  Que envuelva el nav,
     que para eso envuelve.  En movil (≤560px) el tope y el encogimiento se
     reactivan en su media query: alli si compiten marca e identidad por la
     misma fila. */
  flex: 0 0 auto;
  align-items: center;
  gap: .9rem;
  padding-right: 2.4rem;
  font-size: .88rem;
}

.identity-link {
  color: var(--ink-muted);
  white-space: nowrap;
}

.identity-link:hover {
  color: var(--ink);
}

/* Registrarse es lo unico que esta cabecera PIDE, asi que es lo unico que
   lleva forma de boton.  Contorno y no relleno — por encima esta la marca y
   al lado el menu, y un boton macizo se comeria a los dos — y el mismo radio
   y el mismo borde que ``.reqbtn``, que es la forma que en esta casa
   significa "esto se pulsa". */
.identity-cta {
  padding: .28rem .7rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  color: var(--ink);
}

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

.identity-user {
  overflow: hidden;
  min-width: 0;
  max-width: 11rem;
  color: var(--ink-strong);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.identity-user:hover {
  color: var(--accent);
}

.bell-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.bell-form {
  display: flex;
}

.bell {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.bell:hover {
  background: var(--surface-hover);
  color: var(--accent);
}

.bell-icon {
  display: block;
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}

/* Sin avisos no hay insignia: la campana se queda como un icono discreto mas
   de la barra.  Con ellos, el unico punto de color de la cabecera. */
.bell-badge {
  position: absolute;
  top: -.1rem;
  right: -.25rem;
  min-width: 1.05rem;
  padding: 0 .25rem;
  border-radius: 999px;
  background: var(--accent);
  /* Anillo del color de la barra: despega la insignia de la campana sin
     sumar un color mas. */
  box-shadow: 0 0 0 2px var(--surface-1);
  color: var(--accent-contrast);
  font-size: .66rem;
  font-weight: 700;
  line-height: 1.05rem;
  text-align: center;
}

.bell-panel {
  position: absolute;
  top: calc(100% + .55rem);
  right: -.4rem;
  z-index: 900;
  overflow-y: auto;
  width: 21rem;
  max-width: calc(100vw - 1.6rem);
  max-height: min(60vh, 24rem);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--surface-1);
  box-shadow: var(--shadow-board);
  font-size: .84rem;
}

.bell-panel[hidden] {
  display: none;
}

.bell-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .6rem;
  padding: .55rem .8rem;
  border-bottom: 1px solid var(--border);
  color: var(--ink-muted);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.bell-markall button {
  padding: 0;
  border: none;
  background: none;
  color: var(--accent);
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}

.bell-markall button:hover {
  text-decoration: underline;
}

.bell-list {
  list-style: none;
}

.bell-item + .bell-item {
  border-top: 1px solid var(--border);
}

/* LEIDA = VISITADA, y se ve: lo pendiente va en NEGRITA con la barra de
   acento en el canto; lo ya visitado, en peso normal y atenuado.  El mismo
   idioma que un correo. */
.bell-item a {
  display: block;
  padding: .55rem .8rem;
  color: var(--ink-muted);
}

.bell-item.unseen a {
  color: var(--ink);
}

.bell-item.unseen .bell-line {
  font-weight: 600;
}

.bell-item a:hover {
  background: var(--surface-hover);
  text-decoration: none;
}

/* Lo no visto se marca con una barra en el canto, no con otro color de
   fondo: el aviso ya enlaza a una posicion y un segundo color competiria con
   el estado de hover. */
.bell-item.unseen a {
  box-shadow: inset .18rem 0 0 var(--accent);
}

.bell-line {
  display: block;
  overflow-wrap: anywhere;
}

.bell-line b {
  color: var(--ink-strong);
}

.bell-when,
.notif-when {
  display: block;
  margin-top: .12rem;
  color: var(--ink-muted);
  font-size: .74rem;
}

.bell-empty {
  padding: .7rem .8rem;
  color: var(--ink-muted);
  line-height: 1.45;
}

.bell-all {
  display: block;
  padding: .5rem .8rem;
  border-top: 1px solid var(--border);
  font-size: .78rem;
  text-align: center;
}

/* Pagina completa de avisos: la misma lista, sin la caja. */
.notif-lede {
  margin: -.35rem 0 1rem;
  font-size: .88rem;
}

.notif-list {
  list-style: none;
}

.notif-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .2rem .9rem;
  padding: .55rem .2rem .55rem .6rem;
  border-bottom: 1px solid var(--border);
}

.notif-row.unseen {
  box-shadow: inset .18rem 0 0 var(--accent);
}

/* El mismo idioma que la campana: pendiente en negrita, visitado atenuado. */
.notif-link {
  flex: 1 1 18rem;
  color: var(--ink-muted);
  overflow-wrap: anywhere;
}

.notif-row.unseen .notif-link {
  color: var(--ink);
  font-weight: 600;
}

.notif-markall {
  margin: 0 0 .8rem;
}

.notif-link b {
  color: var(--ink-strong);
}

.notif-row .notif-when {
  flex: 0 0 auto;
  margin-top: 0;
}

main {
  max-width: 1100px;
  margin: 1.4rem auto;
  padding: 0 1.2rem;
}

.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: .8rem;
  margin: 1rem 0 1.6rem;
}

.metric {
  padding: .7rem 1rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-1);
  text-align: center;
}

.metric .v {
  font-size: 1.7rem;
  font-weight: 600;
}

.metric .l {
  color: var(--ink-muted);
  font-size: .8rem;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: .6rem;
}

.tile {
  padding: .55rem .6rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  transition: transform .08s;
}

.tile:hover {
  transform: translateY(-2px);
  text-decoration: none;
}

.tile .mv {
  color: var(--ink);
  font-size: 1.05rem;
  font-weight: 700;
}

.tile .ev {
  color: var(--ink-muted);
  font-size: .85rem;
}

.tile.won {
  border-color: var(--won);
  background: var(--won-surface);
}

.tile.lost {
  border-color: var(--lost);
  background: var(--lost-surface);
}

.tile.draw {
  border-color: var(--draw);
}

.tile.hot {
  border-color: var(--hot);
  background: var(--hot-surface);
}

.tile.warm {
  border-color: var(--warm);
}

.chip {
  display: inline-block;
  min-width: 12px;
  height: 12px;
  margin-right: .45rem;
  border-radius: 50%;
}

.chip.won { background: var(--won); }
.chip.lost { background: var(--lost); }
.chip.draw { background: var(--draw); }
.chip.hot { background: var(--hot); }
.chip.warm { background: var(--warm); }
.chip.cold { background: var(--cold); }

table {
  width: 100%;
  border-collapse: collapse;
}

th {
  padding: .45rem .6rem;
  border-bottom: 1px solid var(--border);
  color: var(--ink-muted);
  font-size: .78rem;
  letter-spacing: 1px;
  text-align: left;
  text-transform: uppercase;
}

td {
  padding: .5rem .6rem;
  border-bottom: 1px solid var(--border);
}

tr:hover td {
  background: var(--surface-2);
}

.boardwrap {
  position: relative;
  width: min(440px, 100%);
}

.atomic-board.cg-wrap {
  width: 100%;
  aspect-ratio: 1;
  overflow: visible;
  box-shadow: var(--shadow-board);
}

.atomic-board cg-board {
  overflow: hidden;
  border-radius: 6px;
}

.atomic-board coords.files {
  left: 0;
}

.board {
  display: grid;
  grid-template-rows: repeat(8, 1fr);
  grid-template-columns: repeat(8, 1fr);
  width: 100%;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 6px;
  box-shadow: var(--shadow-board);
}

.sq {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.sq.sel {
  z-index: 1;
  outline: 3px solid var(--hot);
  outline-offset: -3px;
}

.sq.dest::before {
  position: absolute;
  z-index: 2;
  width: 26%;
  height: 26%;
  border-radius: 50%;
  background: var(--move-destination);
  content: "";
}

.sq.dest:has(img)::before {
  width: 92%;
  height: 92%;
  border: 4px solid var(--move-destination);
  background: none;
}

.raw {
  width: 0;
  min-width: 100%;
  max-height: 16rem;
  overflow-y: auto;
  padding: .5rem .7rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-1);
  color: var(--ink-muted);
  font: 11px/1.5 ui-monospace, Consolas, monospace;
  white-space: pre-wrap;
  word-break: break-all;
}

/* Cada linea multipv en su bloque: el separador sobrevive al minificador. */
.raw .rawline + .rawline {
  margin-top: .35rem;
}

.raw .rawdivider {
  margin-top: .5rem;
  opacity: .55;
  font-style: italic;
}

.raw .rawprior {
  opacity: .7;
}

details summary {
  margin: .6rem 0 .3rem;
  color: var(--ink-muted);
  font-size: .85rem;
  cursor: pointer;
}

.sq.l { background: var(--sq-l); }
.sq.d { background: var(--sq-d); }

.sq img {
  display: block;
  width: 88%;
  height: 88%;
}

.board-legal {
  width: min(440px, 100%);
  margin-top: .55rem;
}

.board-legal summary {
  margin: 0;
}

.board-legal nav {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  margin-top: .45rem;
}

.board-legal a {
  padding: .18rem .4rem;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font: 12px/1.4 ui-monospace, Consolas, monospace;
}

.coord {
  position: absolute;
  font-size: .62rem;
  font-weight: 700;
  opacity: .75;
  pointer-events: none;
}

.coord.file {
  right: 3px;
  bottom: 1px;
}

.coord.rank {
  top: 1px;
  left: 3px;
}

.sq.l .coord { color: var(--sq-d); }
.sq.d .coord { color: var(--sq-l); }

.cols {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.6rem;
  align-items: start;
}

.verdict {
  margin: .8rem 0;
  padding: .5rem .9rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-1);
  font-weight: 600;
}

.verdict.won { border-color: var(--won); }
.verdict.lost { border-color: var(--lost); }

.reqbtn {
  display: inline-block;
  padding: .4rem .9rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--surface-1);
  color: var(--ink);
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
}

.reqbtn:hover:not(:disabled) {
  border-color: var(--won);
}

.reqbtn:disabled {
  color: var(--ink-muted);
  cursor: default;
}

.reqrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .8rem;
  margin: .7rem 0;
}

/* Veredicto de un click que ya no compraba en ESTA posicion: se lee al lado
   del boton, no dentro, porque el boton tiene que seguir diciendo lo que
   hace. Ambos colores estan tomados de la paleta, asi que el par claro/oscuro
   sale del tema y no de un hex suelto. */
.reqnote {
  flex: 0 0 100%;   /* siempre su propia linea: es un veredicto, no un chip */
  color: var(--ink);
  font-size: .8rem;
}

.reqnote.spent {
  color: var(--hot);
}

/* Que linea compra "Verify PV". Va pegado al boton porque es su argumento y
   no un ajuste de despues, asi que comparte la fila y no abre otra: el
   ``gap`` de ``.reqrow`` los separaria como si fueran dos acciones. El
   desplegable toma prestada la forma de ``.reqbtn`` (mismo borde, misma
   superficie, mismo tamano de letra) para que la pareja se lea como un solo
   control, y ``max-width`` evita que una linea con nombre largo empuje la
   fila fuera de la columna del tablero. */
.pvlinechoice {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  max-width: 100%;
}

.pvlinelab {
  color: var(--ink-muted);
  font-size: .8rem;
}

.pvline {
  min-width: 0;      /* que encoja en un telefono en vez de ensanchar la fila */
  max-width: 12rem;
  padding: .35rem .5rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--surface-1);
  color: var(--ink);
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
}

.pvline:hover {
  border-color: var(--won);
}

/* Selector de profundidad del boton de peticion. Solo se pinta para quien
   puede elegir peldano, asi que estas reglas no tocan el explorador de nadie
   mas. Todo el bloque es flexible y ningun hijo tiene ancho intrinseco que
   defender (``min-width: 0`` en el propio deslizador), asi que en un telefono
   la linea se parte sola y el body nunca scrollea horizontal. */
.depthrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem .7rem;
  margin: .1rem 0 .55rem;
  max-width: min(26rem, 100%);
  font-size: .8rem;
}

.depthlab {
  color: var(--ink-muted);
}

/* El deslizador y su escala comparten columna: las etiquetas de los peldanos
   solo significan algo si caen debajo del recorrido, no debajo de la fila. */
.depthscale {
  display: flex;
  flex: 1 1 9rem;
  flex-direction: column;
  gap: .1rem;
  min-width: 0;
}

.depthscale input[type="range"] {
  width: 100%;
  min-width: 0;
  margin: 0;
  accent-color: var(--won);
}

.depthticks {
  display: flex;
  justify-content: space-between;
  color: var(--ink-muted);
  font-size: .72rem;
}

/* Siempre su propia linea, como ``.reqnote``: la columna del tablero no da
   para etiqueta + recorrido + escala + una cifra con coletilla ni en un
   escritorio ancho, asi que la segunda linea es una decision y no un reflujo
   que aparece a un ancho cualquiera. */
.depthnow {
  flex: 0 0 100%;
  color: var(--ink);
}

/* Linea de estado de la peticion viva de esta posicion: va DEBAJO del boton y
   del selector porque narra lo que ese boton compro, no lo que ofrece.  Un
   nombre de maquina no tiene un solo espacio donde partirse
   (``belzedar-ryzen-atomicdb#0``, la misma leccion que la tabla de maquinas),
   asi que se parte donde haga falta antes que empujar la pagina en un
   telefono. */
.livereq {
  margin: .1rem 0 .55rem;
  color: var(--ink);
  font-size: .8rem;
  overflow-wrap: anywhere;
}

.progress {
  margin: .9rem 0 1.1rem;
}

.pkpis {
  font-size: .85rem;
}

.queue {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.6rem;
  margin-bottom: .4rem;
}

/* Un item de rejilla no baja de su min-content por defecto, asi que una
   columna con una linea larga dentro empuja la pagina en vez de encogerse. */
.queue > * {
  min-width: 0;
}

/* El tope de 26rem es mas ancho que un telefono, y como la linea no se parte
   (nowrap + ellipsis) ese ancho se convierte en el min-content de la columna:
   medido, la rejilla de .queue pedia 361px dentro de 337 y sacaba el body
   entero fuera de la pantalla.  El tope cede ante el contenedor y la elipsis
   hace el resto; en pantalla grande no cambia nada. */
.qline {
  display: inline-block;
  max-width: min(26rem, 100%);
  overflow: hidden;
  vertical-align: bottom;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.milestone-line {
  display: inline-block;
  max-width: 100%;
  vertical-align: bottom;
}

.milestone-line summary {
  display: inline-block;
  margin: 0;
  border-radius: 3px;
  list-style: none;
  cursor: pointer;
}

.milestone-line summary::-webkit-details-marker {
  display: none;
}

.milestone-line summary::after {
  display: inline-block;
  margin-left: .38rem;
  border-width: .28rem 0 .28rem .4rem;
  border-style: solid;
  border-color: transparent transparent transparent currentColor;
  content: "";
  transform-origin: 40% 50%;
  transition: transform .12s ease;
}

.milestone-line[open] summary::after {
  transform: rotate(90deg);
}

.milestone-line summary:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}

.milestone-line[open] {
  display: block;
  margin: .3rem 0 0 6.6rem;
}

.milestone-full {
  display: block;
  font-size: .82rem;
  white-space: normal;
}

.fenbox {
  display: flex;
  gap: .6rem;
  margin: 0 0 1.2rem;
}

.fenbox input {
  flex: 1;
  max-width: 560px;
  padding: .45rem .7rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--surface-1);
  color: var(--ink);
  font: 12px/1.4 ui-monospace, Consolas, monospace;
}

.fenbox input:focus {
  border-color: var(--won);
  outline: none;
}

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

.feed {
  list-style: none;
}

.feed li {
  padding: .45rem .2rem;
  border-bottom: 1px solid var(--border);
  font-size: .92rem;
}

.feed .t {
  margin-right: .6rem;
  color: var(--ink-muted);
  font-size: .8rem;
}

h2 {
  margin: 1.6rem 0 .7rem;
  font-size: 1.1rem;
}

.dim {
  color: var(--ink-muted);
}

.crumb {
  margin-bottom: .6rem;
  color: var(--ink-muted);
  font-size: .9rem;
}

/* Los KPIs de salud de la prueba son para quien los busca, no para la
   portada entera: plegados por defecto (peticion del propietario, 29-jul). */
.proof-health {
  margin-bottom: .9rem;
}

.proof-health summary {
  cursor: pointer;
  font-size: .9rem;
}

.proof-health[open] summary {
  margin-bottom: .4rem;
}

.linebox {
  margin-bottom: .9rem;
  padding: .55rem .8rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-1);
  line-height: 1.9;
  /* A 90-ply line used to push the whole page sideways.  It wraps inside its
     own box; if a single token ever cannot wrap, the box scrolls rather than
     the document.  max-width keeps it honest inside a grid column, where
     min-width:auto would otherwise let the content set the track size. */
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
  overflow-x: auto;
}

.linebox a {
  /* Plies are separated by a REAL space in the markup, not by a margin: the
     clipboard carries text nodes only, and a margin-separated line pastes
     as "1. Nf3f62. e4d5".  Keep it that way. */
  padding: .1rem .3rem;
  border-radius: 4px;
  color: var(--ink);
}

.linebox a:hover {
  background: var(--surface-2);
  text-decoration: none;
}

.linebox a.cur {
  background: var(--accent);
  color: var(--accent-contrast);
  font-weight: 700;
}

.opening-card {
  margin: 0 0 1rem;
  padding: .75rem .9rem;
  border: 1px solid var(--opening-border);
  border-radius: 10px;
  background: var(--opening-sheen), var(--surface-1);
}

.opening-card h2 {
  margin: .12rem 0 0;
  overflow-wrap: anywhere;
  font-size: 1.15rem;
  line-height: 1.25;
}

.opening-kicker {
  display: block;
  color: var(--accent);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.opening-reference {
  margin: .45rem 0 0;
  overflow-wrap: anywhere;
  font-size: .83rem;
}

.opening-enters {
  display: block;
  color: var(--accent);
  font-size: .68rem;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

/* Propuesta publica de nombre de apertura y su moderacion */
.suggest-name {
  margin: 0 0 1.2rem;
  padding: .55rem .85rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-1);
  font-size: .88rem;
}

.suggest-name > summary {
  color: var(--ink-muted);
  cursor: pointer;
}

.suggest-name > summary:hover {
  color: var(--ink);
}

/* El nombre que se esta corrigiendo: fuera del form, que es flex y lo
   pondria en la misma fila que los campos. */
.suggest-current {
  margin: .6rem 0 0;
  font-size: .78rem;
}

.suggest-name form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: .7rem;
  margin-top: .8rem;
}

.suggest-name label {
  display: flex;
  flex: 1 1 15rem;
  flex-direction: column;
  gap: .25rem;
  color: var(--ink-muted);
  font-size: .78rem;
}

.suggest-name input {
  padding: .4rem .6rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--canvas);
  color: var(--ink);
  font: inherit;
  font-size: .85rem;
}

.suggest-name input:focus {
  border-color: var(--won);
  outline: none;
}

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

.suggest-name .dim {
  flex: 1 1 100%;
  font-size: .75rem;
}

.suggest-status {
  margin: .5rem 0 0;
  color: var(--hot);
  font-size: .82rem;
}

.suggest-status.ok {
  color: var(--won);
}

.suggest-actions {
  display: flex;
  gap: .4rem;
}

.reqbtn.ghost {
  color: var(--ink-muted);
}

.reqbtn.ghost:hover:not(:disabled) {
  border-color: var(--lost);
  color: var(--ink);
}

/* Campanas de exploracion: la activa arriba, con su progreso, y el buzon de
   propuestas mas abajo.  La tarjeta toma prestada la lamina de .opening-card
   porque es la otra cosa de la casa que dice "esto es lo importante de esta
   pagina", y asi las dos se leen como la misma familia en claro y en oscuro. */
.campaign-card {
  margin: 0 0 1.1rem;
  padding: .8rem .95rem;
  border: 1px solid var(--opening-border);
  border-radius: 10px;
  background: var(--opening-sheen), var(--surface-1);
}

.campaign-kicker {
  display: block;
  color: var(--accent);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.campaign-card .campaign-title {
  margin: .18rem 0 .5rem;
  overflow-wrap: anywhere;
  font-size: 1.12rem;
  line-height: 1.3;
}

/* La linea real debajo del titulo elegido: subtitulo, no titular. Solo
   aparece cuando dice algo que el titulo no dice ya. */
.campaign-line {
  margin: -.3rem 0 .1rem;
  overflow-wrap: anywhere;
  font-size: .84rem;
}

.campaign-row-san {
  margin-top: .12rem;
  overflow-wrap: anywhere;
  font-size: .78rem;
}

/* Flex con gap: la separacion entre cifras no depende de que sobreviva un
   salto de linea del HTML, que el minificador se lleva por delante. */
.campaign-stats {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem .9rem;
  font-size: .84rem;
}

.campaign-bar {
  overflow: hidden;
  height: .5rem;
  margin: .55rem 0 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
}

.campaign-bar > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--won);
}

.campaign-by {
  margin: .45rem 0 0;
  font-size: .78rem;
}

.campaign-lede {
  margin: -.35rem 0 .7rem;
  font-size: .85rem;
}

.campaign-status {
  margin: 0 0 .9rem;
  color: var(--accent);
  font-size: .88rem;
}

.campaign-list {
  list-style: none;
}

.campaign-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .3rem .9rem;
  padding: .5rem .2rem;
  border-bottom: 1px solid var(--border);
  font-size: .92rem;
}

.campaign-row-line {
  flex: 1 1 18rem;
  min-width: 0;
}

/* Un titulo elegido a mano puede ser mas ancho que la fila en un movil, y
   .qline se dimensiona por su contenido hasta 26rem — sin este tope se sale
   de la tarjeta.  Con el, manda la fila y los puntos suspensivos que .qline
   ya trae hacen el resto. */
.campaign-row-line .qline {
  max-width: 100%;
}

.campaign-row-votes {
  flex: 0 0 auto;
  font-size: .82rem;
}

/* Cada boton es su propio formulario (un POST, una accion): sin flex se
   apilarian, porque un <form> es un bloque. */
.campaign-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-top: .55rem;
}

.campaign-row .campaign-actions {
  margin-top: 0;
}

/* Con sesion iniciada la caja no ofrece campo de firma: dice el nombre con
   el que va a salir.  Ocupa el hueco de la etiqueta que sustituye. */
.campaign-credit {
  flex: 1 1 15rem;
  align-self: center;
  font-size: .78rem;
}

/* Marca sobria de "este numero lo respalda el subarbol, no la eval puntual" */
.backed-mark {
  margin-left: .35rem;
  padding: 0 .28rem;
  border: 1px solid var(--border-strong);
  border-radius: 3px;
  color: var(--ink-muted);
  font-size: .62rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  vertical-align: .08em;
  /* Con los plies DENTRO, el chip es una sola pieza: si el renglon se acaba
     salta entero, nunca partido en dos recuadros a medio borde. */
  white-space: nowrap;
  cursor: help;
}

/* El chip ES el salto al ply donde NACE el valor: el numero de plies vive
   dentro de la etiqueta y todo el chip se pincha.  En reposo no se distingue
   del chip mudo — la tinta apagada de .backed-mark manda sobre el color de
   enlace global; solo al apuntarlo toma el acento.  Una flecha suelta al lado
   se leia como el sube/baja de una clasificacion, no como un enlace. */
a.backed-mark {
  text-decoration: none;
  cursor: pointer;
}

a.backed-mark:hover,
a.backed-mark:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  /* Subrayado del TEXTO, no del borde: el recuadro ya se pinta de acento. */
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
}

/* Respaldo sin peso de busqueda: valor subido por una linea CAMINADA por un
   visitante, sin un solo analisis de motor debajo.  Borde discontinuo y tinta
   de aviso para que nadie lo lea como veredicto (caso Wolfram: 9994 "backed"
   sobre territorio sin explorar). */
.backed-mark.light {
  border-style: dashed;
  color: var(--warn, #b4762a);
  border-color: var(--warn, #b4762a);
}

footer {
  margin: 3rem 0 1rem;
  color: var(--ink-muted);
  font-size: .8rem;
  text-align: center;
}

html.theme-ready body,
html.theme-ready header,
html.theme-ready .metric,
html.theme-ready .tile,
html.theme-ready .raw,
html.theme-ready .verdict,
html.theme-ready .reqbtn,
html.theme-ready .pvline,
html.theme-ready .fenbox input,
html.theme-ready .linebox,
html.theme-ready .campaign-card,
html.theme-ready .opening-card {
  transition:
    background-color 180ms ease,
    border-color 180ms ease,
    color 180ms ease,
    box-shadow 180ms ease;
}

html.theme-ready .tile {
  transition:
    transform 80ms ease,
    background-color 180ms ease,
    border-color 180ms ease,
    color 180ms ease,
    box-shadow 180ms ease;
}

@media (max-width: 820px) {
  .cols,
  .queue {
    grid-template-columns: 1fr;
  }

  /* Una columna sola sigue sin poder encogerse por debajo de su contenido: el
     tablero pedia sus 381px dentro de un telefono de 375 y sacaba la pagina
     entera de la pantalla (medido en produccion, 401 de scroll en 375). El
     `min-width: 0` deja que la columna ceda, y como .boardwrap ya es
     `min(440px, 100%)` el tablero se encoge con ella. */
  .cols > * {
    min-width: 0;
  }
}

@media (max-width: 560px) {
  /* Dos filas en un telefono: marca e identidad arriba, menu debajo.  En una
     sola no caben — el menu ya necesitaba scroll horizontal el solo — y la
     identidad es lo que no puede quedar detras de ese scroll: es lo que la
     pagina quiere que alguien vea. */
  header {
    flex-wrap: wrap;
    gap: .72rem;
    padding: .58rem .75rem;
  }

  header h1 {
    order: 1;
    margin: 0;
  }

  header h1 a {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
  }

  header nav {
    order: 4;
    flex: 1 1 100%;
    flex-wrap: nowrap;
    gap: .85rem;
    overflow-x: auto;
    padding-bottom: .08rem;
    scrollbar-color: var(--scroll-thumb) var(--scroll-track);
    scrollbar-width: thin;
  }

  header nav a {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    font-size: .86rem;
  }

  .identity {
    order: 2;
    /* Un TOPE, no solo la capacidad de encoger: en un contenedor que hace
       wrap, el reparto en filas se decide con el tamano que cada elemento
       PIDE, antes de encoger a nadie.  Sin el, un nombre de usuario largo
       hacia que la identidad pidiera mas de lo que quedaba y el interruptor
       de tema se iba a una fila para el solo — un icono huerfano alineado a
       la izquierda, debajo de la marca.  Las 10rem reservadas son la marca,
       los huecos y el interruptor.  El encogimiento vuelve AQUI (en
       escritorio esta apagado a proposito). */
    flex-shrink: 1;
    min-width: 0;
    max-width: calc(100% - 10rem);
    gap: .6rem;
    margin-left: auto;
    padding-right: 0;
  }

  /* El panel deja de colgar de la CAMPANA y pasa a colgar de la BARRA.  A la
     izquierda del icono no caben 21rem en un telefono, asi que un panel
     anclado a su borde derecho se salia de la pantalla por la izquierda
     (medido: 136px fuera a 375px de ancho).  Colgando de la barra ocupa el
     ancho util entero y cae justo debajo, tenga la barra dos filas o tres. */
  header {
    position: relative;
  }

  .bell-wrap {
    position: static;
  }

  .bell-panel {
    top: calc(100% + .3rem);
    right: .75rem;
    left: .75rem;
    width: auto;
    max-width: none;
  }

  /* Un nombre largo no puede empujar a "Sign out" fuera de la pantalla. */
  .identity-user {
    max-width: 6.5rem;
  }

  /* In the header row, against the same edge. Fixed positioning is dropped
     on a phone: the bar already reaches the corner, and an icon floating
     there would sit on the scrolling nav. */
  header .theme-toggle {
    position: static;
    order: 3;
    flex: 0 0 auto;
    margin-left: 0;
  }

}

@media (max-width: 480px) {
  .milestone-line[open] {
    margin: .3rem 0 0;
  }
}

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

@media (forced-colors: active) {
  .theme-toggle,
  .bell {
    forced-color-adjust: auto;
    border: 1px solid ButtonText;
    background: ButtonFace;
    color: ButtonText;
  }

  /* En alto contraste el color de la insignia desaparece, asi que lo que
     tiene que sobrevivir es el borde: sin el, el numero flota sobre el
     icono. */
  .bell-badge {
    border: 1px solid ButtonText;
  }
}

/* Proof numbers sit beside the eval, deliberately quiet: they are scheduling
   information, not a verdict, and they must not out-shout the move state. */
.proofnums {
  font-variant-numeric: tabular-nums;
  font-size: .8rem;
  white-space: nowrap;
}

/* Pagina de contribuidor.  Reutiliza lo que ya existe — .metrics, .feed,
   .chip, table — y solo anade lo que no tenia sitio: los clubes de nodos, la
   grafica de dos semanas y la segunda linea de las celdas de la tabla de
   maquinas.  Un telefono no aguanta nueve columnas, asi que lo secundario
   (threads, hash, sistema, recuento de analisis) va DEBAJO de su celda en vez
   de a su lado. */
.contrib-name {
  font-size: 1.35rem;
}

.contrib-lede {
  max-width: 60ch;
  margin-bottom: .9rem;
  font-size: .9rem;
}

.contrib-since {
  margin-top: -.9rem;
  margin-bottom: 1.2rem;
  font-size: .85rem;
}

.contrib-badges {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-bottom: .2rem;
}

.contrib-badge {
  padding: .18rem .65rem;
  border: 1px solid var(--opening-border);
  border-radius: 999px;
  background: var(--opening-sheen);
  color: var(--opening-ink);
  font-size: .78rem;
  letter-spacing: .5px;
}

.contrib-section {
  margin-bottom: 2rem;
}

.contrib-sub {
  margin: 1.1rem 0 .4rem;
  color: var(--ink-muted);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.contrib-when {
  color: var(--ink-muted);
  font-size: .8rem;
}

/* Lo que se puede hacer con una peticion propia: adelantarla y retirarla.
   Enlaces de texto y no botones con caja, y por dos motivos que apuntan al
   mismo sitio.  En la fila de la cola, una caja por fila convertiria la lista
   en una botonera.  En la pagina de la posicion, los dos comparten renglon con
   la linea de estado, que es una frase, y ahi una caja competiria con los tres
   botones de peticion que estan justo encima.  Mismo peso visual entre ellos a
   proposito: son dos opciones de la misma peticion, no una principal y una
   secundaria.  Mismo tratamiento que el "Mark all read" de la campana, que es
   el otro POST minusculo del sitio. */
.queue-bump,
.queue-cancel {
  display: inline;
  margin-left: .5rem;
}

.queue-bump button,
.queue-cancel button,
.queue-receipt button {
  padding: 0;
  border: none;
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: .8rem;
  cursor: pointer;
}

.queue-bump button:hover,
.queue-cancel button:hover,
.queue-receipt button:hover {
  text-decoration: underline;
}

/* El recibo de lo que se acaba de hacer con la cola.  Lleva marca de color a
   la izquierda y no fondo: la seccion entera es una lista y un bloque relleno
   ahi dentro compite con lo que la persona ha venido a mirar. */
.queue-receipt {
  margin: .1rem 0 .8rem;
  padding-left: .6rem;
  border-left: 3px solid var(--accent);
  font-size: .9rem;
}

.queue-receipt form {
  display: inline;
  margin-left: .4rem;
}

/* Vaciar la cola entera.  Cerrado es un renglon; abierto ES el paso de
   confirmacion, con la cifra y las consecuencias antes del boton. */
.queue-clear {
  margin: .6rem 0 0;
  font-size: .85rem;
}

.queue-clear summary {
  color: var(--accent);
  cursor: pointer;
}

.queue-clear p {
  margin: .35rem 0;
  max-width: 46rem;
}

.queue-clear button {
  padding: .25rem .7rem;
  border: 1px solid var(--warm);
  border-radius: 4px;
  background: none;
  color: var(--warm);
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
}

.queue-clear button:hover {
  background: var(--warm);
  color: var(--bg);
}

.contrib-spec {
  margin-top: .15rem;
  font-size: .8rem;
}

.contrib-workers td {
  vertical-align: top;
}

/* Nodos por dia, sin una sola linea de JavaScript: catorce rectangulos y una
   linea de base.  ``preserveAspectRatio: none`` deja que se estire a lo ancho
   del sitio que haya — es una FORMA, no una lectura de valores exactos, y
   esos viven en el tooltip de cada barra. */
.spark {
  display: block;
  width: 100%;
  max-width: 420px;
  height: 72px;
}

.spark rect {
  fill: var(--accent);
}

.spark rect.quiet {
  fill: var(--border-strong);
}

.spark line {
  stroke: var(--border-strong);
  stroke-width: 1;
}

.contrib-sparknote {
  margin-top: .35rem;
  font-size: .82rem;
}

/* Con datos reales el min-content de las cinco columnas supera cualquier
   telefono (medido: 492px con seis maquinas zen4 y una linea "searching");
   partir texto no basta.  La tabla ancha se desplaza dentro de su propio
   contenedor y el body no scrollea horizontal jamas. */
.contrib-scroll {
  overflow-x: auto;
}

/* En un telefono, cinco columnas solo caben si el nombre de la maquina puede
   partirse: ``belzedar-ryzen-atomicdb#0`` no tiene un solo espacio y sin esto
   sacaba la tabla entera fuera de la pantalla (medido: 427px de tabla en 337
   de sitio).  Se parte el nombre y se aprieta el relleno; nada se esconde. */
@media (max-width: 560px) {
  .contrib-workers,
  .contrib-names {
    font-size: .84rem;
  }

  .contrib-workers th,
  .contrib-workers td,
  .contrib-names th,
  .contrib-names td {
    padding: .4rem .25rem;
  }

  /* La cabecera en versalitas con interletrado es lo que mas ancho gasta y lo
     que menos informa: cuatro palabras cortas no necesitan separacion extra
     para leerse. */
  .contrib-workers th,
  .contrib-names th {
    font-size: .7rem;
    letter-spacing: 0;
  }

  .contrib-workers td:first-child,
  .contrib-names td:first-child {
    overflow-wrap: anywhere;
  }

  .contrib-workers .contrib-spec,
  .contrib-names .contrib-spec {
    font-size: .74rem;
  }
}

/* Ranking de contribuidores de la portada.  Dos ventanas de la MISMA pregunta,
   una al lado de la otra, y casi todo prestado de lo que ya existe:
   .contrib-scroll para el desbordamiento, .contrib-sub para el titulillo y
   .contrib-spec para la segunda linea de una celda.  El reparto en columnas no
   necesita media query — la rejilla pide 22rem por columna PERO nunca mas de
   lo que hay, asi que en un telefono se apila sola y en 320px no desborda. */
.lb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
  gap: .6rem 1.6rem;
  align-items: start;
}

.lb-table {
  font-size: .92rem;
}

.lb-table td {
  vertical-align: top;
}

/* Las cifras alineadas a la derecha y con cifras de ancho fijo: una columna de
   nodos que no comparte punto decimal no se puede comparar de un vistazo, que
   es lo unico que una tabla asi tiene que dejar hacer. */
.lb-table .n {
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* La columna del puesto se encoge a su contenido en vez de repartirse el ancho
   como las demas; el resto de la fila lo agradece en un telefono. */
.lb-place {
  width: 1px;
}

/* El puesto, no una medalla dibujada: el numero dentro de un disco.  Los tres
   primeros se distinguen por borde y tinta — el dorado que el sitio ya usa
   para lo raro, el gris fuerte y el ambar — y del cuarto en adelante es texto
   apagado sin borde.  Dos segundos puestos pintan dos discos iguales. */
.lb-medal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.6rem;
  height: 1.6rem;
  padding: 0 .3rem;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--ink-muted);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
}

.lb-medal.first {
  border-color: var(--opening-ink);
  background: var(--opening-sheen);
  color: var(--opening-ink);
}

/* Tinta NEUTRA, no la mas fuerte que hay: lo que marca el primer puesto es el
   relleno, que ninguno de los otros dos tiene, y en tema claro un segundo
   puesto en --ink-strong es casi negro — el contraste mas alto de los tres, o
   sea la plata gritando por encima del oro. */
.lb-medal.second {
  border-color: var(--border-strong);
  color: var(--ink);
}

.lb-medal.third {
  border-color: var(--warm);
  color: var(--warm);
}

/* Un nombre de cuenta puede no tener un solo espacio y ser mas ancho que su
   columna; se parte antes que empujar la tabla. */
.lb-name {
  display: inline-block;
  max-width: 100%;
  overflow-wrap: anywhere;
  font-weight: 600;
}

/* Cuota de la flota, con la misma forma que la barra de campana.  El ancho es
   el porcentaje DE VERDAD y no una escala relativa al primero: en una flota
   repartida las barras salen finas, y eso es justamente lo que hay que ver.
   El minimo de dos pixeles es para que una cuota pequena siga siendo visible,
   igual que el dia flojo conserva su barra de un pixel en la grafica de la
   pagina de contribuidor. */
.lb-bar {
  overflow: hidden;
  height: .35rem;
  max-width: 12rem;
  margin: .3rem 0 .15rem;
  border-radius: 999px;
  background: var(--surface-2);
}

.lb-bar > span {
  display: block;
  min-width: 2px;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

.lb-foot {
  margin-top: .4rem;
  font-size: .8rem;
}

@media (max-width: 560px) {
  .lb-table {
    font-size: .84rem;
  }

  .lb-table th,
  .lb-table td {
    padding: .4rem .25rem;
  }

  .lb-table th {
    font-size: .7rem;
    letter-spacing: 0;
  }
}
