/* ══ La hoja de Atelier ═══════════════════════════════════════════════════
   Los tokens y las reglas de docs/DESIGN.md, aplicados de verdad. Se lee de
   arriba abajo: fuente, tokens, base, chrome, formularios y luego cada
   componente en el orden en que aparece en la aplicación. */

/* Archivo, autoalojada. El taller tiene mala cobertura y la fuente no puede
   depender de una petición externa. Un solo archivo variable por rango: pesos
   400-700 y el eje de anchura, que es la razón de elegirla — la matrícula se
   compone estrechando la misma familia. */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("/assets/archivo-latin-2348e0b4.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("/assets/archivo-latin-ext-f1d50082.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+2113, U+2C60-2C7F;
}

:root {
  --paper: #F6F7F5;
  --card: #FFFFFF;
  --ink: #16181C;
  --ink-soft: #5F6873;
  --rule: #DFE2DE;
  --plate: #123A8F;
  --space: 4px;

  /* Derivados: el azul de matrícula posado sobre el papel, para el fondo de
     lo que está seleccionado, y una línea más clara que --rule para separar
     dentro de una tarjeta sin cortarla en dos. */
  --plate-tint: #E7EDF9;
  --plate-deep: #0C2A6B;
  --hairline: #EBEDE9;
  /* Lo que todavía no ha pasado se lee igual que lo demás, solo que apagado:
     un peldaño futuro del color de una línea no se lee, y el cliente que abre
     esto quiere ver el camino entero. 4.5:1 sobre blanco. */
  --ink-faint: #6F7781;
  --alarm: #C2452D;

  /* Dos alturas y no cinco: una tarjeta apoyada en el papel y una tarjeta que
     flota por encima del flujo. La diferencia entre las dos es la jerarquía. */
  --lift-rest: 0 1px 1px rgb(22 24 28 / 4%), 0 2px 6px rgb(22 24 28 / 4%);
  --lift-float: 0 1px 2px rgb(22 24 28 / 6%), 0 12px 24px -8px rgb(22 24 28 / 18%);

  /* El radio crece con la jerarquía: una fila casi recta, una tarjeta redonda,
     un panel más, y la píldora solo para lo que se pulsa. */
  --r-row: 8px;
  --r-card: 14px;
  --r-panel: 20px;
  --r-pill: 999px;
}

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

body {
  margin: 0;
  padding: 0 calc(var(--space) * 5) calc(var(--space) * 26);
  background: var(--paper);
  color: var(--ink);
  font: 400 16px/1.55 "Archivo", system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  -webkit-text-size-adjust: 100%;
  text-rendering: optimizeLegibility;
}

main { max-width: 640px; margin: 0 auto; padding-top: calc(var(--space) * 6); }

/* El azul de matrícula es el único acento. Un enlace visitado no cambia de
   color: aquí no se navega por un sitio, se trabaja. */
a, a:visited { color: var(--plate); text-decoration-thickness: 1px; text-underline-offset: 2px; }

/* ── Tipografía ───────────────────────────────────────────────────────────
   Una sola familia. La jerarquía la hacen el peso y el tamaño, nunca una
   versalita espaciada encima del bloque. */
h1 {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.15;
  margin: 0 0 calc(var(--space) * 3);
}
h2 {
  font-size: 18px;
  font-weight: 650;
  letter-spacing: -0.01em;
  margin: calc(var(--space) * 9) 0 calc(var(--space) * 3);
}
.lede { margin: 0 0 calc(var(--space) * 6); color: var(--ink-soft); max-width: 56ch; }

/* Los datos que acompañan a un título no se cosen con puntos medios: se
   separan con espacio, y así cada idioma los parte donde le toca y ninguno
   arrastra una puntuación que no significa nada. Ver docs/DESIGN.md. */
.meta { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--space) * 1) calc(var(--space) * 4); color: var(--ink-soft); }
p.meta { margin: 0 0 calc(var(--space) * 6); }
span.meta, dd.meta { display: inline-flex; }
/* Una matrícula no se subraya: es una placa, y una placa con una raya debajo
   deja de parecerse a una placa. El enlace se nota al pasar por encima. */
.meta a { margin-right: 0; min-height: 0; text-decoration: none; }
.meta a:hover .plate { border-color: var(--plate); }
.hint { color: var(--ink-soft); font-size: 14px; }

/* ── El chrome ────────────────────────────────────────────────────────────
   Arriba el sitio donde se está; abajo, a dónde se puede ir. Ninguno de los
   dos se lleva atención: son el marco del trabajo. */
/* Las dos barras cruzan la pantalla entera, pero lo que llevan dentro va en la
   misma columna que el contenido. En un ordenador, una marca pegada al borde
   izquierdo con el título a cuatrocientos píxeles no parece la misma
   aplicación, y cuatro destinos repartidos en mil doscientos píxeles son cuatro
   botones de trescientos: eso no es un destino, es una pancarta. */
.bar-inner {
  display: flex;
  align-items: center;
  gap: calc(var(--space) * 3);
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}
.tabbar .bar-inner { gap: calc(var(--space) * 1); }

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: calc(var(--space) * 3);
  min-height: 60px;
  margin: 0 calc(var(--space) * -5);
  padding-inline: calc(var(--space) * 5);
  background: color-mix(in srgb, var(--paper) 88%, #fff);
  border-bottom: 1px solid var(--hairline);
  backdrop-filter: saturate(180%) blur(12px);
}
.bar-inner > * { min-width: 0; }

/* El nombre de la cuenta va al lado de la marca y se parte en dos líneas si
   hace falta: un taller no se llama igual de largo en cada sitio, y cortar un
   nombre con puntos suspensivos es peor que bajarlo una línea. */
.whose { color: var(--ink-soft); font-size: 15px; line-height: 1.2; }

/* La marca: el mismo icono que queda en la pantalla de inicio del móvil y el
   nombre al lado. Con el icono, la barra deja de ser una línea de texto y se
   reconoce de un vistazo cuál de las aplicaciones abiertas es esta. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--space) * 2);
  min-width: 0;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--plate);
}
.brand-icon { flex: none; border-radius: 7px; }
.brand-name { white-space: nowrap; }

/* Los iconos de la interfaz. Heredan el color de la fila y no tienen ninguno
   propio: un icono con color de marca dentro de una fila de texto se lee como
   un botón que no es. */
.icon { flex: none; display: block; }

/* ── El menú de la cabecera ───────────────────────────────────────────────
   Una sola cosa que se abre y lleva a cualquier sitio: se escribe arriba una
   matrícula o un nombre y lo encontrado sustituye al menú, y debajo están lo
   que se empieza, los sitios sin pestaña, la cuenta y la salida.

   Es un <details>, así que abre y cierra sin JavaScript; el controlador
   `popup` solo añade lo que se espera de un menú —fuera y Escape lo cierran,
   Ctrl+K lo abre, y el cursor cae ya en el campo—. Ver docs/DESIGN.md. */
.jump { position: relative; margin-left: auto; }
/* Del lado del cliente la campana ya empuja hasta el borde: si el menú empuja
   otra vez, la campana se queda plantada en mitad de la barra. */
.bell + .jump { margin-left: 0; }

.jump-open {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--space) * 2);
  min-height: 44px;
  padding: 0 calc(var(--space) * 2);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  list-style: none;
  cursor: pointer;
}
.jump-open::-webkit-details-marker { display: none; }
/* En un móvil el nombre del taller no cabe al lado de la marca y de la
   campana, y partido en dos líneas deja la barra torcida. Se queda la inicial,
   que es lo que distingue una cuenta de otra de un vistazo, y el nombre entero
   está dentro, en la primera línea del panel. */
@media (max-width: 519px) {
  .jump-open > .whose { display: none; }
}
.jump-open::after {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  margin-right: calc(var(--space) * 1);
  border-right: 2px solid var(--ink-soft);
  border-bottom: 2px solid var(--ink-soft);
  transform: translateY(-2px) rotate(45deg);
}
@media (hover: hover) {
  .jump-open:hover { background: var(--card); border-color: var(--rule); }
}
.jump-open:focus-visible { outline: 2px solid var(--plate); outline-offset: 2px; }
.jump[open] > .jump-open { background: var(--card); border-color: var(--rule); }

/* Las iniciales de la cuenta. No es una foto ni un color por persona: es la
   forma más corta de decir en cuál se está sin escribir el nombre dos veces,
   y en un móvil el nombre largo se queda fuera y esto no. */
.avatar {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: var(--r-pill);
  background: var(--plate-tint);
  color: var(--plate-deep);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* Quién es, dentro del panel: el mismo círculo del botón y el nombre entero
   al lado. No es un rótulo de bloque, es la respuesta a en qué cuenta estoy. */
.jump-whose {
  display: flex;
  align-items: center;
  gap: calc(var(--space) * 3);
  margin: 0 0 calc(var(--space) * 2);
  padding: calc(var(--space) * 2) calc(var(--space) * 3);
  color: var(--ink);
  font-size: 15px;
  font-weight: 650;
}
/* Y por eso mismo, donde el botón ya dice el nombre, esta línea no está: el
   nombre de la cuenta se escribe una vez, en el sitio donde cabe. */
@media (min-width: 520px) {
  .jump-whose { display: none; }
}

/* El panel flota por encima del flujo, así que lleva la sombra que flota. */
.jump-panel {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space) * 2);
  z-index: 20;
  width: max-content;
  min-width: 288px;
  max-width: min(340px, calc(100vw - var(--space) * 10));
  padding: calc(var(--space) * 2);
  border: 1px solid var(--rule);
  border-radius: var(--r-panel);
  background: var(--card);
  box-shadow: var(--lift-float);
}

/* El campo de buscar, con la lupa dentro. Es lo primero del panel porque es lo
   primero que se hace: en un taller con doscientos coches, llegar a la ficha
   escribiendo tres letras de la matrícula es más corto que cualquier lista. */
.jump-find { position: relative; margin: 0 0 calc(var(--space) * 2); }
.jump-find .icon {
  position: absolute;
  left: calc(var(--space) * 3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--ink-soft);
  pointer-events: none;
}
.jump-find input[type="search"] {
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding-left: calc(var(--space) * 9);
  border-radius: var(--r-row);
  background: var(--paper);
  font-size: 15px;
}
.jump-find input[type="search"]::-webkit-search-cancel-button { cursor: pointer; }

/* La tecla que abre el menú, dibujada como una tecla. En un móvil no hay
   teclado y no se dibuja: sería enseñar un atajo que nadie puede pulsar. */
.jump-key:empty { display: none; }
.jump-key {
  position: absolute;
  right: calc(var(--space) * 2);
  top: 50%;
  transform: translateY(-50%);
  padding: 2px calc(var(--space) * 1.5);
  border: 1px solid var(--rule);
  border-radius: 5px;
  background: var(--card);
  color: var(--ink-soft);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  pointer-events: none;
}
@media (max-width: 519px) {
  .jump-key { display: none; }
}

.jump-list { margin: 0; padding: 0; list-style: none; }
.jump-list + .jump-list { margin-top: calc(var(--space) * 2); padding-top: calc(var(--space) * 2); border-top: 1px solid var(--hairline); }
.jump-list form { margin: 0; }

/* Una fila del menú es una fila: radio de fila, no de píldora, y ocupa el
   ancho entero para que el dedo no tenga que apuntar. El icono ayuda a
   encontrarla la cuarta vez; la palabra la dice siempre. */
.jump-row {
  display: flex;
  align-items: center;
  gap: calc(var(--space) * 3);
  width: 100%;
  min-height: 44px;
  padding: 0 calc(var(--space) * 3);
  border: 0;
  border-radius: var(--r-row);
  background: transparent;
  box-shadow: none;
  color: var(--ink);
  font-size: 15px;
  font-weight: 550;
  text-align: left;
  text-decoration: none;
}
.jump-row .icon { flex: none; color: var(--ink-soft); }
.jump-row .plate { flex: none; }
.jump-what { flex: 1; min-width: 0; }
.jump-row:hover { background: var(--paper); color: var(--ink); border: 0; }
.jump-row:hover .icon { color: var(--plate); }
.jump-row:focus-visible { outline: 2px solid var(--plate); outline-offset: -2px; }
.jump-row.current { background: var(--plate-tint); color: var(--plate-deep); font-weight: 650; }
.jump-row.current .icon { color: var(--plate-deep); }

/* El número de una fila del menú es el mismo de la campana: el mismo dato dos
   veces en la misma barra no puede tener dos aspectos. */
.jump-row .count {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--plate);
  color: #fff;
  font-size: 13px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

/* No haber encontrado nada se dice, y se dice con lo que se buscó delante: así
   se ve la errata sin volver a mirar el campo. */
.jump-nothing {
  margin: 0;
  padding: calc(var(--space) * 3);
  color: var(--ink-soft);
  font-size: 15px;
}

/* La campana del cliente. Un número y ninguna insignia roja: una marca
   permanente deja de significar nada al tercer día. Ver docs/DESIGN.md. */
.bell { margin-left: auto; }
.bell-link {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--space) * 1.5);
  padding: 0 calc(var(--space) * 2);
  border-radius: var(--r-pill);
  color: var(--ink-soft);
  font-size: 15px;
  text-decoration: none;
}
@media (hover: hover) {
  .bell-link:hover { background: var(--card); color: var(--plate); }
}
.bell-link.pending { color: var(--ink); font-weight: 650; }
.bell-link .count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--plate);
  color: #fff;
  font-size: 13px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.tabbar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 10;
  display: flex;
  gap: calc(var(--space) * 1);
  padding: calc(var(--space) * 2) calc(var(--space) * 5);
  padding-bottom: max(calc(var(--space) * 2), env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--card) 92%, transparent);
  border-top: 1px solid var(--hairline);
  backdrop-filter: saturate(180%) blur(12px);
}
.tabbar a {
  flex: 1;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 calc(var(--space) * 2);
  border-radius: var(--r-pill);
  color: var(--ink-soft);
  font-size: 14px;
  font-weight: 550;
  text-align: center;
  text-decoration: none;
}
.tabbar a.current { background: var(--plate-tint); color: var(--plate-deep); font-weight: 650; }

/* El número que lleva un destino: lo que espera en él. Va pegado al nombre, en
   la misma tipografía y con tabular-nums para que no baile al actualizarse por
   Turbo. Si es cero no se dibuja. Ver docs/DESIGN.md. */
.tabbar a .count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  margin-left: calc(var(--space) * 1.5);
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--plate);
  color: #fff;
  font-size: 12px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.tabbar a.current .count { background: var(--plate-deep); }

/* En un móvil de 375 px, cuatro destinos y un número no caben en una línea de
   texto de 14 px: el nombre se queda y el número baja a su lado, nunca se
   corta con puntos suspensivos. Ver docs/DESIGN.md. */
@media (max-width: 420px) {
  .tabbar a { flex-wrap: wrap; font-size: 13px; }
  .tabbar a .count { margin-left: calc(var(--space) * 1); }
}

/* Un panel es una tarjeta sin filo de etapa: lo que se agrupa y se lee, no lo
   que está en una etapa. El radio es el de un panel, no el de una tarjeta. */
.panel {
  margin-bottom: calc(var(--space) * 4);
  padding: calc(var(--space) * 5);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  background: var(--card);
  box-shadow: var(--lift-rest);
}
.panel > :first-child { margin-top: 0; }
.panel > :last-child { margin-bottom: 0; }
/* El título de una sección va dentro de su tarjeta, que es de lo que es
   título. Sin esto se despega del contenido que encabeza. */
.panel > h2 { margin-top: 0; }
.panel-name { margin: 0 0 calc(var(--space) * 1); font-size: 20px; font-weight: 700; letter-spacing: -0.02em; }
.panel-price { margin: 0 0 calc(var(--space) * 4); font-size: 17px; font-weight: 650; color: var(--ink-soft); }

/* ── La consola de la plataforma ──────────────────────────────────────────
   Quien lleva el negocio no está en un taller con las manos sucias: está
   sentado, delante de una pantalla ancha, y lo que mira son listas de cuentas
   con seis datos por fila. Por eso aquí la navegación va arriba y entera, no
   abajo y en cuatro, y la columna es más ancha que la de un taller: 640 px
   para una fila de seis datos es una fila partida en tres.

   El papel, los tokens y la tipografía son los mismos. No se inventa un tema
   oscuro de administrador: es el mismo producto visto desde el otro lado.
   Ver docs/SPEC.md 18 y docs/DESIGN.md. */
body.console { padding-bottom: calc(var(--space) * 12); }
/* Aquí se mira sentado y en una pantalla ancha: la columna de un móvil deja
   media pantalla en blanco y obliga a abrir una ficha para ver lo que cabría
   al lado. El resto del producto no cambia. */
body.console main { max-width: 900px; }

/* La cabecera es una sola pieza: quién es, dónde se está, la búsqueda y las
   secciones. Dos barras pegadas una encima de otra, cada una con su fondo
   difuminado y su línea, se leían como dos aplicaciones apiladas. */
.console-bar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: block;
  min-height: 0;
  padding-block: 0;
}
.console-bar .bar-inner { max-width: 900px; }

.console-head {
  flex-wrap: wrap;
  gap: calc(var(--space) * 3);
  min-height: 60px;
}

/* La marca y dónde se está, en una sola pieza que lleva a la consola. El
   nombre de la plataforma no es un enlace aparte: es la coletilla de la marca,
   como el nombre del taller lo es del otro lado. */
.console-brand { display: inline-flex; align-items: baseline; gap: calc(var(--space) * 2); }
.console-where { color: var(--ink-soft); font-size: 15px; font-weight: 400; letter-spacing: 0; }

/* Buscar desde donde se esté. En un móvil la caja se lleva el sitio que sobra
   y el menú se queda a la derecha; en un ordenador no crece más de la cuenta,
   porque una dirección de correo cabe de sobra en 280 px. */
/* En un móvil la marca y el menú no dejan sitio a una caja de texto: la
   búsqueda baja a su propia línea entera, que es donde se escribe cómodo. */
.console-find { order: 3; flex: 1 0 100%; min-width: 0; padding-bottom: calc(var(--space) * 2); }
.console-find input[type="search"] { width: 100%; min-height: 44px; }
@media (min-width: 560px) {
  .console-find { order: 0; flex: 1 1 auto; max-width: 280px; margin-left: auto; padding-bottom: 0; }
  .console-find input[type="search"] { min-height: 40px; }
}
.console-bar .jump { margin-left: 0; }

.console-nav { padding-bottom: calc(var(--space) * 2); }
/* Ocho secciones en un móvil son cuatro filas de chrome antes de la primera
   cifra. Se recorren de lado, como la banda de prioridad de Aujourd'hui, y en
   un ordenador caben todas a la vez. */
.console-nav .bar-inner {
  gap: calc(var(--space) * 1);
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.console-nav .bar-inner::-webkit-scrollbar { display: none; }
/* Sin esto, ocho secciones se encogen unas sobre otras en vez de correrse. */
.console-nav a { flex: none; white-space: nowrap; }
@media (min-width: 760px) {
  .console-nav .bar-inner { flex-wrap: wrap; overflow-x: visible; }
}
.console-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 calc(var(--space) * 3);
  border-radius: var(--r-pill);
  color: var(--ink-soft);
  font-size: 15px;
  font-weight: 550;
  text-decoration: none;
}
@media (hover: hover) {
  .console-nav a:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); color: var(--ink); }
}
.console-nav a.current { background: var(--plate-tint); color: var(--plate-deep); font-weight: 650; }

/* El número que lleva una sección: lo que espera en ella, y solo donde algo
   espera de verdad. Un contador en Comptes sería el tamaño de la base de
   datos, que no espera a nadie. */
.console-nav a .count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  margin-left: calc(var(--space) * 2);
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--plate);
  color: #fff;
  font-size: 12px;
  font-weight: 650;
}
.console-nav a.current .count { background: var(--plate-deep); }

/* ── Lo que pide una decisión hoy ─────────────────────────────────────────
   La primera sección del resumen, y la que hace que la consola sirva para
   trabajar y no solo para mirar. Cada línea lleva a la pantalla donde se
   resuelve; ninguna está a cero. */
.attention { margin-bottom: calc(var(--space) * 10); }
.attention h2 { margin-top: calc(var(--space) * 7); }

.alerts {
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--lift-rest);
}
.alerts li { padding: 0 calc(var(--space) * 4); border-bottom: 1px solid var(--hairline); }
.alerts li:last-child { border-bottom: 0; }
.alerts li a {
  display: flex;
  align-items: baseline;
  gap: calc(var(--space) * 3);
  min-height: 52px;
  padding: calc(var(--space) * 2) 0;
  color: var(--ink);
  text-decoration: none;
}
/* El número delante y grande: se cuenta antes de leer qué es. */
.alert-count {
  min-width: 2ch;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.alert-what { font-weight: 550; }
@media (hover: hover) {
  .alerts li a:hover .alert-what { color: var(--plate); text-decoration: underline; text-underline-offset: 3px; }
}

/* Cuando no hay nada, se dice con la misma calma con la que se diría en voz
   alta. Ni una tarjeta vacía ni un dibujo: una frase. */
.all-well { margin: 0; font-size: 18px; font-weight: 600; }

/* ── La ficha de una cuenta ───────────────────────────────────────────────
   Lo que se decide a la izquierda —la fórmula, el acceso— y lo que se consulta
   a la derecha —quién entra, qué ha pasado—. En una pantalla ancha caben las
   dos cosas a la vez, que es justo lo que hace falta para contestar a alguien
   que escribe: se lee el registro sin perder de vista el botón. */
.record-state { margin: calc(var(--space) * -1) 0 calc(var(--space) * 6); }
.record-state .state { border: 1px solid var(--rule); }
.record-state .state.live { border-color: transparent; }

main > .figures + .record { margin-top: calc(var(--space) * 6); }

.record { display: grid; gap: calc(var(--space) * 4); align-items: start; }
@media (min-width: 760px) {
  .record { grid-template-columns: minmax(0, 1fr) minmax(0, 320px); }
}
.record .panel:last-child { margin-bottom: 0; }
.record .panel h2:first-child { margin-top: 0; }
/* Dentro de un panel, el registro no necesita la primera línea separada del
   título: el panel ya es la separación. */
.record .rows li:first-child { padding-top: 0; }

/* Acotar en una consola ancha son tres cosas en una línea, no dos y media.
   En un móvil sigue siendo una debajo de otra. */
@media (min-width: 760px) {
  body.console .filters { grid-template-columns: repeat(3, 1fr); }
}

/* Un par de nombre y cifra separados por novecientos píxeles deja de ser un
   par: el ojo no los junta. En la consola la lista de dos columnas se queda
   del ancho en el que se lee de un vistazo. */
body.console main > .totals, body.console section > .totals { max-width: 480px; }

/* El nombre del mes cabe entero en una consola: partir `septiembre 2026` en
   dos líneas para ahorrar treinta píxeles de una pantalla de novecientos es
   ahorrar donde no falta. */
@media (min-width: 560px) {
  body.console .bars li { grid-template-columns: 120px 1fr 40px; }
}

/* De quién habla la pantalla cuando se llega a ella desde una cuenta, y por
   dónde se vuelve al registro entero. Sin esto se llegaba y no se salía. */
.narrowed { margin: calc(var(--space) * -2) 0 calc(var(--space) * 5); }

/* Las fórmulas se comparan. Una debajo de otra obliga a recordar lo que decía
   la anterior; al lado, la diferencia se ve. En un móvil vuelven a la pila. */
.plan-cards { display: grid; gap: calc(var(--space) * 4); align-items: start; }
@media (min-width: 760px) {
  .plan-cards { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
  .plan-cards .panel { margin-bottom: 0; }
}

/* El veredicto de la pantalla de salud. Una frase, y el punto de delante dice
   lo mismo que la frase para quien no distingue el verde del óxido. */
.verdict {
  display: flex;
  align-items: center;
  gap: calc(var(--space) * 2);
  margin: 0 0 calc(var(--space) * 8);
  font-size: 18px;
  font-weight: 600;
}
.verdict::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: var(--r-pill);
  background: currentcolor;
}
.verdict.well { color: var(--stage-ready); }
.verdict.unwell { color: var(--alarm); }

/* La salida. Es lo único de esta barra que lleva a otra aplicación, así que se
   separa del nombre y no del todo: nadie tiene que buscarla. */
.leave { margin-left: auto; font-size: 15px; font-weight: 550; white-space: nowrap; }

/* Los chips de la lista de cuentas. Cada uno dice a la vez qué hay y qué se
   está mirando: el número contesta la pregunta antes de hacerla. */
.chips { display: flex; flex-wrap: wrap; gap: calc(var(--space) * 2); margin-bottom: calc(var(--space) * 5); }
.chip, .chip:visited {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--space) * 2);
  min-height: 40px;
  padding: 0 calc(var(--space) * 4);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--ink-soft);
  font-size: 15px;
  font-weight: 550;
  text-decoration: none;
}
.chip:hover { border-color: var(--ink-soft); color: var(--ink); }
.chip.current, .chip.current:visited { background: var(--plate-tint); border-color: transparent; color: var(--plate-deep); font-weight: 650; }
.chip .count { color: inherit; opacity: 0.7; font-variant-numeric: tabular-nums; }

/* La lista de cuentas: la casilla a la izquierda y todo lo demás en una
   columna, para que el nombre, el estado y la dirección se lean en vertical
   sin que nada salte de sitio al marcar. */
.rows.accounts > li { display: flex; align-items: flex-start; gap: calc(var(--space) * 3); }
.account-line { display: flex; flex-direction: column; gap: calc(var(--space) * 1); min-width: 0; flex: 1; }
.rows .pick { display: flex; align-items: center; min-height: 44px; }
.rows input[type="checkbox"] { width: 20px; height: 20px; accent-color: var(--plate); }
.pick-all label { display: flex; align-items: center; gap: calc(var(--space) * 3); min-height: 44px; font-size: 15px; font-weight: 550; color: var(--ink-soft); }
/* Lo que está parado se dice con palabra y con color, no solo con color. */
.meta .held { color: var(--alarm); font-weight: 650; }

/* La barra de lo marcado. Se queda pegada abajo porque es donde está la mano
   cuando se acaba de marcar la última fila, y no existe si no hay nada. */
.picked-bar {
  position: sticky;
  bottom: calc(var(--space) * 3);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--space) * 3);
  margin-top: calc(var(--space) * 4);
  padding: calc(var(--space) * 3) calc(var(--space) * 4);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  background: var(--card);
  box-shadow: var(--lift-float);
}
/* `display: flex` gana al `[hidden]` del navegador, y la barra salía con la
   selección vacía. */
.picked-bar[hidden] { display: none; }
.picked-count { margin: 0; font-size: 15px; font-weight: 650; }
.picked-does { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--space) * 2); margin-left: auto; }
.picked-plan { display: flex; align-items: center; gap: calc(var(--space) * 2); }
.picked-plan select { width: auto; min-height: 44px; }

/* Un panel con precio a la derecha y el nombre a la izquierda: son lo mismo
   leído de dos maneras y van en la misma línea. */
.panel-top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: calc(var(--space) * 3); }
.panel-top .panel-name, .panel-top .panel-price { margin-bottom: calc(var(--space) * 4); }
.panel-does { margin: calc(var(--space) * 4) 0 0; }

/* Un enlace que hace de botón. Lo es cuando lleva a la pantalla de crear algo:
   no cambia nada por sí mismo, así que no puede ser un botón de verdad. */
.button-link, .button-link:visited {
  display: inline-flex;
  align-items: center;
  min-height: 46px;
  padding: 0 calc(var(--space) * 5);
  border: 1px solid var(--plate);
  border-radius: var(--r-pill);
  background: var(--plate);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--lift-rest);
}
.button-link:hover { background: var(--plate-deep); border-color: var(--plate-deep); color: #fff; }
/* La fila de lo que se puede hacer en una pantalla: modificar, borrar, empezar
   otra cosa. Todo lo que hay dentro se dibuja igual —la píldora blanca con un
   filo—, venga de un enlace o de un formulario: al pulgar le da igual cuál de
   los dos es, y dos cosas que se pulsan igual no pueden parecer distintas. */
.does {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--space) * 3);
  margin: calc(var(--space) * 6) 0;
}
.does form { margin: 0; }
.does > a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: 0;
  padding: 0 calc(var(--space) * 4);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--ink);
  font-weight: 550;
  text-decoration: none;
  box-shadow: var(--lift-rest);
}
.does > a:hover { border-color: var(--ink-soft); }
/* Lo que empieza algo sí es el azul: en una fila de cuatro píldoras blancas,
   la que abre trabajo nuevo es la que se busca. */
.does > a.button-link { border-color: var(--plate); color: #fff; }
.does button, .does input[type="submit"] { min-height: 44px; }

/* Un grupo de campos con su título: los límites de una fórmula son cuatro
   preguntas de la misma clase y se leen juntas. */
.fields, .picks {
  display: flex;
  flex-direction: column;
  gap: calc(var(--space) * 2);
  margin: calc(var(--space) * 2) 0;
  padding: calc(var(--space) * 4);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
}
.fields legend, .picks legend { padding: 0 calc(var(--space) * 2); font-size: 14px; font-weight: 550; color: var(--ink-soft); }
.fields label { font-size: 14px; font-weight: 550; color: var(--ink-soft); }

/* En qué anda una promoción, en una palabra y en un color. */
.state {
  display: inline-flex;
  align-items: center;
  padding: 0 calc(var(--space) * 2);
  border-radius: var(--r-pill);
  background: var(--paper);
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 650;
}
.state.live { background: var(--plate-tint); color: var(--plate-deep); }
.state.revoked, .state.expired { color: var(--alarm); }

/* Doce meses en barras. Una lista de doce números no dice si sube o baja, y es
   lo único que se le pregunta a esa sección. La barra es decoración: el número
   está escrito al lado y se lee igual sin ver el color. */
.bars { display: flex; flex-direction: column; gap: calc(var(--space) * 2); margin: 0; padding: 0; list-style: none; }
.bars li { display: grid; grid-template-columns: 80px 1fr 32px; align-items: center; gap: calc(var(--space) * 3); }
.bar-name { color: var(--ink-soft); font-size: 14px; }
.bar-track { height: 10px; border-radius: var(--r-pill); background: var(--hairline); }
/* El relleno es un SVG vacío al que la vista le da el ancho como atributo: la
   política de contenido no deja pasar un `style=`, y con uno todos los meses
   se dibujaban llenos. El color y el radio se los pone aquí. */
.bar-fill { display: block; height: 10px; border-radius: var(--r-pill); background: var(--plate); }
.bar-count { font-size: 14px; font-weight: 650; text-align: right; font-variant-numeric: tabular-nums; }

/* ── Formularios ──────────────────────────────────────────────────────────
   Se rellenan de pie, con el móvil en una mano. Campos altos, bordes
   tranquilos, y el foco siempre visible. */
.stack { display: flex; flex-direction: column; gap: calc(var(--space) * 2); max-width: 420px; }
/* Un botón mide lo que dice, no lo que mide el formulario. Estirado al ancho
   de la columna deja de parecer un botón y parece una barra. Ver DESIGN.md. */
.stack input[type="submit"], .stack button[type="submit"] { align-self: flex-start; }
.stack label { font-size: 14px; font-weight: 550; color: var(--ink-soft); }
.stack.wide { max-width: 640px; }

/* Dos campos cortos en una línea. Un código postal y una ciudad son un dato
   partido en dos, y uno debajo del otro los separa más de lo que están. En un
   móvil vuelven a la pila, porque ahí no caben dos. */
.two-up { display: grid; grid-template-columns: 1fr; gap: calc(var(--space) * 2); }
.two-up .field { display: flex; flex-direction: column; gap: calc(var(--space) * 1); }
@media (min-width: 480px) {
  .two-up { grid-template-columns: 1fr 1fr; gap: calc(var(--space) * 3); }
}

input[type="text"], input[type="email"], input[type="number"], input[type="password"],
input[type="datetime-local"], input[type="date"], input[type="time"], input[type="tel"],
input[type="search"], input[type="url"], select, textarea {
  width: 100%;
  min-height: 46px;
  padding: calc(var(--space) * 2) calc(var(--space) * 3);
  border: 1px solid var(--rule);
  border-radius: var(--r-row);
  background: var(--card);
  color: inherit;
  font: inherit;
  box-shadow: inset 0 1px 1px rgb(22 24 28 / 3%);
}
textarea { min-height: 96px; line-height: 1.5; resize: vertical; }
/* Un desplegable se queda nativo a propósito: en un móvil abre la rueda del
   sistema, que se acierta con el pulgar sucio y a la primera, y ninguna lista
   escrita a mano se le acerca. Lo que se cambia es cómo se ve: la misma caja
   que un campo y el mismo galón que el menú de la cabecera, dibujado en el
   fondo porque un select no admite pseudoelementos. */
select {
  appearance: none;
  padding-right: calc(var(--space) * 10);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%235F6873' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-position: right calc(var(--space) * 4) center;
  background-size: 12px 8px;
  background-repeat: no-repeat;
  cursor: pointer;
}
@media (hover: hover) {
  select:hover { border-color: var(--ink-soft); }
}
input:focus, select:focus, textarea:focus { border-color: var(--plate); }

/* El botón es una píldora: se ve que se pulsa antes de leer lo que dice, y se
   hunde un pelo al pulsarla. */
input[type="submit"], button {
  min-height: 46px;
  padding: 0 calc(var(--space) * 5);
  border: 1px solid var(--plate);
  border-radius: var(--r-pill);
  background: var(--plate);
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--lift-rest);
}
input[type="submit"]:hover, button:hover { background: var(--plate-deep); border-color: var(--plate-deep); }
input[type="submit"]:active, button:active { transform: translateY(1px); box-shadow: none; }

.quiet button, button.quiet, button.small.quiet, input[type="submit"].quiet {
  background: var(--card);
  color: var(--ink);
  border-color: var(--rule);
  font-weight: 550;
}
.quiet button:hover, button.quiet:hover, input[type="submit"].quiet:hover { background: var(--paper); border-color: var(--ink-soft); }

.triage button.small, button.small { min-height: 44px; padding: 0 calc(var(--space) * 4); font-size: 14px; }

/* Lo que no se deshace. Va al final de la pantalla, detrás de un pliegue, y con
   una sola línea roja que la separa del resto: --alarm es lo que se ha roto, y
   un borrado a propósito todavía no lo está. Ver docs/DESIGN.md. */
.grave { margin-top: calc(var(--space) * 12); padding-top: calc(var(--space) * 6); border-top: 1px solid var(--alarm); }
.grave h2 { color: var(--alarm); }
.grave-door { margin: calc(var(--space) * 4) 0; }
.grave details { margin-top: calc(var(--space) * 4); }
.grave details > summary, .rows details > summary { cursor: pointer; }
.grave details[open] > summary { margin-bottom: calc(var(--space) * 2); font-weight: 600; }
.grave .stack { margin-top: calc(var(--space) * 3); }

/* El selector lleva el tipo a propósito: `input[type="submit"]` pesa más que
   una clase suelta, y sin esto el botón de borrar salía azul. */
input[type="submit"].grave-button, button.grave-button { background: var(--alarm); border-color: var(--alarm); }
input[type="submit"].grave-button:hover, button.grave-button:hover { background: #9E3624; border-color: #9E3624; }

/* La lista de clientes de un taller en la consola: cada fila se abre en su
   sitio para pedir el nombre escrito, y el pliegue se lee como lo que es. */
.erasing details { flex-basis: 100%; }
.erasing details > summary { min-height: 44px; align-items: center; color: var(--alarm); font-weight: 550; }
.erasing details[open] > summary { margin-bottom: calc(var(--space) * 2); }

/* Un pliegue se abre, y hay que verlo antes de pulsarlo: el color no basta. */
.erasing details > summary::after, .grave details > summary::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 2px solid currentcolor;
  border-bottom: 2px solid currentcolor;
  transform: translateY(-2px) rotate(45deg);
}
.erasing details[open] > summary::after, .grave details[open] > summary::after { transform: translateY(2px) rotate(-135deg); }
.grave details > summary { display: flex; align-items: center; gap: calc(var(--space) * 2); }

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

/* Un enlace solo en un párrafo sin clase es una acción, no una frase: se
   dibuja como un botón tranquilo para que el pulgar sepa dónde va. Un párrafo
   con clase es contenido —un título de resultado, una pista— y se queda como
   está. */
main p:not([class]) > a:only-child, .month-link > a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 calc(var(--space) * 4);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--ink);
  font-weight: 550;
  text-decoration: none;
  box-shadow: var(--lift-rest);
}
main p:not([class]) > a:only-child:hover, .month-link > a:hover { border-color: var(--ink-soft); }
main p a { min-height: 44px; display: inline-flex; align-items: center; margin-right: calc(var(--space) * 4); }

/* Un taller que empieza no tiene nada que mirar. La pantalla vacía no es un
   dibujo con una frase simpática: dice qué va a pasar y por dónde se empieza.
   Ver docs/DESIGN.md. */
.start { margin-top: calc(var(--space) * 6); }
.start .lede { margin-bottom: calc(var(--space) * 5); }
.start-doors { display: flex; flex-wrap: wrap; gap: calc(var(--space) * 3); margin: 0; }

/* ── La bienvenida ────────────────────────────────────────────────────────
   La primera pantalla, y una sola: quién es y cómo se llama. El idioma ya
   viene del navegador, así que no se pregunta arriba: se corrige abajo, donde
   está quien lo necesita y no estorba a quien no. Ver docs/SPEC.md 16. */
.welcome { max-width: 460px; margin: 0 auto; padding-top: calc(var(--space) * 6); }
.welcome .mark { margin-bottom: calc(var(--space) * 5); }
.welcome-who { margin: calc(var(--space) * -2) 0 calc(var(--space) * 6); color: var(--ink-soft); font-size: 14px; }
.welcome .stack { max-width: none; gap: calc(var(--space) * 4); }

.cards { display: flex; flex-direction: column; gap: calc(var(--space) * 3); margin: 0; padding: 0; border: 0; }

/* ── La entrada ───────────────────────────────────────────────────────────
   Las dos pantallas de entrar: la dirección y el código. No son pantallas de
   trabajo ni son la puerta: son un umbral, y por eso lo único que hay es una
   tarjeta centrada con la marca encima. Nada más cabe aquí. */
.gate {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--space) * 6);
  min-height: 72vh;
  justify-content: center;
  padding-block: calc(var(--space) * 8);
}

/* La tarjeta flota: es lo único que hay en la pantalla y no está apoyada en
   una lista, así que la altura la separa del papel. */
.gate-card {
  width: 100%;
  max-width: 400px;
  padding: calc(var(--space) * 8);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  background: var(--card);
  box-shadow: var(--lift-float);
}

.gate-card h1 { margin: 0 0 calc(var(--space) * 2); font-size: 26px; }
.gate-card .lede { margin: 0 0 calc(var(--space) * 6); }

/* Aquí el botón sí cruza la tarjeta de lado a lado: no hay nada más que pulsar
   en toda la pantalla, y el pulgar llega desde donde esté. */
.gate-form { max-width: none; gap: calc(var(--space) * 2); }
.gate-form input[type="submit"] { align-self: stretch; margin-top: calc(var(--space) * 2); }
.gate-form input[type="email"], .gate-form input[type="text"] { min-height: 52px; font-size: 17px; }

/* El código se lee de un correo y se teclea de memoria: ancho, separado y en
   cifras grandes, para no perder el sitio a medias. */
.code-field {
  font-size: 26px;
  font-weight: 600;
  letter-spacing: 0.34em;
  text-align: center;
  text-indent: 0.34em;   /* compensa el espacio que la última cifra arrastra */
}

.mark { display: flex; align-items: center; gap: calc(var(--space) * 3); margin: 0 0 calc(var(--space) * 6); }
.mark-icon { border-radius: 10px; }
.mark-name { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }

.gate-fine { margin: calc(var(--space) * 6) 0 0; color: var(--ink-soft); font-size: 14px; }

/* Pedir otro código y cambiar de dirección son la misma cosa dicha dos veces:
   van juntos, pequeños, y ninguno de los dos parece el botón principal. */
.gate-again { display: flex; flex-wrap: wrap; gap: calc(var(--space) * 4); margin-top: calc(var(--space) * 5); }
.gate-again form { margin: 0; }

button.as-link, .as-link, a.as-link:visited {
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--plate);
  font-size: 14px;
  font-weight: 550;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
button.as-link:hover, .as-link:hover { background: none; color: var(--plate-deep); }
button.as-link:active { transform: none; }

.gate .tongues { margin-top: 0; }

/* El alta del segundo factor necesita sitio para el QR, y el QR necesita
   marco blanco alrededor o la cámara del teléfono no lo encuentra. */
.gate-card.wide-card { max-width: 460px; }
.qr {
  width: 216px;
  margin: 0 auto calc(var(--space) * 5);
  padding: calc(var(--space) * 3);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  background: #fff;
}
.qr svg { display: block; width: 100%; height: auto; }

.by-hand { margin-bottom: calc(var(--space) * 6); font-size: 14px; }
.by-hand > summary { cursor: pointer; color: var(--ink-soft); }
/* La clave escrita se copia a mano, cifra a cifra: separada y en grupos. */
.secret {
  margin: calc(var(--space) * 2) 0 0;
  padding: calc(var(--space) * 3);
  border-radius: var(--r-row);
  background: var(--paper);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 15px;
  letter-spacing: 0.12em;
  overflow-wrap: anywhere;
}

/* ── La puerta ────────────────────────────────────────────────────────────
   La pantalla que ve quien llega de fuera, y la única del producto que no es
   papel claro. No es una contradicción con DESIGN.md: la aplicación se usa de
   pie en un taller con las puertas abiertas, y esto se lee sentado. En cuanto
   se entra, todo vuelve a ser papel.

   Los tokens de la puerta viven aquí y no en :root a propósito: nada de lo de
   abajo puede escaparse a una pantalla de trabajo. El azul es el mismo de la
   matrícula, subido hasta que se lee sobre lo oscuro; los colores de etapa son
   los mismos de siempre, que es lo que permite enseñar el producto de verdad. */
.door {
  --night: #0E1620;
  --night-soft: #16202B;
  --night-rule: #253243;
  --night-ink: #F1F3F6;
  --night-ink-soft: #A3B0C0;
  --beam: #7FA6EE;      /* --plate a plena luz: el mismo azul, legible en negro */
  --beam-deep: #4F7BD0;

  max-width: 1040px;
  margin: 0 auto;
  color: var(--night-ink);
}

/* El fondo oscuro cruza la pantalla entera, no solo la columna. */
body:has(.door) { background: var(--paper); }
main:has(.door) { max-width: none; padding: 0; }
main:has(.door)::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: #0E1620;
}

.door h2, .door h3 { letter-spacing: -0.02em; }
.door h2 { margin: 0 0 calc(var(--space) * 4); font-size: clamp(30px, 4.4vw, 46px); font-weight: 700; line-height: 1.1; }
.door h3 { margin: 0 0 calc(var(--space) * 3); font-size: 21px; font-weight: 700; }
.door p { margin: 0 0 calc(var(--space) * 4); }

/* La cabecera: marca, la frase de una línea en medio, y las dos puertas. Es
   la de Fizzy y funciona porque la frase es una y cabe. */
.door-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--space) * 3) calc(var(--space) * 6);
  padding: calc(var(--space) * 5) 0;
}
.door-brand { margin: 0; color: var(--night-ink); font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
.door-pitch { flex: 1; margin: 0; min-width: 220px; color: var(--night-ink-soft); font-size: 15px; }
.door-ways { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--space) * 3); }

/* Un enlace que es una acción es la misma píldora que un botón: llena para lo
   que se quiere que se pulse, con un filo para lo de al lado. */
.door-button, .door-quiet {
  display: inline-flex;
  align-items: center;
  min-height: 46px;
  padding: 0 calc(var(--space) * 5);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: var(--beam);
  color: #10182A;
  font-weight: 650;
  text-decoration: none;
  white-space: nowrap;
}
.door-button:visited { color: #10182A; }
.door-button:hover { background: #9BBCF5; }
.door-button:active, .door-quiet:active { transform: translateY(1px); }

.door-quiet, .door-quiet:visited { background: transparent; border-color: var(--night-rule); color: var(--night-ink); font-weight: 600; }
.door-quiet:hover { border-color: var(--night-ink-soft); background: var(--night-soft); }

.door-button.big, .door-quiet.big { min-height: 56px; padding: 0 calc(var(--space) * 8); font-size: 18px; }

/* ── La foto del producto ──
   Una pantalla de Aujourd'hui dibujada con el HTML de verdad, dentro de un
   marco de navegador y sobre luz de color. Una captura envejece sola y solo
   está en un idioma; esto se traduce con la aplicación. */
.shot {
  margin: calc(var(--space) * 4) 0 calc(var(--space) * 12);
  padding: calc(var(--space) * 5) calc(var(--space) * 5) 0;
  border-radius: var(--r-panel) var(--r-panel) 0 0;
  background: linear-gradient(112deg, #F2A9C4 0%, #C9A6E8 38%, #8FB6F2 72%, #7FE3DA 100%);
}
.shot-frame {
  overflow: hidden;
  border-radius: 12px 12px 0 0;
  background: var(--card);
  box-shadow: 0 -2px 40px rgb(16 24 32 / 22%);
}
.shot-chrome { display: flex; gap: 7px; padding: calc(var(--space) * 3) calc(var(--space) * 4); border-bottom: 1px solid var(--hairline); }
.shot-chrome span { width: 11px; height: 11px; border-radius: var(--r-pill); background: var(--rule); }

/* La pantalla se corta por abajo a propósito: un tablero que termina con un
   palmo de blanco parece un tablero vacío, y lo que dice el corte es que hay
   más. Es lo que hace Fizzy con el suyo. */
.shot-screen { max-height: 520px; padding: calc(var(--space) * 5) calc(var(--space) * 6) 0; color: var(--ink); overflow: hidden; }
.shot-title { margin: 0 0 calc(var(--space) * 5); font-size: 26px; font-weight: 700; letter-spacing: -0.025em; }
.shot-band {
  display: flex;
  align-items: center;
  gap: calc(var(--space) * 2);
  margin: calc(var(--space) * 5) 0 calc(var(--space) * 1);
  font-size: 15px;
  font-weight: 650;
}
.shot-band .count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--plate);
  color: #fff;
  font-size: 13px;
  font-weight: 650;
}
.shot-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--space) * 2) calc(var(--space) * 4);
  margin: 0;
  padding: calc(var(--space) * 3) 0;
  border-bottom: 1px solid var(--hairline);
  font-size: 15px;
}
.shot-row:last-child { border-bottom: 0; }
.shot-who { font-weight: 650; }
/* Lo que dijo el cliente va debajo, en una línea: es lo que se lee para
   decidir si corre prisa. */
.shot-said { flex-basis: 100%; color: var(--ink-soft); }
/* La etapa lleva su punto y su nombre, como en todas partes: el color nunca va
   solo. Ver docs/DESIGN.md. */
.shot-stage { display: inline-flex; align-items: center; gap: calc(var(--space) * 2); font-size: 14px; font-weight: 600; }
.shot-stage::before { content: ""; width: 8px; height: 8px; border-radius: var(--r-pill); background: currentcolor; }
.shot-stage.stage-repair { color: var(--stage-repair); }
.shot-stage.stage-quote_sent { color: var(--stage-quote); }
.shot-stage.stage-waiting_part { color: var(--stage-part); }
.shot-stage.stage-ready { color: var(--stage-ready); }
.shot-stage.stage-diagnostic { color: var(--stage-diagnostic); }

/* El titular: lo único de todo el producto que crece con la ventana. La
   segunda línea se apaga, que es lo que hace que la primera pese. */
.door-headline {
  margin: 0 0 calc(var(--space) * 14);
  font-size: clamp(38px, 6.6vw, 68px);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.03em;
  text-align: center;
}
.door-headline span { display: block; color: var(--night-ink-soft); }

/* ── La carta ──
   Una hoja de papel en mitad de la pantalla oscura. Es lo único que se lee
   despacio, y por eso es lo único que no es oscuro: dos columnas con el
   pliegue en medio, como una hoja abierta. */
.letter {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(var(--space) * 12);
  margin-bottom: calc(var(--space) * 16);
  padding: calc(var(--space) * 12) calc(var(--space) * 10);
  border-radius: 4px;
  background: var(--card);
  background-image: linear-gradient(90deg, transparent calc(50% - 24px), rgb(22 24 28 / 7%) 50%, transparent calc(50% + 24px));
  color: var(--ink);
  box-shadow: 0 24px 60px -20px rgb(0 0 0 / 55%);
}
.letter p { margin: 0 0 calc(var(--space) * 5); max-width: 44ch; }
.letter-turn { font-weight: 700; }
.letter-sign { margin-top: calc(var(--space) * 8); }
.letter-who { display: block; font-weight: 700; }
.letter-role { display: block; color: var(--ink-soft); font-size: 14px; font-style: italic; }

/* ── Las bandas ── */
.door-band { padding: calc(var(--space) * 14) 0; text-align: center; }
.door-band > h2 { text-align: center; }
.door-sub { margin: 0 auto calc(var(--space) * 10); max-width: 56ch; color: var(--night-ink-soft); font-size: 19px; }

.door-halves {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: calc(var(--space) * 6);
  text-align: left;
}
.door-halves article {
  padding: calc(var(--space) * 8);
  border: 1px solid var(--night-rule);
  border-radius: var(--r-panel);
  background: var(--night-soft);
}
.door-halves p { color: var(--night-ink-soft); }
/* La escalera es la del producto y se dibuja en papel, como la ve el cliente:
   volver a pintarla en oscuro sería enseñar algo que no existe. */
.door-halves .ladder { margin-bottom: 0; }

.door-list { margin: 0; padding: 0; list-style: none; }
.door-list li { padding: calc(var(--space) * 3) 0; border-bottom: 1px solid var(--night-rule); }
.door-list li:last-child { border-bottom: 0; }

/* Lo pequeño va seguido en un solo párrafo, con el nombre de cada cosa en
   negrita: seis tarjetas con un icono cada una dirían que son seis funciones
   grandes, y no lo son. */
.door-run { margin: 0 auto; max-width: 60ch; font-size: 21px; line-height: 1.5; color: var(--night-ink-soft); }
.door-run b { color: var(--night-ink); font-weight: 700; }

.door-prices { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: calc(var(--space) * 4); text-align: left; }
.price { padding: calc(var(--space) * 6); border: 1px solid var(--night-rule); border-radius: var(--r-card); background: var(--night-soft); }
.price-name { margin: 0; color: var(--night-ink-soft); font-size: 14px; }
.price-figure { margin: calc(var(--space) * 1) 0 0; font-size: 30px; font-weight: 700; letter-spacing: -0.03em; }
.price-note { margin: calc(var(--space) * 1) 0 0; color: var(--night-ink-soft); font-size: 14px; }

/* Autoalojarse dibujado como lo que es: un plano. La retícula es la única
   textura de esta pantalla, igual que las franjas de peligro son la única de
   la aplicación. */
.blueprint {
  margin: calc(var(--space) * 4) 0;
  padding: calc(var(--space) * 16) calc(var(--space) * 8);
  border-radius: var(--r-panel);
  background-color: #16307A;
  background-image: linear-gradient(rgb(255 255 255 / 7%) 1px, transparent 1px),
                    linear-gradient(90deg, rgb(255 255 255 / 7%) 1px, transparent 1px);
  background-size: 28px 28px;
  text-align: center;
}
.blueprint h2 { margin-left: auto; margin-right: auto; max-width: 20ch; }
.blueprint p { margin: 0 auto; max-width: 58ch; color: #C9D8F7; font-size: 18px; }

/* Las preguntas: una fila por pregunta, y la respuesta debajo cuando se pide.
   Sin JavaScript, porque un <details> ya lo hace. */
.door-asks { display: flex; flex-direction: column; gap: calc(var(--space) * 3); text-align: left; }
.door-ask { border-radius: var(--r-card); background: var(--night-soft); }
.door-ask > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--space) * 4);
  min-height: 60px;
  padding: calc(var(--space) * 3) calc(var(--space) * 6);
  list-style: none;
  cursor: pointer;
  font-size: 17px;
  font-weight: 650;
}
.door-ask > summary::-webkit-details-marker { display: none; }
.door-ask > summary::after {
  content: "";
  flex: none;
  width: 14px;
  height: 14px;
  background: linear-gradient(var(--night-ink-soft) 0 0) center/14px 2px no-repeat,
              linear-gradient(var(--night-ink-soft) 0 0) center/2px 14px no-repeat;
}
.door-ask[open] > summary::after { background: linear-gradient(var(--night-ink-soft) 0 0) center/14px 2px no-repeat; }
.door-ask > summary:hover { color: var(--beam); }
.door-ask p { margin: 0; padding: 0 calc(var(--space) * 6) calc(var(--space) * 6); max-width: 64ch; color: var(--night-ink-soft); }

.door-close { padding: calc(var(--space) * 16) 0 calc(var(--space) * 10); text-align: center; }
.door-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(var(--space) * 3); margin: 0 0 calc(var(--space) * 4); }
.door-fine { margin: 0; color: var(--night-ink-soft); font-size: 14px; }

.door-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--space) * 4);
  padding: calc(var(--space) * 8) 0 calc(var(--space) * 14);
  border-top: 1px solid var(--night-rule);
}
.door-made { margin: 0; max-width: 52ch; color: var(--night-ink-soft); font-size: 14px; }
.door-foot .tongues { margin-top: 0; }
.door-foot .tongue, .door-foot .tongue:visited { border-color: var(--night-rule); background: transparent; color: var(--night-ink-soft); }
.door-foot .tongue:hover { background: var(--night-soft); border-color: var(--night-ink-soft); color: var(--night-ink); }
.door-foot .tongue.current, .door-foot .tongue.current:visited { background: var(--beam); border-color: transparent; color: #10182A; }

/* En un móvil: la carta deja de ser una hoja abierta y pasa a ser una hoja, y
   las dos puertas de arriba desaparecen porque están otra vez tres dedos más
   abajo. Ver docs/DESIGN.md. */
@media (max-width: 720px) {
  .letter { grid-template-columns: 1fr; gap: 0; padding: calc(var(--space) * 8) calc(var(--space) * 6); background-image: none; }
}
@media (max-width: 560px) {
  .door-ways { display: none; }
  .door-pitch { flex-basis: 100%; }
  .shot { margin-bottom: calc(var(--space) * 10); padding-inline: calc(var(--space) * 3); }
  .shot-screen { max-height: 380px; padding: calc(var(--space) * 4) calc(var(--space) * 4) 0; }
  .door-band, .blueprint { padding-block: calc(var(--space) * 10); }
  .blueprint { padding-inline: calc(var(--space) * 5); }
}

.cards { display: flex; flex-direction: column; gap: calc(var(--space) * 3); margin: 0; padding: 0; border: 0; }

/* La tarjeta elegida se enciende entera, no solo su botón: es lo que se ha
   dicho de uno mismo, y tiene que verse desde un brazo de distancia. */
.card-choice {
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--lift-rest);
}
.card-choice:has(input:checked) { border-color: var(--plate); box-shadow: var(--lift-float); }
.card-choice:hover { border-color: var(--ink-soft); }
.card-choice:has(input[type="radio"]:focus-visible) { outline: 3px solid var(--plate); outline-offset: 2px; }

.choice-head {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--space) * 3);
  min-height: 44px;
  padding: calc(var(--space) * 4) calc(var(--space) * 5);
  cursor: pointer;
}
.choice-head input[type="radio"] { width: 22px; height: 22px; margin: 2px 0 0; accent-color: var(--plate); flex: none; }
.choice-title { display: block; font-size: 18px; font-weight: 650; letter-spacing: -0.01em; }
.choice-hint { display: block; margin-top: calc(var(--space) * 1); font-size: 14px; font-weight: 400; color: var(--ink-soft); }

.choice-fields {
  display: flex;
  flex-direction: column;
  gap: calc(var(--space) * 2);
  padding: 0 calc(var(--space) * 5) calc(var(--space) * 5);
}
.choice-fields[hidden] { display: none; }
.choice-fields label { font-size: 14px; font-weight: 550; color: var(--ink-soft); }
.choice-fields label + input { margin-bottom: calc(var(--space) * 1); }

/* Los idiomas se escriben cada uno en el suyo: en esta pantalla todavía no
   sabemos cuál habla quien mira. Ver Language. */
.tongues { display: flex; flex-wrap: wrap; gap: calc(var(--space) * 2); margin-top: calc(var(--space) * 10); }
.tongues form { margin: 0; }
/* La píldora de un idioma es la misma se llegue por un botón —la bienvenida,
   que cambia el idioma de la cuenta— o por un enlace —la puerta, donde todavía
   no hay cuenta que cambiar—. El aspecto lo lleva la clase, no la etiqueta. */
.tongues button, .tongue {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 calc(var(--space) * 4);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink-soft);
  font-size: 15px;
  font-weight: 550;
  text-decoration: none;
  box-shadow: none;
}
.tongues button:hover, .tongue:hover { background: var(--card); border-color: var(--rule); color: var(--ink); }
.tongues button.current, .tongue.current { background: var(--plate-tint); border-color: transparent; color: var(--plate-deep); }

/* Una lista de cosas que se marcan: se pulsan con el pulgar, así que la fila
   entera mide lo que mide un dedo. */
.picks label { display: flex; align-items: center; gap: calc(var(--space) * 3); min-height: 44px; font-size: 16px; color: var(--ink); }
.picks input[type="checkbox"], .switch input[type="checkbox"] { width: 22px; height: 22px; accent-color: var(--plate); }

.switch { display: flex; align-items: center; gap: calc(var(--space) * 3); min-height: 44px; }

.flash {
  display: flex;
  align-items: center;
  gap: calc(var(--space) * 2);
  margin: 0 0 calc(var(--space) * 5);
  padding: calc(var(--space) * 3) calc(var(--space) * 4);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--lift-rest);
}
.flash.alert { border-color: var(--alarm); color: var(--alarm); }

.errors {
  margin: 0 0 calc(var(--space) * 4);
  padding: calc(var(--space) * 3) calc(var(--space) * 4);
  border: 1px solid var(--alarm);
  border-radius: var(--r-card);
  background: var(--card);
  color: var(--alarm);
  list-style-position: inside;
}
.errors li + li { margin-top: calc(var(--space) * 1); }

/* ── La matrícula ─────────────────────────────────────────────────────────
   El identificador real de un coche. Es el único elemento con permiso para
   llamar la atención, y se compone como la placa: banda azul con la F, fondo
   blanco, borde fino, la misma familia estrechada. Ver docs/DESIGN.md. */
.plate {
  display: inline-flex;
  align-items: stretch;
  overflow: hidden;
  min-height: 26px;
  border: 1px solid var(--ink);
  border-radius: 4px;
  background: var(--card);
  color: var(--ink);
  font-size: 15px;
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: 0.05em;
  line-height: 24px;
  padding-right: calc(var(--space) * 2);
  white-space: nowrap;
}
.plate-band {
  display: flex;
  align-items: center;
  padding: 0 calc(var(--space) * 1.5);
  margin-right: calc(var(--space) * 2);
  background: var(--plate);
  color: #fff;
  font-size: 11px;
  font-stretch: 100%;
  letter-spacing: 0;
}

/* ── Aujourd'hui ──────────────────────────────────────────────────────────
   Los colores de etapa son el sistema entero: van de frío a caliente
   siguiendo el estado real del trabajo. Ver docs/DESIGN.md. */
:root {
  --stage-diagnostic: #5B6B7A;
  --stage-quote:      #7A5AA6;
  --stage-part:       #9E6716;
  --stage-repair:     #C2452D;
  --stage-ready:      #2E7D4F;
}

.screen-head { display: flex; align-items: baseline; justify-content: space-between; gap: calc(var(--space) * 4); margin-bottom: calc(var(--space) * 5); }
.screen-head h1 { margin-bottom: 0; }

/* La banda de prioridad está por encima del flujo, y por eso sus tarjetas son
   grandes, flotan y se deslizan con el pulgar. La diferencia de tratamiento es
   la jerarquía. La barra de desplazamiento sobra: la tarjeta cortada por el
   borde ya dice que hay más. */
.band {
  display: flex;
  gap: calc(var(--space) * 3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  margin: 0 calc(var(--space) * -5) calc(var(--space) * 9);
  padding: calc(var(--space) * 1) calc(var(--space) * 5) calc(var(--space) * 4);
  -webkit-overflow-scrolling: touch;
}
.band::-webkit-scrollbar { display: none; }
.band-card {
  flex: 0 0 auto;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--space) * 2);
  width: 196px;
  min-height: 168px;
  padding: calc(var(--space) * 4);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  background: var(--card);
  box-shadow: var(--lift-float);
  color: var(--ink);
  text-decoration: none;
}
a.band-card:visited { color: var(--ink); }
.band-card:hover { box-shadow: 0 2px 4px rgb(22 24 28 / 8%), 0 16px 30px -10px rgb(22 24 28 / 22%); }
.band-vehicle { font-size: 18px; font-weight: 650; line-height: 1.2; letter-spacing: -0.01em; }
.band-stage { font-size: 14px; font-weight: 650; margin-top: auto; }
.band-why { font-size: 14px; color: var(--ink-soft); line-height: 1.35; }

/* La etapa va escrita y en su color, con un punto delante: el color solo no
   comunica nada a quien no lo distingue. */
.band-stage::before, .card-stage::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: calc(var(--space) * 2);
  border-radius: 50%;
  background: currentcolor;
  vertical-align: 0.08em;
}

.stage-diagnostic { color: var(--stage-diagnostic); }
.stage-quote_sent { color: var(--stage-quote); }
.stage-waiting_part { color: var(--stage-part); }
.stage-repair { color: var(--stage-repair); }
.stage-ready { color: var(--stage-ready); }
.stage-none { color: var(--ink-soft); }

/* Cuántos hay es un dato, no un adorno: ficha al lado del título, en la misma
   tinta secundaria que todo lo que acompaña. */
.count { font-weight: 400; color: var(--ink-soft); }
h2 .count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  padding: 0 calc(var(--space) * 2);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  background: var(--card);
  font-size: 13px;
  vertical-align: 2px;
}

/* ── Las listas ───────────────────────────────────────────────────────────
   Una lista es una lista: filas separadas por una línea fina, sin tarjeta ni
   sombra. Lo que flota es lo que está por encima del flujo, y nada más. */
.rows { list-style: none; margin: 0; padding: 0; }
/* Una fila escondida está escondida: `display: flex` le gana al `hidden` del
   navegador, y quien filtraba seguía viéndolo todo. */
.rows li[hidden] { display: none; }
.rows li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: calc(var(--space) * 1) calc(var(--space) * 4);
  min-height: 52px;
  align-items: center;
  padding-inline: calc(var(--space) * 2);
  margin-inline: calc(var(--space) * -2);
  border-bottom: 1px solid var(--hairline);
}

/* La fila entera lleva a un sitio, así que la fila entera responde. Solo donde
   hay ratón: en un móvil no existe el "por encima", y un resaltado que se queda
   pegado después del toque dice que sigues ahí cuando ya te has ido. */
@media (hover: hover) {
  .rows li:has(a):hover { background: color-mix(in srgb, var(--ink) 5%, var(--paper)); border-radius: var(--r-row) var(--r-row) 0 0; }
}
.rows li:last-child { border-bottom: 0; }
.rows li a { display: inline-flex; align-items: center; gap: calc(var(--space) * 2); min-height: 44px; color: var(--ink); text-decoration: none; }
.rows li a:hover { color: var(--plate); }
.places { margin-top: calc(var(--space) * 9); }
.places li a { flex: 1; font-weight: 550; }
.places li a:hover { color: var(--plate); }

.excerpt { flex-basis: 100%; color: var(--ink-soft); font-size: 14px; margin-bottom: calc(var(--space) * 2); }
code { font-size: 13px; word-break: break-all; }

/* El triaje: lo que dice el mensaje y los coches a los que puede ir, a la vez
   y sin abrir nada. Ranger cuesta un toque, y el pulgar no tiene que apuntar. */
.rows details > summary {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--space) * 2);
  align-items: baseline;
  min-height: 52px;
  padding: calc(var(--space) * 2) 0;
  cursor: pointer;
}
.rows details > summary::marker { color: var(--ink-soft); }
.said {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--space) * 1) calc(var(--space) * 3);
  align-items: baseline;
  width: 100%;
  padding-top: calc(var(--space) * 3);
}
.said .excerpt { margin-bottom: 0; }
.sender { font-weight: 650; }
.rows li.urgent .sender { box-shadow: inset 3px 0 0 var(--ink); padding-left: calc(var(--space) * 2); }
/* Las etapas a las que se puede ir llevan su color, el mismo de la tarjeta y
   el mismo de la banda. El color no va solo: la etapa está escrita al lado del
   punto, como en todas partes. */
.stage-chip { border-color: var(--rule); }
button.stage-chip.stage-diagnostic { color: var(--stage-diagnostic); }
button.stage-chip.stage-quote_sent { color: var(--stage-quote); }
button.stage-chip.stage-waiting_part { color: var(--stage-part); }
button.stage-chip.stage-repair { color: var(--stage-repair); }
button.stage-chip.stage-ready { color: var(--stage-ready); }
.stage-chip:hover { border-color: currentcolor; background: var(--paper); }
.stage-chip::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: calc(var(--space) * 2);
  border-radius: 50%;
  background: currentcolor;
}

/* Se archiva un mensaje pulsando la matrícula del coche, así que el botón es
   el soporte de la placa: se aparta y la deja verse. Al lado va de quién es el
   coche, y al final por qué se propone: se confirma lo que ya se sabe. */
.plate-button, .triage button.plate-button {
  display: flex;
  align-items: center;
  gap: calc(var(--space) * 2);
  min-height: 52px;
  padding: calc(var(--space) * 2) calc(var(--space) * 3);
  background: var(--card);
  border-color: var(--rule);
  color: var(--ink);
  font-weight: 550;
  text-align: left;
}
.plate-button:hover, .triage button.plate-button:hover { background: var(--paper); border-color: var(--plate); }

.triage {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--space) * 2);
  align-items: center;
  width: 100%;
  padding-bottom: calc(var(--space) * 3);
}
/* Un coche por línea: tres matrículas en fila no se leen, y media matrícula
   no se pulsa con el pulgar. */
.triage .button_to { flex: 1 1 100%; }
.triage .button_to button.plate-button { width: 100%; }
.plate-button .plate { flex: none; }
.plate-button .who { flex: 1; min-width: 0; font-weight: 550; }
.plate-button .hint { flex: none; max-width: 38%; font-size: 12px; line-height: 1.2; text-align: right; }
.plate-button.wide { width: 100%; }
.rows li:has(.plate-button) { padding-block: calc(var(--space) * 1); }

/* La búsqueda solo aparece con JavaScript, porque sin él es un campo que no
   hace nada: la lista entera ya está debajo. */
.filter-field { width: 100%; margin-bottom: calc(var(--space) * 3); }

/* Un aviso es una frase, y la fila entera lleva a su asunto. Sin leer no es un
   color: es el peso. Nada de fondo azul pálido ni de punto de color, que en una
   lista de ocho dejan de decir nada. Ver docs/DESIGN.md. */
.rows li a.notice {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: calc(var(--space) * 1) calc(var(--space) * 3);
  width: 100%;
  padding: calc(var(--space) * 3) 0;
}
.notice-what { font-weight: 650; }
.notice time { font-size: 14px; color: var(--ink-soft); white-space: nowrap; }
.notice-about { grid-column: 1 / -1; font-size: 14px; }
.notices li.read .notice-what { font-weight: 400; color: var(--ink-soft); }

/* ── El tablero ───────────────────────────────────────────────────────────
   Dos columnas y no siete. En un móvil no caben lado a lado sin apretar la
   matrícula, así que se apilan: el orden de lectura es el mismo. */
.board { display: grid; grid-template-columns: 1fr; gap: calc(var(--space) * 7); }
@media (min-width: 560px) { .board { grid-template-columns: 1fr 1fr; align-items: start; } }
.board h2 { margin-top: 0; }
/* Una columna vacía se lee como vacía a propósito, no como media pantalla que
   no ha cargado. */
.column-empty { margin: 0; color: var(--ink-soft); font-size: 15px; }
.column { display: flex; flex-direction: column; gap: calc(var(--space) * 3); }

/* La etapa es el color de la tarjeta, y además va escrita. El filo de color
   es ancho y llega a las esquinas: se ve desde un metro. */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: calc(var(--space) * 2);
  padding: calc(var(--space) * 4) calc(var(--space) * 4) calc(var(--space) * 4) calc(var(--space) * 5);
  border: 1px solid var(--hairline);
  border-left: 5px solid var(--ink-soft);
  border-radius: var(--r-card);
  background-color: var(--card);
  box-shadow: var(--lift-rest);
}
.card-diagnostic { border-left-color: var(--stage-diagnostic); }
.card-quote_sent { border-left-color: var(--stage-quote); }
.card-waiting_part { border-left-color: var(--stage-part); }
.card-repair { border-left-color: var(--stage-repair); }
.card-ready { border-left-color: var(--stage-ready); }
.card-none { border-left-color: var(--rule); }

.card-head, a.card-head:visited { color: var(--ink); }
.card-head { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--space) * 2) calc(var(--space) * 3); min-height: 44px; color: var(--ink); text-decoration: none; }
.card-vehicle { font-size: 17px; font-weight: 650; letter-spacing: -0.01em; }
.card-title { margin: 0; }
.card-stage { margin: 0; font-size: 14px; font-weight: 650; }
.card-since { color: var(--ink-soft); font-weight: 400; }
.card-unread { margin: 0; font-size: 14px; color: var(--ink-soft); }
.card-stages > summary {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 14px;
  font-weight: 550;
  color: var(--ink-soft);
  cursor: pointer;
}
.card-stages > summary:hover { color: var(--plate); }

/* Lo terminado no ocupa columna: cae al pie, en gris, con su sello. */
.done { color: var(--ink-soft); }
.done .rows li a { color: var(--ink-soft); }
.stamp {
  font-size: 13px;
  font-weight: 650;
  color: var(--ink-soft);
  border: 1px solid var(--rule);
  border-radius: var(--r-row);
  padding: calc(var(--space) * 1) calc(var(--space) * 2);
}

/* Una pantalla vacía es una invitación a hacer algo, y se lee como un título.
   Detrás de un formulario o de una lista necesita aire: pegada al botón de
   arriba parece que el botón haya contestado. */
.empty-title { font-size: 20px; font-weight: 650; letter-spacing: -0.01em; }
h2.empty-title { margin-top: 0; }
p.empty-title { margin: calc(var(--space) * 8) 0 calc(var(--space) * 2); }

/* ── La ficha del coche ───────────────────────────────────────────────────
   Una página larga que se lee, no cinco pestañas. */
.fiche-head h1 { margin-bottom: calc(var(--space) * 2); }
.contacts { display: flex; flex-wrap: wrap; gap: calc(var(--space) * 2); }
.contact {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 calc(var(--space) * 4);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--ink);
  font-weight: 550;
  text-decoration: none;
  box-shadow: var(--lift-rest);
}
a.contact:visited { color: var(--ink); }
.contact:hover { border-color: var(--ink-soft); }
.current .card { margin-bottom: calc(var(--space) * 2); }

.timeline { display: flex; flex-direction: column; gap: calc(var(--space) * 5); }
.entry { border-left: 2px solid var(--rule); padding-left: calc(var(--space) * 4); }
.entry-head { display: flex; flex-wrap: wrap; gap: calc(var(--space) * 2) calc(var(--space) * 3); align-items: baseline; margin: 0; font-size: 14px; color: var(--ink-soft); }
.entry-who { font-weight: 650; color: var(--ink); }
.entry-body { margin: calc(var(--space) * 1) 0 0; }
.entry-body p { margin: 0 0 calc(var(--space) * 2); }
.entry-stage_changed .entry-body, .entry-finished .entry-body { font-weight: 650; }
.entry-note { border-left-color: var(--ink); }
.entry-platform { border-left-color: var(--plate); }
.entry-publish { display: flex; align-items: center; gap: calc(var(--space) * 3); margin-top: calc(var(--space) * 2); }
.note-form { max-width: none; margin-top: calc(var(--space) * 6); }

/* ── La carta y la ficha pública ────────────────────────────────────────── */
.service-name { font-weight: 650; }

/* La ficha pública es la única pantalla que ve alguien que no ha entrado
   nunca, así que respira más que el resto. Ver docs/DESIGN.md. */
.storefront header { margin-bottom: calc(var(--space) * 7); }
.storefront h1 { margin-bottom: calc(var(--space) * 1); font-size: 34px; }
.storefront-city { margin: 0; color: var(--ink-soft); font-size: 17px; }
.storefront-address { display: flex; flex-direction: column; margin: 0 0 calc(var(--space) * 4); color: var(--ink-soft); }

/* La carta de un taller se lee como la de un restaurante: qué es, qué cuesta,
   cuánto dura. Nada de tarjetas ni de sombras: son filas de una lista. */
.menu { list-style: none; margin: 0; padding: 0; }
.menu li { padding: calc(var(--space) * 4) 0; border-bottom: 1px solid var(--hairline); }
.menu-name { margin: 0; font-size: 17px; font-weight: 650; }
.menu-about { margin: calc(var(--space) * 1) 0 0; color: var(--ink-soft); }
.menu-terms { display: flex; flex-wrap: wrap; gap: calc(var(--space) * 4); margin: calc(var(--space) * 2) 0 0; }
.menu-price { font-weight: 650; }
.menu-duration { color: var(--ink-soft); }

/* ── El anuario ───────────────────────────────────────────────────────────
   Una tarjeta por taller, con lo que hace falta para elegir sin abrir
   ninguna: dónde está, qué nota tiene, qué hace y cuándo tiene hueco.
   Una fila de texto no dejaba comparar dos. Ver docs/SPEC.md 8. */
.found { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(var(--space) * 3); }
@media (min-width: 640px) {
  .found { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
}
.found-card {
  display: flex;
  flex-direction: column;
  gap: calc(var(--space) * 2);
  padding: calc(var(--space) * 5);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--lift-rest);
}
.found-name { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -0.01em; }
.found-name a { color: var(--ink); text-decoration: none; }
.found-name a:hover { color: var(--plate); text-decoration: underline; text-underline-offset: 3px; }
/* La dirección entera, no solo la ciudad: es lo primero que se mira para saber
   si pilla cerca, y hasta ahora había que abrir la ficha para verla. */
.found-where { font-size: 14px; }
.found-does .state { border: 1px solid var(--rule); }
.found-when { display: flex; flex-wrap: wrap; gap: calc(var(--space) * 1) calc(var(--space) * 4); margin: 0; margin-top: auto; padding-top: calc(var(--space) * 2); font-size: 14px; }

/* Dónde está el taller, en su tarjeta y arriba del todo. */
.where-map { margin: calc(var(--space) * 2) 0 0; }
.where-when { margin: calc(var(--space) * 6) 0 calc(var(--space) * 2); font-size: 15px; font-weight: 650; }
.hours { display: grid; grid-template-columns: auto 1fr; gap: calc(var(--space) * 1) calc(var(--space) * 4); margin: 0; font-size: 14px; }
.hours dt { color: var(--ink-soft); }
.hours dd { margin: 0; font-variant-numeric: tabular-nums; }

/* ── El planificador ──────────────────────────────────────────────────────
   El color ya está gastado en las etapas y no se pide prestado: aquí el tipo
   de cita va escrito y el estado se dice con el borde. Ver docs/DESIGN.md. */
.views, .steps { display: flex; flex-wrap: wrap; gap: calc(var(--space) * 1); margin-bottom: calc(var(--space) * 5); }
.views a, .steps a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding: 0 calc(var(--space) * 3);
  border-radius: var(--r-pill);
  color: var(--ink-soft);
  font-size: 15px;
  font-weight: 550;
  text-decoration: none;
}
.views a:hover, .steps a:hover { color: var(--ink); }
.views a.current { background: var(--plate-tint); color: var(--plate-deep); font-weight: 650; }

.requests { margin-bottom: calc(var(--space) * 7); }

.agenda-day { margin: calc(var(--space) * 7) 0 calc(var(--space) * 2); font-size: 15px; }
.hours { list-style: none; margin: 0; padding: 0; }

.slot { padding: calc(var(--space) * 3) 0; border-top: 1px solid var(--hairline); }
.slot-hour { display: flex; flex-wrap: wrap; align-items: baseline; gap: calc(var(--space) * 3); margin: 0; }
.slot-hour time { font-weight: 650; font-variant-numeric: tabular-nums; }
.slot-kind { font-size: 14px; font-weight: 650; }
.slot-length, .slot-open { font-size: 14px; color: var(--ink-soft); }
.slot-open { margin: calc(var(--space) * 1) 0 0; }
/* Un hueco libre es un espacio con una línea fina y su hora. Lo que llena la
   pantalla es el trabajo, no el vacío. */
.slot-free { color: var(--ink-soft); }
.slot-free time { color: var(--ink); }

/* El estado se dice con el borde y con texto: solicitada discontinua,
   confirmada plena. */
.booking {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--space) * 3);
  min-height: 44px;
  margin-top: calc(var(--space) * 2);
  padding: calc(var(--space) * 2) calc(var(--space) * 4);
  border: 1px solid var(--ink);
  border-radius: var(--r-card);
  background: var(--card);
  color: var(--ink);
  text-decoration: none;
}
a.booking:visited { color: var(--ink); }
.booking-offered, .booking-requested { border-style: dashed; }
.booking-who { font-weight: 650; }
.booking-state { font-size: 14px; color: var(--ink-soft); }

/* El planificador es la única pantalla que rompe la columna de 640 px, y solo
   en semana y mes: siete días dentro de la columna son siete tiras de cuarenta
   píxeles donde una hora no cabe. Ver docs/DESIGN.md. */
@media (min-width: 760px) {
  .wide-out {
    width: min(calc(100vw - 40px), 1120px);
    margin-left: calc((640px - min(calc(100vw - 40px), 1120px)) / 2);
  }
}

/* La semana se apila en móvil y se pone en columnas en una pantalla ancha. */
.week { display: grid; grid-template-columns: 1fr; gap: calc(var(--space) * 2); }
@media (min-width: 700px) {
  .week { grid-template-columns: repeat(7, 1fr); align-items: start; gap: calc(var(--space) * 3); }
  .week .agenda-day { margin-top: 0; font-size: 14px; }
  .week .slot-hour { flex-direction: column; gap: 0; }
}

/* El mes es de escritorio. En 375 px no se apretuja una rejilla de siete
   columnas: se enseña la lista de los días que tienen algo. */
.month { display: none; }
.month-list { list-style: none; margin: 0; padding: 0; }
.month-list li { border-bottom: 1px solid var(--hairline); }
.month-list a { display: flex; justify-content: space-between; gap: calc(var(--space) * 4); min-height: 48px; align-items: center; color: var(--ink); text-decoration: none; }
@media (min-width: 700px) {
  .month { display: table; width: 100%; border-collapse: collapse; }
  .month-list { display: none; }
  .month th { padding: calc(var(--space) * 2); font-size: 14px; font-weight: 550; color: var(--ink-soft); text-align: left; }
  .month td { border: 1px solid var(--hairline); vertical-align: top; background: var(--card); }
  .month td a { display: flex; justify-content: space-between; gap: calc(var(--space) * 2); min-height: 56px; padding: calc(var(--space) * 2); color: var(--ink); text-decoration: none; }
  .month .outside a { color: var(--ink-soft); }
  .month .outside { background: transparent; }
  .month .today { box-shadow: inset 0 0 0 2px var(--plate); }
  .month-count { font-weight: 650; }
}

.surcharge { font-weight: 650; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Los filtros del anuario: una etiqueta encima de su campo, como el resto de
   los formularios. En una pantalla ancha caben en fila. */
.filters { display: grid; grid-template-columns: 1fr; gap: calc(var(--space) * 3); margin-bottom: calc(var(--space) * 7); padding: calc(var(--space) * 4); border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--card); box-shadow: var(--lift-rest); }
.filters label { font-size: 14px; font-weight: 550; color: var(--ink-soft); }
/* Una etiqueta y su campo son una sola celda de la rejilla, o se separan. */
.filters .field { display: flex; flex-direction: column; gap: calc(var(--space) * 1); }
.filters label.switch { color: var(--ink); }
.filters select, .filters input[type="number"] { width: 100%; }
.filters input[type="submit"] { justify-self: start; }
@media (min-width: 560px) {
  .filters { grid-template-columns: repeat(2, 1fr); align-items: end; }
  .filters input[type="submit"] { grid-column: 1 / -1; }
}

/* Reservar desde la ficha pública se abre en su sitio, sin salir de la carta. */
.booking-open > summary { display: flex; align-items: center; min-height: 44px; font-weight: 650; color: var(--plate); cursor: pointer; }
.booking-open .stack { margin: calc(var(--space) * 3) 0 calc(var(--space) * 5); }
.hours-open { padding: calc(var(--space) * 3) calc(var(--space) * 4); border: 1px solid var(--rule); border-radius: var(--r-card); }
.hours-open legend { padding: 0 calc(var(--space) * 2); font-size: 14px; color: var(--ink-soft); }
.hours-open label { display: flex; align-items: center; gap: calc(var(--space) * 3); min-height: 44px; }
.hours-open input[type="radio"] { width: 22px; height: 22px; accent-color: var(--plate); }

/* El estancamiento no tiene color: lleva franjas, como la cinta de peligro de
   un taller. Es la única textura de toda la aplicación, y por eso se ve. Va al
   final porque pinta el borde izquierdo por encima del color de la etapa. */
.stalled {
  border-left: 6px solid transparent;
  background-image: repeating-linear-gradient(45deg, #16181C 0 6px, #E8C547 6px 12px);
  background-repeat: no-repeat;
  background-size: 6px 100%;
  background-position: left top;
  background-origin: border-box;
}

/* ── La escalera del cliente ──────────────────────────────────────────────
   Vertical, un peldaño por línea: el actual en tinta plena, los pasados con su
   marca y su fecha, los futuros apagados. Sin barra de progreso ni porcentaje:
   un coche no está al 60 %. Ver docs/DESIGN.md. */
.ladder {
  list-style: none;
  margin: 0 0 calc(var(--space) * 8);
  padding: calc(var(--space) * 2) calc(var(--space) * 5);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  background: var(--card);
  box-shadow: var(--lift-rest);
}

.rung {
  position: relative;
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: baseline;
  gap: calc(var(--space) * 2);
  min-height: 48px;
  padding: calc(var(--space) * 2) 0;
  color: var(--ink-faint);
}

/* La marca la pone el CSS y no el texto: un peldaño no se lee en voz alta
   diciendo "palomita". El hilo que los une tampoco se anuncia. */
.rung::before { content: ""; grid-column: 1; color: inherit; font-size: 15px; }
.rung::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 32px;
  bottom: -4px;
  width: 2px;
  background: var(--hairline);
}
.rung:last-child::after { display: none; }
.rung.past { color: var(--ink-soft); }
.rung.past::before { content: "✓"; }
.rung.current { color: var(--ink); font-weight: 650; }
.rung.current::before { content: "●"; }

.rung time { grid-column: 3; font-size: 14px; font-variant-numeric: tabular-nums; }
.rung-line { grid-column: 2 / -1; margin: calc(var(--space) * 1) 0 0; font-weight: 400; font-size: 14px; color: var(--ink-soft); }

/* Una foto ocupa el ancho de la columna, sin recorte a cuadrado y sin marco:
   es la prueba de que alguien está mirando el coche de verdad. */
.entry-photo, .photo-full { display: block; width: 100%; height: auto; margin: calc(var(--space) * 2) 0; border-radius: var(--r-card); }

/* Dos toques: la etiqueta es el botón y abre la cámara; el campo no se ve. El
   foco del teclado se dibuja sobre la etiqueta, porque el campo es invisible y
   un foco que no se ve es como no tenerlo. */
.photo-form { margin-top: calc(var(--space) * 4); }
.photo-form:focus-within .photo-button { outline: 3px solid var(--plate); outline-offset: 2px; }
.photo-button {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 calc(var(--space) * 5);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--ink);
  font-weight: 550;
  cursor: pointer;
}

/* El garaje del cliente: una tarjeta por coche, tranquila y con aire. Un
   cliente abre esto cuatro veces en una semana; no necesita densidad. */
.garage { display: flex; flex-direction: column; gap: calc(var(--space) * 4); }
.car {
  padding: calc(var(--space) * 5);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  background: var(--card);
  box-shadow: var(--lift-rest);
}
.car h2, .car h3 { margin: 0; font-size: 17px; }
.car-name { margin: calc(var(--space) * 2) 0 0; font-size: 18px; font-weight: 650; letter-spacing: -0.01em; }
.car-stage { margin: calc(var(--space) * 3) 0 0; font-weight: 650; }
/* Dónde está y qué se puede hacer con él. El taller va debajo de la etapa
   porque la pregunta es "en qué anda", y la respuesta completa es las dos
   cosas: en qué etapa y en qué taller. */
.car-where { margin: calc(var(--space) * 1) 0 0; color: var(--ink-soft); }
.car-does { margin: calc(var(--space) * 4) 0 0; }

/* El garaje no va dentro de una tarjeta: ya son tarjetas, y una tarjeta dentro
   de otra deja de agrupar nada. Lo que lo agrupa es su título. */
.garage-section { margin-bottom: calc(var(--space) * 4); }
.garage-section > h2 { margin-top: calc(var(--space) * 8); }
.garage-section .panel-does { margin-top: calc(var(--space) * 3); }


/* ── Devis y facturas ─────────────────────────────────────────────────────
   La tabla es lo único que puede ser más ancho que la columna, y entonces se
   desplaza sola dentro de su caja. */
.lines { overflow-x: auto; margin-bottom: calc(var(--space) * 4); }
.lines table { width: 100%; border-collapse: collapse; font-size: 14px; }
.lines th, .lines td { padding: calc(var(--space) * 3) calc(var(--space) * 2); border-bottom: 1px solid var(--hairline); text-align: left; }
.lines th { font-weight: 550; color: var(--ink-soft); }
.line-kind { display: block; color: var(--ink-soft); }
.lines .figure { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

.totals { display: grid; grid-template-columns: 1fr auto; gap: calc(var(--space) * 2) calc(var(--space) * 4); margin: 0 0 calc(var(--space) * 6); }
.totals dt { color: var(--ink-soft); }
.totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.totals .due { font-weight: 700; color: var(--ink); font-size: 20px; }

.line-fields { margin: 0 0 calc(var(--space) * 4); padding: calc(var(--space) * 4); border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--card); }
.line-figures { display: grid; grid-template-columns: repeat(2, 1fr); gap: calc(var(--space) * 3); margin-top: calc(var(--space) * 3); }
.line-figures span { display: flex; flex-direction: column; gap: calc(var(--space) * 1); }
.line-figures label { font-size: 14px; font-weight: 550; color: var(--ink-soft); }

.quick-lines { margin-bottom: calc(var(--space) * 5); }
.quick-lines h2 { font-size: 15px; font-weight: 650; color: var(--ink-soft); margin: 0 0 calc(var(--space) * 2); }

/* Lo que la pantalla del cliente pide hacer va en su propia caja, y solo eso.
   Es la única caja de la aplicación con el borde en azul de matrícula. */
/* Lo que espera una respuesta del cliente. Una sola forma para las dos
   pantallas donde aparece —el garaje y el seguimiento—, porque es la misma
   cosa: el filo azul y la sombra que flota. El color no se gasta en un fondo
   de alarma; la urgencia es posición, y esto va arriba. Ver docs/DESIGN.md. */
.asks, .waiting {
  padding: calc(var(--space) * 5);
  margin-bottom: calc(var(--space) * 6);
  border: 1px solid var(--plate);
  border-radius: var(--r-panel);
  background: var(--card);
  box-shadow: var(--lift-float);
}
.asks h2, .waiting h2 { margin: 0 0 calc(var(--space) * 2); font-size: 18px; }
.asks p { margin: 0 0 calc(var(--space) * 3); }
.refuse > summary { display: flex; align-items: center; min-height: 44px; color: var(--ink-soft); cursor: pointer; }

/* La nota en cifra y las estrellas al lado: 4,3 dice más que cuatro dibujos y
   medio. Ver docs/DESIGN.md. */
.rating { display: inline-flex; align-items: baseline; gap: calc(var(--space) * 2); }
.rating-figure { font-weight: 700; font-size: 18px; font-variant-numeric: tabular-nums; }
.rating-stars { color: var(--ink-soft); letter-spacing: 1px; }

.reviews { display: flex; flex-direction: column; gap: calc(var(--space) * 4); }
.review { padding: calc(var(--space) * 5); border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--card); box-shadow: var(--lift-rest); }
.review-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: calc(var(--space) * 3); margin: 0; font-size: 14px; color: var(--ink-soft); }
.review-who { font-weight: 650; color: var(--ink); }
.review-reply { margin-top: calc(var(--space) * 3); padding-left: calc(var(--space) * 4); border-left: 2px solid var(--rule); }
.scores { display: grid; grid-template-columns: 1fr auto; gap: calc(var(--space) * 1) calc(var(--space) * 4); margin: calc(var(--space) * 3) 0; font-size: 14px; }
.scores dt { color: var(--ink-soft); }
.scores dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }

/* Lo que hay que prever tiene su sección, y nunca la banda de prioridad: no
   corre prisa hoy. Ver docs/SPEC.md 12. */
.maintenance { margin-bottom: calc(var(--space) * 7); }
.maintenance h2 { font-size: 15px; font-weight: 650; color: var(--ink-soft); margin: 0 0 calc(var(--space) * 2); }
.due-who { margin: 0 0 calc(var(--space) * 1); font-weight: 650; }
.maintenance .rows li { padding: calc(var(--space) * 3) 0; }
.maintenance form { margin-top: calc(var(--space) * 2); }

.offer-price { font-weight: 700; font-size: 20px; }

/* Los números del mes. Una cifra grande, la comparación debajo, y nada que
   no se lea en un móvil. Ver docs/SPEC.md 14. */
/* En un móvil, una cifra por fila: "120,00 €" partido en dos líneas no es una
   cifra, es un acertijo. Dos columnas solo cuando de verdad caben. */
.figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: calc(var(--space) * 3); }

.figure-card {
  padding: calc(var(--space) * 5);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--lift-rest);
}

.wide-card { margin-bottom: calc(var(--space) * 3); }
.figure-label { margin: 0; font-size: 14px; color: var(--ink-soft); }
.figure-value { margin: calc(var(--space) * 1) 0 0; font-size: 30px; font-weight: 700; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.figure-value.big { font-size: 38px; }
.figure-value.quiet { font-size: 18px; font-weight: 550; color: var(--ink-soft); letter-spacing: 0; }
.figure-note { margin: calc(var(--space) * 1) 0 0; font-size: 14px; color: var(--ink-soft); }

/* La línea es la forma, no el dato: el dato está escrito encima. */
.trend { display: block; width: 100%; height: 40px; margin-top: calc(var(--space) * 3); color: var(--plate); }

.month-link { margin-top: calc(var(--space) * 8); }

/* El aviso del plan. Discreto y al final: no compite con el trabajo del día.
   Ver docs/SPEC.md 15. */
.plan-note { margin-top: calc(var(--space) * 7); color: var(--ink-soft); font-size: 14px; }

/* El registro del panel: una línea por entrada, leída de corrido y no como una
   tabla de la base de datos. Ver docs/SPEC.md 18. */
.log li { display: block; padding: calc(var(--space) * 3) 0; }
.log-when { display: block; font-size: 14px; color: var(--ink-soft); }
.log-who { display: block; font-weight: 650; }
.log-what { display: block; }

/* Solo se mueve lo que responde a una acción, y ni eso para quien ha pedido
   que nada se mueva. Ver docs/DESIGN.md. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
  input[type="submit"]:active, button:active { transform: none; }
}
