/* Rancho's home — sistema de marca Rancho
 *
 * La app es oscura, siempre: de noche manda la brasa, como el panel de pared. Tuvo también un
 * tema claro --el papel frío de casa con tarjetas blancas y el acento terracota-- que seguía al
 * teléfono, pero no se usaba y se sacó el 22/09/2026. Lucas: "el tema claro ni se usa, yo lo
 * sacaría".
 *
 * La interfaz está dibujada, así que va PLANA: nada de degradados ni sombras
 * que finjan volumen. La trama aparece sólo en lo que viene de una foto.
 *
 * Los nombres de las variables no cambiaron: los usa el JS que dibuja los SVG.
 */

:root {
  /* Que el navegador dibuje oscuros también lo suyo: el reloj de los campos de hora, las
     listas desplegables y las barras de desplazamiento. */
  color-scheme: dark;

  --bg: #121212;
  --zone: #1c211f;
  --card: #202725;
  --border: #33403c;
  --card-border: #2b3633;

  --text: #f2f2f0;
  --muted: #8fa39b;
  --track: #33403c;

  --accent: #e8a33d;        /* la brasa */
  --brasa-brillo: #e8702a;  /* el naranja del halo de Rancho */
  --on-accent: #121212;
  --danger: #d9705f;


  --accent-tint: rgba(232, 163, 61, 0.14);
  --accent-tint-border: rgba(232, 163, 61, 0.40);
  --danger-tint: rgba(217, 112, 95, 0.14);
  --danger-tint-border: rgba(217, 112, 95, 0.40);

  /* el catálogo es de esquinas cortas, no de burbujas */
  --radius-card: 6px;
  --radius-zone: 8px;
  --radius-btn: 5px;

  --fuente-nombre: Anton, "Futura Condensed ExtraBold", Impact, sans-serif;
  --fuente-tecnica: Oswald, "DIN Condensed", "Helvetica Neue", sans-serif;
  /* Si Yellowtail no llega (sin red, o tarda), el "cursive" de Windows es la Comic Sans: Lucas la
     vio en "la casa, de un toque" (23/09/2026). Antes van las letras a mano que traen Windows. */
  --fuente-mano: Yellowtail, "SignPainter", "Segoe Script", "Brush Script MT", cursive;
  --fuente-ui: -apple-system, system-ui, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--fuente-ui);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.wrap {
  max-width: 1100px; margin: 0 auto;
  /* Abajo, el lugar del botón de Rancho (58 y 16 de margen) más 16 de aire: al llegar al fondo no tapa
     nada, ni la banda (Ux/Ui). */
  padding: calc(16px + env(safe-area-inset-top)) calc(16px + env(safe-area-inset-right)) calc(90px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left));
}

/* ── la cabecera es la cabecera de una ficha ─────────────────────────── */
header { margin-bottom: 16px; }
.ficha-cab { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pildora {
  display: inline-block; background: var(--text); color: var(--bg);
  font-family: var(--fuente-tecnica); font-weight: 600; font-size: 12px;
  letter-spacing: 0.15em; padding: 4px 10px 3px 10px; border-radius: var(--radius-btn);
}
.status { font-family: var(--fuente-tecnica); font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); display: flex; align-items: center; gap: 6px; margin-left: auto; }
.dot { width: 8px; height: 8px; border-radius: 2px; background: var(--accent); display: inline-block; }
.dot.off { background: var(--danger); }
/* La casa no contesta y el Worker sí: gris, porque el rojo ya lo lleva el aviso de abajo (Ux/Ui, Voz y tono). */
.dot.gris { background: var(--muted); }

/* El aviso dice el motivo real de una falla, en palabras. Va debajo de la
 * cabecera porque el chip de estado es de un vistazo y no le entra una frase.
 * Plano, como todo lo demas: borde de sello, sin sombra. */
.aviso { background: var(--card); border: 1px solid var(--danger); border-left-width: 3px;
  border-radius: var(--radius-card); color: var(--text); font-size: 14px; line-height: 1.45;
  padding: 10px 13px; margin: 0 0 12px; }
.aviso[hidden] { display: none; }
/* En un mantenimiento no es una falla: el sello en brasa, como el del Inicio (.hoy-aviso-casa.espera). */
.aviso.espera { border-color: var(--border); border-left-color: var(--accent); }
/* El renglón de la casa en el corte: de cuándo es la lista y cuánto insiste Rancho. */
.aviso-renglon { display: block; margin-top: 3px; font-size: 12.5px; line-height: 1.4; color: var(--muted); }

/* ── la casa en el corte (docs/planes/2026-09-24-la-casa-en-el-corte.md) ──────────────────────────── */
/* La última lista conocida: los controles enteros y el estado en gris, sin relleno ni brasa, porque no se sabe. El
   único rojo es el del aviso de arriba; cada aparato dice NO CONTESTA en gris. */
.card.corte .pct { color: var(--muted); }
input[type="range"].sin-dato { -webkit-appearance: none; appearance: none; background: transparent; }
input[type="range"].sin-dato::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: var(--border); }
input[type="range"].sin-dato::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 24px; height: 24px; margin-top: -10px;
  border: none; border-radius: 50%; background: var(--muted); }
.corte-palabra { margin-left: auto; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); }
.tval.sin-dato { color: var(--muted); }
.tval.guardada-anillo { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 2px; }
.tg.corte::before { background: none; border-color: var(--border); }
.tg.corte .knob { background: var(--muted); }
.tg.corte.lado-on .knob, .tg.corte.pedido-on .knob { left: 22px; }
.tg.corte.pedido-off .knob { left: 4px; }
.tg.corte.pedido-on .knob, .tg.corte.pedido-off .knob { background: var(--text); }

/* ── cuando una orden no salió (falla.js) ─────────────────────────────── */
/* Lo que tocaste: 2 px de contorno en el rojo de la noche, 6 s. Contorno y nunca relleno: relleno es
   lo que está actuando ahora, y una orden que falló ya pasó. Se apaga en 300 ms. */
.falla-toque { outline: 2px solid var(--danger); outline-offset: 1px; transition: outline-color .3s ease; }
.falla-toque.sale { outline-color: transparent; }
/* La franja: abajo, en el lugar del botón de Rancho, plana. Tapa lo de abajo un rato y no empuja
   nada: lo que estabas mirando no se corre. Qué no salió en 14, y por qué en 12,5, un renglón cada
   uno. */
.franja-falla {
  position: fixed; z-index: 45;
  left: calc(16px + env(safe-area-inset-left)); right: calc(16px + env(safe-area-inset-right));
  bottom: calc(16px + env(safe-area-inset-bottom));
  max-width: 560px; margin: 0 auto;
  display: flex; align-items: center; gap: 4px;
  background: var(--card); border: 1px solid var(--danger); border-left-width: 3px; border-radius: var(--radius-card);
  padding: 6px 0 6px 13px;
  opacity: 0; translate: 0 16px; transition: opacity .2s ease-out, translate .2s ease-out;
}
.franja-falla.entra { opacity: 1; translate: 0 0; }
.franja-falla[hidden] { display: none; }
.ff-texto { flex: 1; min-width: 0; }
.ff-que, .ff-porque { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ff-que { font-family: var(--fuente-ui); font-size: 14px; line-height: 1.35; color: var(--text); }
.ff-porque { font-family: var(--fuente-ui); font-size: 12.5px; line-height: 1.35; color: var(--muted); }
.ff-cerrar { flex: none; width: 44px; height: 44px; padding: 0; background: none; border: none; color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center; }
/* La orden que espera a la casa (falla.js; Ux/Ui, 2026-09-24-orden-en-espera.md): lo pedido lleva el contorno
   de brasa, sin relleno, mientras espera; si no sale, pasa al rojo 6 s como una falla. En el interruptor el
   anillo va en la pista, no en el botón de 44. La franja, con el sello en brasa y CANCELAR en vez de la cruz,
   de la misma forma que la cruz: sin fondo ni borde, gris, del ancho de la palabra. */
.guardada-toque { outline: 2px solid var(--accent); outline-offset: 1px; }
.guardada-toque.falla-toque { outline-color: var(--danger); }
.tg.guardada-toque { outline: none; }
.tg.guardada-toque::before { outline: 2px solid var(--accent); outline-offset: 1px; }
.franja-falla.guardada { border-color: var(--border); border-left-color: var(--accent); }
.ff-cancelar { flex: none; height: 44px; padding: 0 12px; background: none; border: none; color: var(--muted); cursor: pointer;
  font-family: var(--fuente-tecnica); font-size: 13px; letter-spacing: 0.1em; text-transform: uppercase; }
.ff-cerrar[hidden], .ff-cancelar[hidden] { display: none; }
/* Lo pedido que la pestaña marca por su cuenta (acs.js, tvs.js): el mismo anillo. El interruptor lleva la
   perilla del lado pedido y la pista como está de verdad (Ux/Ui, con Design system). */
.chip.guardada-anillo { outline: 2px solid var(--accent); outline-offset: 1px; }
.tg.guardada-anillo::before { outline: 2px solid var(--accent); outline-offset: 1px; }
.tg.pedido-on .knob { left: 22px; }
.tg.on.pedido-off .knob { left: 4px; }
/* Los puntitos de un botón de una vez mientras insiste, abajo y al centro: no mueven nada del botón (en el
   renglón, el «▼ CERRAR» de una cortina se partía en dos). */
button.guardada-toque { position: relative; }
/* Con el botón adelante, para ganarle a .rancho-puntos de asistente.css, que carga después. */
.guardada-toque .guardada-puntos { position: absolute; left: 50%; bottom: 5px; transform: translateX(-50%); display: inline-flex; padding: 0; gap: 3px; }
.guardada-toque .guardada-puntos span { width: 4px; height: 4px; background: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .franja-falla { translate: none; transition: opacity .2s ease-out; }
}
.cab-regla { border-bottom: 2px solid var(--text); margin: 9px 0 11px; }

/* ── controles ───────────────────────────────────────────────────────── */
button {
  font: inherit; color: var(--text); cursor: pointer;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-btn); padding: 9px 13px;
  -webkit-tap-highlight-color: transparent; transition: transform .05s ease;
  /* Sin esto, tocar dos veces seguidas un botón (el +1 de la temperatura, el +/− de una tele) hace zoom, como un
     doble tap cualquiera del navegador (Lucas, 25/09/2026, encontrado por Design system). No es el pellizco: eso
     sigue andando, y el viewport no lleva user-scalable=no. */
  touch-action: manipulation;
}
button:active { transform: scale(0.97); }
.btn-accent { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

/* Los mandos hablan todos en la misma voz técnica.
 * Los dos de arriba se reparten el ancho entero, como los de adentro de cada ambiente. Sin el
 * flex quedaban pegados a la izquierda, de anchos distintos entre sí, y con 79px de aire al
 * costado en un teléfono. */
.topbar { display: flex; gap: 8px; margin-bottom: 14px; }
.topbar button { flex: 1; min-height: 44px; font-family: var(--fuente-tecnica); font-size: 12.5px; letter-spacing: 0.1em; text-transform: uppercase; padding: 10px 14px; }

/* ── pestañas ────────────────────────────────────────────────────────── */
.tabnav { display: flex; gap: 8px; margin-bottom: 16px; }
.tabs { display: flex; gap: 4px; background: var(--zone); border: 1px solid var(--border); border-radius: var(--radius-zone); padding: 3px; flex: 1; }
.tabs-auto { flex: none; }
.tab {
  flex: 1; text-align: center; padding: 8px 10px; border: none; background: transparent;
  color: var(--muted); cursor: pointer; border-radius: var(--radius-btn);
  font-family: var(--fuente-tecnica); font-weight: 500; font-size: 12.5px;
  letter-spacing: 0.1em; text-transform: uppercase;
}
.tab.active { background: var(--text); color: var(--bg); }
/* El dibujo mide 33 de alto; la zona de toque, 45: 6 px de más arriba y abajo, sin cambiar lo que se ve
   (Ux/Ui, aprobado por Design system). */
.tab { position: relative; }
.tab::before { content: ''; position: absolute; left: 0; right: 0; top: -6px; bottom: -6px; }

/* ── el índice: cada aparato es un renglón del catálogo ──────────────── */
.zcols { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; align-items: start; }

.zone { background: var(--card); border: 1px solid var(--card-border); border-radius: var(--radius-zone); overflow: hidden; }
.zone-top { display: flex; align-items: center; gap: 8px; padding: 11px 14px 9px; }
/* El cuadradito dice estado, siempre: brasa si en esa zona algo anda ahora, --track si no (Design system y Ux/Ui,
   auditoría del 25/09/2026). Las secciones sin estado lo llevan igual, en --track, así todos los títulos arrancan igual. */
.zone-marca { width: 11px; height: 11px; border-radius: 2px; background: var(--track); flex: none; }
.zone-marca.anda { background: var(--accent); }
.zone-name { font-family: var(--fuente-nombre); font-size: 19px; line-height: 1; }
.zone-pct { font-family: var(--fuente-tecnica); font-size: 13px; letter-spacing: 0.08em; color: var(--muted); margin-left: auto; }
/* 44 de alto para el dedo sin agrandar la tarjeta: los márgenes negativos le devuelven los 26 que
   ocupaba (16 del deslizador y 10 de aire). Lo de más cae en el aire de arriba y de abajo, donde no
   hay nada que tocar. */
.zone input[type="range"] { width: calc(100% - 28px); margin: -9px 14px -9px; }
.zone-btns { display: flex; gap: 6px; padding: 0 14px 12px; }
.zone-btns button { flex: 1; min-height: 44px; font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; padding: 7px; }

/* el renglón */
.card {
  border-top: 1px solid var(--card-border); padding: 11px 14px;
  display: flex; flex-direction: column; gap: 9px;
}
/* Como .card.corte (línea de arriba): el valor en gris, sin relleno, con el borde de siempre y los controles
   enteros — «esta no contesta», no «esto está muerto» (Design system, 27/09/2026). */
.card.offline .pct { color: var(--muted); }
.crow { display: flex; align-items: baseline; gap: 10px; }
.cnro { font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.08em; color: var(--muted); flex: none; width: 26px; }
.cname { font-family: var(--fuente-nombre); font-size: 17px; line-height: 1.05; }
.cpos { margin-left: auto; text-align: right; white-space: nowrap; }
.cpos .pct { font-family: var(--fuente-tecnica); font-weight: 500; font-size: 17px; letter-spacing: 0.04em; }
.cpos .word { font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
/* 44 de alto para el dedo, con la pista dibujada fina como siempre: el navegador la centra. */
/* Los deslizadores de posición de las cortinas, con dos toques rápidos, podían hacer el mismo zoom que un botón
   (Calidad, 25/09/2026). */
input[type="range"] { width: 100%; height: 44px; accent-color: var(--accent); touch-action: manipulation; }
.cbtns { display: flex; gap: 6px; }
.cbtns button { flex: 1; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; gap: 5px; font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; padding: 8px; }

/* El aviso de la cortina que perdió la cuenta con un corte de luz. No es una alarma: es una
   nota al pie con un botón, del mismo tamaño que los otros botones de la tarjeta. */
.cancla { display: flex; align-items: center; gap: 8px; }
.cancla span { font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.04em; color: var(--muted); }
.cancla button { margin-left: auto; flex: none; min-height: 44px; font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; padding: 8px 12px; }

/* El mapa que dibuja la aspiradora. Fondo del mismo color que la tarjeta porque el esquema
   Grayscale lo deja transparente donde no hay casa, así que el hueco lo pone la app. */
.vmapa { position: relative; margin-top: 12px; border: 1px solid var(--card-border); border-radius: var(--radius-card); background: var(--zone); overflow: hidden;
  isolation: isolate; }
/* Sin esto, mantener apretado sobre una imagen abre el "guardar imagen" del telefono y el
   gesto de dibujar la zona se pierde la mitad de las veces. */
.vmapa img { display: block; width: 100%; height: 100%; -webkit-touch-callout: none; user-select: none; -webkit-user-select: none; }
/* El mapa en los grises de la app (Design system, Dora en la marca): toma el tono de --zone y conserva su luz. Traía
   los colores de la aspiradora, con zonas rojas que no son una falla. Lo que va encima (Dora, el recorrido, la zona
   que se marca y las piezas) queda como lo más claro. */
.vmapa img { mix-blend-mode: luminosity; }

/* El nombre de cada pieza, puesto donde queda la pieza. Ya no se toca: se elige en la fila de
   botones de abajo (.vpiezas-fila), y acá se muestra lo mismo. Fondo semiopaco para que se lea
   sobre cualquier parte del mapa. */
.vpiezas { position: absolute; inset: 0; pointer-events: none; }
/* Todo lo que va encima del mapa se agranda con el --vesc que pone el JS, que sale del ancho
   que tiene el mapa en pantalla. Antes estaba en pixeles fijos: el mapa se estiraba en una
   pantalla grande y las pastillas quedaban de juguete. */
.vpieza { position: absolute; transform: translate(-50%, -50%); pointer-events: none;
  font-size: calc(11px * var(--vesc, 1)); line-height: 1; white-space: nowrap;
  padding: calc(5px * var(--vesc, 1)) calc(7px * var(--vesc, 1));
  border-radius: calc(4px * var(--vesc, 1));
  background: color-mix(in srgb, var(--card) 88%, transparent); color: var(--text);
  border: 1px solid var(--card-border); font-family: inherit;
  user-select: none; -webkit-user-select: none; }
/* La misma gramática que los botones de la fila (Design system): elegida en contorno de acento,
   porque es lo que va a pasar; la que está limpiando, rellena, porque es lo que está pasando. */
.vpieza.on { border-color: var(--accent); color: var(--accent); }
.vpieza.limpiando { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

/* Las piezas para elegir, en botones de 44 debajo del mapa (aspiradora.js, renderPiezas). Cada una
   toma su ancho y el espacio de más se reparte igual, como repartir() en el panel. */
.vpiezas-fila { display: flex; gap: 6px; margin-top: 12px; }
.vpiezas-fila.dos-filas { display: grid; }
.vpbtn { flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0 8px; background: transparent; color: var(--muted);
  border: 1px solid var(--border); border-radius: var(--radius-btn); white-space: nowrap;
  font-family: var(--fuente-tecnica); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; }
.vpbtn.elegida { border-color: var(--accent); color: var(--accent); }
.vpbtn.limpiando { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
/* Los patios se dibujan igual pero apagados: están en el mapa, pero la aspiradora no sale afuera
   y no están en la fila para elegir. Apagados con el gris de la marca, sin transparencia ni
   itálica (Design system, 25/09/2026). */
.vpieza.afuera { color: var(--muted); }

/* La base. Es una referencia, no un control: sin ella, Dora parada arriba de la nada no se
   entiende. */
.vbase { position: absolute; width: calc(9px * var(--vesc, 1)); height: calc(9px * var(--vesc, 1));
  transform: translate(-50%, -50%); border: calc(2px * var(--vesc, 1)) solid var(--muted);
  border-radius: calc(2px * var(--vesc, 1)); background: var(--card); pointer-events: none; }

/* El renglon que ensenia a usar el mapa. Va en minuscula y a 12,5px a proposito: es el unico
   texto que sirve para aprender, y la tipografia tecnica en mayusculas no se lee. */
.vayuda { font-size: 12.5px; line-height: 1.35; color: var(--muted); margin-top: 12px; }
/* Dora. La dibuja la app y no el mapa, porque el mapa se rehace cada 5 segundos y así daba
   saltos; acá se interpola entre dato y dato. Es un círculo pelado: la flechita que marcaba
   para dónde miraba ensuciaba más de lo que informaba. */
.vdora { position: absolute; width: calc(13px * var(--vesc, 1)); height: calc(13px * var(--vesc, 1));
  margin: 0; border-radius: 50%; transform: translate(-50%, -50%);
  background: var(--accent); border: calc(2px * var(--vesc, 1)) solid var(--bg);
  box-shadow: 0 0 0 1px var(--accent); transition: none; }

/* El camino recorrido. Lo dibuja la app y no el mapa: la imagen del mapa es de AHORA y el
   monigote va unos segundos atrás a propósito, así que la línea de la imagen aparecía antes de
   que Dora pasara por ahí. Dibujándola nosotros, crece justo abajo del círculo.
   non-scaling-stroke: el SVG está en píxeles del mapa (1580 de ancho) pero se ve a 343, y sin
   eso la línea quedaría finita como un pelo. */
.vrastro { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.vrastro path { fill: none; stroke-width: calc(2px * var(--vesc, 1)); stroke-linejoin: round;
  stroke-linecap: round; vector-effect: non-scaling-stroke; stroke-opacity: 0.85; }
/* Todo en brasa, y lo que estaba haciendo se dice por la línea y no por el color (Ux/Ui y Design system, Dora en la
   marca: el azul y el verde no son de la marca): barrer, llena; trapear, puntos cada 5 (con la punta redonda, una raya
   de largo 0 es un punto); las dos, raya y punto. Los traslados --salir de la base, volver a lavar la mopa-- NO se
   dibujan: Lucas, "si ya termino la limpieza no te importa como llego, que te marque lo que limpiaba nomas". El
   camino queda cortado donde no limpio, que es la verdad, en vez de unido por una recta que nadie recorrio. */
.vrastro path { stroke: var(--accent); }
.vrastro .trapear { stroke-dasharray: 0 calc(5px * var(--vesc, 1)); }
.vrastro .ambos   { stroke-dasharray: calc(8px * var(--vesc, 1)) calc(5px * var(--vesc, 1)) 0 calc(5px * var(--vesc, 1)); }
/* Una limpieza terminada queda de recuerdo, en gris y no transparente: una brasa al 38 % sobre el mapa gris era un
   marrón sucio. La brasa es lo que está pasando. */
.vrastro.terminada path { stroke: var(--muted); stroke-opacity: 1; }
.vmapa.dibujando { cursor: crosshair; touch-action: none; }
.vmapa.dibujando::after { content: 'arrastrá para marcar la zona'; position: absolute; left: 8px; top: 8px; font-family: var(--fuente-tecnica); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); background: rgba(0,0,0,.55); padding: 3px 7px; border-radius: var(--radius-btn); }
.vmapa-sel { position: absolute; border: 2px solid var(--accent); background: color-mix(in srgb, var(--accent) 18%, transparent); pointer-events: none; }

/* ── rótulos y vacíos ────────────────────────────────────────────────── */
.section-h, .lbl { font-family: var(--fuente-tecnica); font-weight: 500; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); margin: 4px 0 8px; }
.lbl { margin: 10px 0 6px; }
.empty { font-family: var(--fuente-mano); font-size: 21px; color: var(--muted); }

/* ── automatizaciones ────────────────────────────────────────────────── */
.auto-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; align-items: start; }
/* Una opción larga en un select (el nombre de una cortina) ensanchaba la columna y la regla se pasaba 12 px
   del margen en Cortinas (Ux/Ui): la columna no crece más que la pantalla. */
.auto-cols > * { min-width: 0; }
.field select { max-width: 100%; }
.rule { display: flex; align-items: center; gap: 12px; background: var(--card); border: 1px solid var(--card-border); border-radius: var(--radius-card); padding: 12px 14px; margin-bottom: 8px; }
.rtime { font-family: var(--fuente-tecnica); font-weight: 500; font-size: 19px; letter-spacing: 0.04em; min-width: 54px; }
.rinfo { flex: 1; min-width: 0; }
.rwhat { font-size: 14.5px; font-weight: 500; }
.rwhen { font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
/* La regla que hoy no salió: un renglón de 12 abajo, con la hora en el rojo de la noche y lo demás
   apagado (automations.js, reglaInfo). */
/* Lo que hace una rutina de Rancho (automations.js): la letra del renglón de estado, hasta tres renglones. */
.rhace { font-size: 12px; line-height: 1.35; color: var(--muted); margin-top: 3px; }
/* «LAS DE RANCHO» es su propia sección: las reglas empiezan un poco más abajo. */
[id^="rutina-"] + .section-h { margin-top: 16px; }
.rnosalio { font-size: 12px; line-height: 1.35; color: var(--muted); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rnosalio-hora { color: var(--danger); font-variant-numeric: tabular-nums; }
/* La regla de Dora que ya no limpia nada: ese renglón, en el rojo de la noche (Design system). */
.rwhat.rnolimpia { color: var(--danger); }
/* El interruptor se dibuja de 44 x 26, pero el botón mide 44 x 44, el mínimo de toque de la app:
   la pista es un ::before centrado y el botón en sí no se ve. */
.tg { width: 44px; height: 44px; border: none; background: none; position: relative; cursor: pointer; padding: 0; flex: none; }
.tg::before { content: ''; position: absolute; left: 0; right: 0; top: 9px; height: 26px; border-radius: 4px; border: 1px solid var(--border); background: var(--track); }
.tg .knob { position: absolute; top: 13px; left: 4px; width: 18px; height: 18px; border-radius: 2px; background: var(--card); transition: left .12s ease; }
.tg.on::before { background: var(--accent); border-color: var(--accent); }
.tg.on .knob { left: 22px; background: var(--on-accent); }
/* El tachito: ancho fijo para que al armarse ("¿Borrar?") no se corra el renglón, y alto de
   dedo. Armado, en el rojo de la noche. */
.rdel { flex: none; width: 62px; height: 44px; margin: -8px -6px -8px 0; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 1px solid transparent; border-radius: var(--radius-btn); color: var(--muted); cursor: pointer;
  font-family: var(--fuente-tecnica); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; }
.rdel.armado { color: var(--danger); background: var(--danger-tint); border-color: var(--danger-tint-border); }

.addcard { background: var(--card); border: 1px solid var(--card-border); border-radius: var(--radius-zone); padding: 16px; }
.field { margin-bottom: 13px; }
.field label { display: block; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); margin-bottom: 5px; }
.frow { display: flex; gap: 10px; }
.frow .field { flex: 1; }
.field input, .field select { width: 100%; min-height: 44px; padding: 9px 10px; border-radius: var(--radius-btn); border: 1px solid var(--border); background: var(--bg); color: var(--text); font: inherit; }
/* Un solo campo en toda la app (Ux/Ui, de la pasada de Calidad): en el iPhone, el desplegable salía con el gris y
   el alto del sistema al lado de la hora. Sin el aspecto del sistema, con la flecha en --muted. */
.field select {
  -webkit-appearance: none; appearance: none; padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%238fa39b' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
}
/* Los grados sin las flechitas de WebKit: se escriben. */
.field input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.field input[type="number"]::-webkit-inner-spin-button, .field input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
/* Los días: el botón es la zona de toque y el span, el dibujo (Ux/Ui pidió 44, de la pasada de Calidad). A 375, la
   fila mide 309 adentro de la tarjeta: cada botón toca 44,1 y el día se ve de 42,1 con 2 de aire entre uno y otro,
   como antes. No va con un ::before: WebKit no deja tocar lo que sobresale a la derecha de un botón. */
.days { display: flex; }
.day { flex: 1 1 0; min-width: 0; max-width: 46px; height: 44px; padding: 0 1px; border: 0; background: transparent; cursor: pointer;
  color: var(--text); font-family: var(--fuente-tecnica); font-size: 12px; }
.day > span { display: flex; align-items: center; justify-content: center; height: 100%; border-radius: 4px; border: 1px solid var(--border); }
.day.sel > span { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.primary { width: 100%; min-height: 44px; background: var(--accent); color: var(--on-accent); border: 1px solid var(--accent); border-radius: var(--radius-btn); padding: 11px; font-family: var(--fuente-tecnica); font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; cursor: pointer; }
.primary:disabled { opacity: 0.45; cursor: default; }

.seg { display: flex; gap: 4px; background: var(--zone); border: 1px solid var(--border); border-radius: var(--radius-zone); padding: 3px; margin-bottom: 14px; }
.seg button { flex: 1; min-height: 44px; text-align: center; padding: 8px; border-radius: var(--radius-btn); border: none; background: transparent; color: var(--muted); cursor: pointer; font-family: var(--fuente-tecnica); font-weight: 500; font-size: 12.5px; letter-spacing: 0.1em; text-transform: uppercase; }
.seg button.active { background: var(--text); color: var(--bg); }

/* ── inicio: la casa de un vistazo ──────────────────────────────────── */
/* El clima arriba, las cuatro cosas de la casa en una grilla y lo programado abajo. En el
   teléfono la grilla va de a dos; en una pantalla ancha, las cuatro en fila. La marquita de
   cada cosa se pinta del color de la casa cuando algo quedó abierto o prendido: se ve de
   lejos qué hay que mirar. */
.hoy { display: grid; gap: 12px; }
/* El clima de Inicio mide 124, como la tarjeta del panel (inicio.js): todos los renglones de una
   línea y de alto fijo, así un cielo largo se corta con puntos en vez de estirarla. */
.hoy-clima { padding: 12px 16px 13px; }
.hoy-fecha { font-family: var(--fuente-tecnica); font-size: 12px; line-height: 16px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.hoy-clima-fila { display: flex; align-items: center; gap: 14px; margin-top: 4px; }
/* Sin Anton en los valores del Inicio (Ux/Ui, auditoría de Design system, docs/planes/2026-09-24-inicio-sin-anton-ni-emojis.md). */
.hoy-temp { font: 600 54px/.9 var(--fuente-tecnica); font-variant-numeric: tabular-nums; flex: none; }
.hoy-clima-txt { flex: 1; min-width: 0; }
.hoy-sensacion { font: 600 16px/20px var(--fuente-ui); }
.hoy-sub { font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-top: 4px; }
.hoy-clima-txt .hoy-sub { margin-top: 2px; line-height: 16px; min-height: 16px; }
.hoy-clima-txt .hoy-sub + .hoy-sub { margin-top: 0; }
.hoy-fecha, .hoy-sensacion, .hoy-clima-txt .hoy-sub, .hoy-lluvia { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hoy-lluvia { font-size: 13px; line-height: 18px; margin-top: 5px; color: var(--accent); }
.hoy-lluvia.no { color: var(--muted); }

/* Una cortina que no contesta hace 10 minutos (el vigía, src/vigia.js): la misma franja plana del
   aviso de falla, pero quieta en su lugar, entre el clima y la grilla, hasta que vuelva. */
.hoy-aviso-casa { background: var(--card); border: 1px solid var(--danger); border-left-width: 3px; border-radius: var(--radius-card);
  padding: 9px 13px; }
.hoy-aviso-que { font-size: 14px; line-height: 1.35; color: var(--text); text-wrap: balance; }
/* Lo que espera a la casa y el mantenimiento: no es una falla, va con el sello en brasa (src/guardadas.js). */
.hoy-aviso-casa.espera { border-color: var(--border); border-left-color: var(--accent); }
.hoy-aviso-renglon { display: flex; align-items: center; gap: 6px; font-size: 12px; line-height: 1.4; color: var(--muted); margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hoy-aviso-renglon .rancho-puntos { padding: 0; gap: 3px; flex: none; }
.hoy-aviso-renglon .rancho-puntos span { width: 4px; height: 4px; background: var(--muted); }
.hoy-aviso-porque { font-size: 12.5px; line-height: 1.35; color: var(--muted); }
/* El del giro al revés lleva el botón que lo corrige a la derecha, como «Reacomodar» en la tarjeta. */
.hoy-aviso-fila { display: flex; align-items: center; gap: 10px; }
.hoy-aviso-txt { flex: 1; min-width: 0; }
/* Y si además hay una que no contesta, va abajo en un renglón, en el mismo bloque (Ux/Ui). */
.hoy-aviso-ademas { font-size: 12.5px; line-height: 1.35; color: var(--muted); border-top: 1px solid var(--card-border);
  margin-top: 8px; padding-top: 7px; }
.hoy-aviso-boton { flex: none; min-height: 44px; display: inline-flex; align-items: center; gap: 6px; font-family: var(--fuente-tecnica);
  font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; padding: 8px 12px; }
.hoy-aviso-boton:disabled { cursor: default; transform: none; }
.hoy-grilla { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
@media (min-width: 900px) { .hoy-grilla { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* Con las luces, cinco tarjetas (inicio.js): la última, sola en su fila, va a lo ancho; en una pantalla ancha, las
   cinco en fila (Ux/Ui, docs/planes/2026-09-24-luces.md). */
.hoy-cosa.sola { grid-column: 1 / -1; }
@media (min-width: 900px) {
  .hoy-cosa.sola { grid-column: auto; }
  .hoy-grilla.cinco { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
.hoy-cosa { display: flex; flex-direction: column; align-items: stretch; gap: 3px; min-height: 104px; padding: 12px 14px 13px;
  text-align: left; color: var(--text); font: inherit; cursor: pointer; }
.hoy-cosa:hover { border-color: var(--accent); }
.hoy-cosa-top { display: flex; align-items: center; gap: 7px; }
.hoy-cosa .lbl { margin: 0; }
.hoy-cosa .zone-marca { background: var(--track); }
.hoy-cosa.activa .zone-marca { background: var(--accent); }
.hoy-cosa.alerta .zone-marca { background: var(--danger); }
.hoy-valor { font: 600 20px/1.15 var(--fuente-ui); margin-top: 5px; }
.hoy-detalle { font-size: 12.5px; line-height: 1.35; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hoy-cosa.alerta .hoy-detalle { color: var(--danger); }
/* Cada cosa del detalle, entera: el renglón se corta en los puntos y las comas (inicio.js). */
.hoy-entera { white-space: nowrap; }

/* Lo programado: una fila por cosa, la hora en números parejos. Lo que ya pasó queda apagado y
   lo que viene primero lleva el color de la casa. */
.hoy-agenda { padding-bottom: 6px; }
.hoy-fila { display: flex; align-items: baseline; gap: 12px; padding: 8px 14px; border-top: 1px solid var(--card-border); }
.hoy-hora { flex: none; width: 44px; font-family: var(--fuente-tecnica); font-weight: 500; font-size: 15px; letter-spacing: 0.04em; font-variant-numeric: tabular-nums; }
.hoy-que { flex: 1; min-width: 0; font-size: 13.5px; line-height: 1.35; }
.hoy-fila.paso { color: var(--muted); }
.hoy-fila.proxima .hoy-hora { color: var(--accent); }
.hoy-prox { flex: none; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); }
/* Cómo salió lo que ya pasó, según la bitácora (el aviso de falla de Design system). NO SALIÓ: la hora
   y la marca en el rojo de la noche, y el porqué en --muted: dos cosas en rojo, no tres, porque dos
   renglones rojos gritan. INSISTIENDO: la hora en --text y la marca apagada, con los tres puntitos.
   A LA SEGUNDA: como lo que ya pasó, con su marca apagada. */
.hoy-marca { flex: none; display: inline-flex; align-items: center; gap: 5px; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.hoy-marca-fallo, .hoy-fila.fallo .hoy-hora { color: var(--danger); }
.hoy-marca .rancho-puntos { padding: 0; gap: 3px; }
.hoy-marca .rancho-puntos span { width: 4px; height: 4px; background: var(--muted); }
.hoy-porque { display: block; font-size: 12px; line-height: 1.35; color: var(--muted); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hoy-vacio { padding: 4px 14px 10px; font-size: 13px; color: var(--muted); }

/* ── clima y sol ─────────────────────────────────────────────────────── */
/* Los dibujos del clima (clima-iconos.js), en los colores de la marca: cada parte con su clase, y todo con
   currentColor. La brasa, solo para el sol; lo claro es la luz, porque en la noche la tinta es el fondo. */
.ico-clima { display: block; flex: none; overflow: visible; }
.ico-clima .i-sol { color: var(--accent); }
.ico-clima .i-gris { color: var(--muted); }
.ico-clima .i-luz { color: var(--text); }
.wcard, .solcard { background: var(--card); border: 1px solid var(--card-border); border-radius: var(--radius-card); padding: 13px 16px; margin-bottom: 12px; }
.wtemp { font-family: var(--fuente-tecnica); font-weight: 500; font-size: 32px; line-height: 1; letter-spacing: 0.02em; }
.wloc, .wcond, .sol-sub, .sol-hora { font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }

/* El sol de Cortinas, en 124 como las otras tarjetas que informan (sol.js): el arco a la izquierda,
   de 51 como en el panel, y la columna del estado a la derecha, de ancho fijo para que el arco no
   se mueva cuando cambia el texto. 1 + 21 + 80 + 21 + 1. */
.solcard { display: flex; align-items: center; gap: 14px; padding: 21px 16px; }
.sol-arc-svg { flex: 1; min-width: 0; height: 51px; display: block; }
/* 140: el dibujo (27) y el estado más largo, «Sol con nubes» (107), con 6 entre los dos. */
.sol-estado { flex: none; width: 140px; }
.sol-now { display: flex; align-items: center; gap: 6px; height: 24px; }
.sol-state { font: 600 16px/1 var(--fuente-ui); white-space: nowrap; }
.sol-estado .sol-sub { margin-top: 4px; }
.sol-estado .sol-sub, .sol-hora { line-height: 16px; white-space: nowrap; }
.sol-hora + .sol-hora, .sol-sub + .sol-hora { margin-top: 2px; }
/* A 11 px el amanecer y el atardecer eran dos cuadraditos de color. */
.sol-hora { display: flex; align-items: center; gap: 6px; }

/* El clima de Aires mide 124, la tarjeta de información del panel de la pared (regla del tercio,
   docs/planes/2026-09-23-regla-del-tercio.md): 1 + 8 + 36 + 3 + 40 + 3 + 24 + 8 + 1. Tres
   renglones de alto fijo, así un cielo con nombre largo no la estira. */
.wcard { display: flex; flex-direction: column; align-items: stretch; gap: 3px; padding: 8px 16px; }
.wnow { display: flex; align-items: center; gap: 8px; height: 36px; }
.wnow .wcond { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wcard .chart { height: 40px; }
.wcard .chart-yax { height: 40px; }
.wcard .chart-main > svg { height: 40px; }
.wfc { display: flex; align-items: center; justify-content: space-between; height: 24px; }
.wday { display: flex; align-items: center; gap: 4px; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.06em; color: var(--muted); }
.wday b { color: var(--text); font-weight: 500; }

.chart { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
.chart-yax { display: flex; flex-direction: column; justify-content: space-between; height: 96px; font-family: var(--fuente-tecnica); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); text-align: right; white-space: nowrap; }
.chart-main { flex: 1; min-width: 0; }
.chart-main > svg { width: 100%; height: 96px; display: block; }
.chart-xax { display: flex; justify-content: space-between; font-family: var(--fuente-tecnica); font-size: 10px; letter-spacing: 0.06em; color: var(--muted); margin-top: 4px; }

/* ── aires ───────────────────────────────────────────────────────────── */
/* Las combinaciones, entre el clima y los aires: un toque deja el aire entero como se pide
   (acs.js). 48 de alto y 8 de separación. En contorno cuando ya está así, porque tocarla no
   hace nada: el relleno de acento dice "apretame" (Design system). */
.combinaciones { display: flex; gap: 8px; margin-bottom: 8px; }
.combinaciones[hidden] { display: none; }
.combinacion { flex: 1; min-width: 0; height: 48px; display: flex; align-items: center; gap: 9px; padding: 0 14px;
  background: transparent; color: var(--text); text-align: left;
  font-family: var(--fuente-tecnica); font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; }
.combinacion svg { width: 18px; height: 18px; flex: none; }
.comb-nombre { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.comb-que { flex: none; margin-left: auto; font-size: 11px; letter-spacing: 0.1em; color: var(--muted); }
.combinacion .rancho-puntos { padding: 0; }
.combinacion.activa { border-color: var(--accent); color: var(--accent); cursor: default; }
.combinacion.activa .comb-que { color: var(--accent); }
.combinacion.activa:active { transform: none; }

.accard { background: var(--card); border: 1px solid var(--card-border); border-radius: var(--radius-card); padding: 13px 15px; margin-bottom: 9px; }
.accard:last-child { margin-bottom: 0; }
/* Apagado: el acento es para lo que está vivo. Un chip elegido pero sin
   corriente vuelve a ser un contorno, no un terracota lavado. Pero contorno
   no quiere decir invisible: antes quedaba idéntico a los no elegidos --mismo
   fondo, mismo color, mismo borde-- y apagado no se podía saber en qué modo
   iba a arrancar el aire. Se queda sin relleno, y se distingue por el borde. */
/* Apagado, sin transparencia (Design system, auditoría del 24/09): al 62 % el interruptor para prenderlo parecía
   muerto. Lo apagado lo dice el gris del número, y los controles quedan enteros. */
.accard.off .tval { color: var(--muted); }
.accard.off .chip.on { background: transparent; color: var(--text); border-color: var(--accent); }
.acrow { display: flex; align-items: center; justify-content: space-between; }
.acname { font-family: var(--fuente-nombre); font-size: 18px; line-height: 1.05; }
.temp { display: flex; align-items: center; gap: 12px; }
.rb { width: 44px; height: 44px; border-radius: var(--radius-btn); border: 1px solid var(--border); background: var(--zone); font-size: 20px; color: var(--text); cursor: pointer; }
/* Renglón de 1: con el de la letra, el número pedía 60 px de alto y el renglón de prender era lo
   más alto de la tarjeta apagada. Así lo marcan los botones de al lado. */
.tval { font-family: var(--fuente-tecnica); font-weight: 500; font-size: 40px; line-height: 1; letter-spacing: 0.02em; }
.tval small { font-size: 18px; vertical-align: top; }
.chips { display: flex; gap: 5px; }
/* 44 de alto, el mínimo de toque de la app (Design system): todos los chips, en todas las pestañas. */
.chip { flex: 1; min-height: 44px; text-align: center; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; padding: 8px 4px; border-radius: var(--radius-btn); border: 1px solid var(--border); background: transparent; color: var(--muted); cursor: pointer; }
.chip.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
/* Dora: la potencia y el agua elegidas, en contorno de brasa y con la letra en --text, como el modo de un aire apagado;
   rellenas solo mientras limpia (aspiradora.js, vacChips; Design system, 25/09/2026). */
.chips.en-contorno .chip.on { background: transparent; color: var(--text); border-color: var(--accent); }
#vf-rooms .chip { flex: 0 0 auto; padding: 8px 12px; }
/* Las tarjetas de aire van con el mismo margen lateral que el resto del panel. Sin esto
   colgaban del borde y el titulo quedaba desalineado con ellas. */
.zone-cuerpo { padding: 0 14px 12px; }
/* Los chips de la aleta llevan dibujo en vez de texto: el angulo se lee de un vistazo y
   ademas entra, cosa que "Medio arriba" no hacia. */
.chip-dibujo { padding: 5px 2px 3px; }
.chip-dibujo svg { display: block; margin: 0 auto; }
/* La primera fila lleva la temperatura a la izquierda y el interruptor a la derecha. Van
   metidos unos pixeles hacia adentro: pegados a los bordes, el hueco del medio quedaba
   incomodo, como si los dos se estuvieran escapando de la tarjeta. */
.acrow { padding: 0 7px; }
/* Lo de abajo del renglón de prender: solo con el aire prendido, y se abre deslizándose (acs.js).
   flow-root para que el respiro de arriba quede adentro y se deslice con lo demás. */
.acmas { display: flow-root; }
.acmas > :first-child { margin-top: 10px; }
/* Cada cosa distinta del aire --modos, velocidad, aleta, extras-- es un grupo, con un respiro
   chico entre grupos. Adentro las filas van pegadas: sin eso, y sin titulos, las cinco filas de
   dibujos se leian como un jeroglifico de una sola pieza. */
.acgrupo + .acgrupo { margin-top: 12px; }
/* La lucecita comparte fila con dormir y turbo pero no es del grupo: esos tres se excluyen
   entre si y ella se prende aparte. El hueco lo dice sin escribirlo. */
.chip-aparte { margin-left: 12px; }
.acgrupo .chips + .chips { margin-top: 4px; }
/* «LO DEMÁS» (acs.js): un renglón con el borde de los chips, del ancho de la tarjeta, que abre la aleta y los extras
   (Ux/Ui, docs/planes/2026-09-24-aires-mas.md). A la derecha, lo que está puesto adentro; abierto, sin dibujitos. */
.acmas-boton { display: flex; align-items: center; gap: 8px; width: 100%; padding: 0 12px; }
.acmas-flecha { display: block; width: 12px; height: 12px; transition: transform 150ms ease-out; }
.acmas-boton[aria-expanded="true"] .acmas-flecha { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .acmas-flecha { transition: none; } }
.acmas-resumen { display: flex; align-items: center; gap: 8px; margin-left: auto; color: var(--muted); }
.acmas-resumen svg { display: block; width: 18px; height: 18px; }
.acmas-boton[aria-expanded="true"] .acmas-resumen { display: none; }
/* «Agregar regla» (automations.js): el mismo renglón, con el formulario abajo cuando se abre. */
.agregar-boton { flex: none; }
.agregar-boton[aria-expanded="true"] { margin-bottom: 8px; }
/* flow-root, como .acmas: el respiro de arriba queda adentro y se desliza con lo demás. */
.acmas-extra { display: flow-root; }
.acmas-extra[hidden] { display: none; }
.acmas-extra > :first-child { margin-top: 12px; }
.actimer { border-top: 1px solid var(--card-border); margin-top: 13px; padding-top: 11px; }
.actimer-on { display: flex; align-items: center; justify-content: space-between; gap: 8px; background: var(--accent-tint); border: 1px solid var(--accent-tint-border); border-radius: var(--radius-btn); padding: 8px 11px; font-size: 12.5px; }
.actimer-on b { font-family: var(--fuente-tecnica); font-variant-numeric: tabular-nums; }
.actimer-por { color: var(--muted); }
/* La cruz se dibuja chica pero se toca en 44: los márgenes negativos la meten en el renglón sin
   agrandar la franja. */
.actimer-x { background: none; border: none; color: var(--muted); font-size: 15px; cursor: pointer; width: 44px; height: 44px; padding: 0; margin: -12px -11px -12px 0; flex: none; }

/* ── Dora ────────────────────────────────────────────────────────────── */
/* Tres tarjetas: Dora (estado, mandos y mapa), Cómo limpia y Mantenimiento. En el teléfono van
   una abajo de la otra; en una pantalla ancha el mapa se queda con la columna grande y las
   otras dos se apilan al costado, que es donde se miran de reojo. */
.vgrid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; align-items: start; }
@media (min-width: 900px) {
  .vgrid { grid-template-columns: minmax(0, 1.7fr) minmax(300px, 1fr); }
  .vcard-dora { grid-row: span 2; }
}
.vcard-cuerpo { padding: 0 14px 14px; }
.vcard-dora .vcard-cuerpo { padding-top: 14px; }
.vcard .lbl:first-child { margin-top: 0; }

.vac-robot { display: flex; align-items: center; gap: 12px; }
.vac-quien { flex: 1; min-width: 0; }
.vac-name { font-family: var(--fuente-nombre); font-size: 19px; line-height: 1.05; }
.vac-state { font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-top: 2px; }
.vac-state.anda { color: var(--accent); }
.vac-batt { text-align: right; flex: none; }
.vac-batt .pct { font-family: var(--fuente-tecnica); font-weight: 500; font-size: 18px; letter-spacing: 0.04em; }
.vac-batt .sub, .vsub { font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.vac-rayo { display: inline-block; vertical-align: -1px; margin-right: 4px; }

/* Todos los botones de la pestaña miden lo mismo de alto: 44, el mínimo de toque de la app. */
.vac-acts { display: flex; gap: 7px; margin-top: 12px; }
.vac-acts button, .vac-lavar { flex: 1 1 0; min-width: 0; min-height: 44px; padding: 9px 8px;
  font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vac-mandos .terminar { flex: 2 1 0; }
.chips.de-a-dos { flex-wrap: wrap; }
.chips.de-a-dos .chip { flex: 1 1 calc(50% - 3px); white-space: normal; line-height: 1.25; }
.vac-acts button:disabled, .vac-lavar:disabled { opacity: 0.4; cursor: default; transform: none; }
/* Mandar lleva el doble de ancho que marcar zona: es lo que se aprieta. */
.vac-mandar .primary { flex: 2 1 0; width: auto; padding: 9px 12px; font-size: 12px; }
.vac-lavar { display: block; width: 100%; }

.vac-alerta { display: flex; align-items: center; gap: 8px; background: var(--danger-tint); border: 1px solid var(--danger-tint-border); color: var(--danger); border-radius: var(--radius-btn); padding: 8px 11px; font-size: 12.5px; margin-top: 12px; }
/* Se dibuja chico, pero se toca en 44: los márgenes negativos no agrandan la franja roja. */
.vac-alerta-ok { margin: -8px -6px -8px auto; flex: none; min-height: 44px; padding: 5px 11px; font-size: 12px; }
/* Un aviso no es una falla: no hay nada que aceptar, hay algo que ir a hacer. Por eso no
   lleva el rojo de alarma ni un boton al lado, pero va igual de arriba. */
.vac-aviso { background: var(--zone); border: 1px solid var(--card-border); color: var(--text); border-radius: var(--radius-btn); padding: 8px 11px; font-size: 12.5px; margin-top: 8px; line-height: 1.35; }
.vac-nota { margin-top: 8px; }

/* Mientras se marca una zona, las pastillas no se tocan: el dedo está dibujando. */
.vmapa.dibujando .vpieza { opacity: 0.45; }

/* Un repuesto por renglón: la barra a la izquierda y su reset a la derecha. */
.vlife { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-top: 1px solid var(--card-border); }
.lbl + .vlife { border-top: 0; padding-top: 2px; }
.vlife-info { flex: 1; min-width: 0; }
.vlife-top { display: flex; justify-content: space-between; gap: 8px; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-bottom: 5px; }
.vlife-top .low { color: var(--danger); font-weight: 600; }
.vlife-bar { height: 6px; background: var(--track); border-radius: 2px; overflow: hidden; }
.vlife-bar > span { display: block; height: 100%; background: var(--accent); }
.vlife-bar > span.low { background: var(--danger); }
/* Ancho fijo: al armarse dice "¿Seguro?", y si cambiara de ancho la barra de al lado bailaría. */
.vlife-reset { flex: none; width: 84px; min-height: 44px; padding: 6px 4px; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }
.vlife-reset.armado { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

/* ── teles ───────────────────────────────────────────────────────────── */
/* Una tarjeta por tele, con los mismos márgenes y botones que las de Dora. Apagada es solo el
   nombre y el interruptor: el resto no hace nada con la tele apagada. */
.tvtop { display: flex; align-items: center; gap: 12px; padding: 13px 14px; }
.tvquien { flex: 1; min-width: 0; }
.tvquien .zone-name { font-size: 19px; line-height: 1.05; }
.tvstate { font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-top: 3px; }
.tvstate.prendida { color: var(--accent); }
.tvcard .tg:disabled { opacity: 0.45; cursor: default; transform: none; }
.tvaviso { color: var(--danger); font-size: 12.5px; line-height: 1.35; padding: 0 14px 12px; margin-top: -4px; }
/* «Se apaga a las 01:15 · lo puso Rancho» (Tele olvidada): la franja del temporizador del aire, pegada al
   renglón de estado y con el margen de la tarjeta. */
.tvcuenta { padding: 0 14px 12px; margin-top: -4px; }
.tvcuerpo { padding: 0 14px 14px; }

.tvfila { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }
.tvfila + .tvfila { margin-top: 7px; }
.tvfila button { min-height: 44px; padding: 9px 6px; font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tvfila button.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.tvfila .tvglifo { font-family: var(--fuente-ui); font-size: 16px; letter-spacing: 0; line-height: 1; }
.tvcuerpo .lbl { margin: 14px 0 6px; }

/* Las apps: cuadraditos oscuros con el logo en blanco (la B de Lucas, 24/09/2026; los logos en
   marcas.js), seis por fila en el teléfono. Se reconocen por la forma: el único color de la fila
   es el anillo de la brasa de la que está puesta. */
.tvapps { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 6px; }
.tvapp { aspect-ratio: 1; min-width: 0; padding: 0; display: flex; align-items: center; justify-content: center;
  background: var(--zone); color: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-btn); overflow: hidden; }
.tvapp.marca { color: var(--text); }
/* El logo, del tamaño de su forma (Ux/Ui, 24/09/2026, con la medida de Calidad), en el cuadradito de 46 del
   teléfono: los símbolos adentro de 22 × 22; un círculo lleno a 24, que a 22 se ve más chico que un cuadrado;
   y las palabras adentro de 30 × 16. El dibujo es la caja justa de la tinta (marcas.js), y entra sin estirarse. */
.tvapp .logo, .tvapp img { width: 47.8%; height: 47.8%; }
.tvapp.forma-circulo .logo, .tvapp.forma-circulo img { width: 52.2%; height: 52.2%; }
.tvapp.forma-palabra .logo, .tvapp.forma-palabra img { width: 65.2%; height: 34.8%; }
.tvapp .logo { fill: currentColor; }
.tvapp img { display: block; object-fit: contain; pointer-events: none;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
/* Las que no tienen logo llevan el nombre, chiquito y en dos renglones si hace falta. */
.tvapp span { padding: 0 3px; font-family: var(--fuente-tecnica); font-size: 9.5px; font-weight: 600; letter-spacing: 0.03em;
  text-transform: uppercase; line-height: 1.05; text-align: center; overflow-wrap: anywhere; }
.tvapp.on { box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--accent); }
.tvapp:not(.marca).on { color: var(--text); }

/* Las entradas, con su nombre, en grilla pareja: con la fila que envuelve sola quedaban de
   anchos distintos y el ojo no encontraba nada. */
.tvfuentes { display: grid; grid-template-columns: repeat(auto-fill, minmax(98px, 1fr)); gap: 6px; }
.tvfuentes .chip { padding: 8px 6px; min-width: 0; }
.tvfuentes .chip span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.tvcartelito { width: 100%; min-height: 44px; margin-top: 14px; font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; }

/* ── Luces (luces.js) ─────────────────────────────────────────────────
   El diseño de Ux/Ui (docs/planes/2026-09-24-luces.md), aprobado por Design system: una baldosa de 84 por luz, en dos
   columnas. Apagada, como las tarjetas; prendida, con el tinte de brasa y, si regula, la raya de 4 px hasta su nivel. */
.luces-demo { margin: 0 0 12px; font-size: 14px; line-height: 1.45; color: var(--muted); }
.luces-grilla { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.luz {
  position: relative; display: flex; flex-direction: column; justify-content: space-between; gap: 6px;
  min-height: 84px; padding: 11px 13px 14px; text-align: left; overflow: hidden;
  background: var(--card); border: 1px solid var(--card-border); border-radius: var(--radius-zone);
  touch-action: pan-y; user-select: none; -webkit-user-select: none; transition: background .2s ease, border-color .2s ease;
}
/* Lo que se arrastra no se hunde (Design system): la baldosa también es un deslizador, y uno que se achica bajo el dedo
   tiembla. La respuesta al toque es el cambio de estado. */
.luz:active { transform: none; }
.luz-cab { display: flex; align-items: center; gap: 7px; min-width: 0; }
.luz .zone-marca { background: var(--track); transition: background .2s ease; }
.luz-amb { font: 500 12px/1 var(--fuente-tecnica); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.luz-nombre { display: block; font-size: 17px; line-height: 1.25; color: var(--text); }
/* El estado lo escribe data-estado: el texto de la baldosa no cambia, y así falla.js la encuentra. */
.luz-estado { display: block; margin-top: 1px; font-size: 12.5px; line-height: 1.3; color: var(--muted); font-variant-numeric: tabular-nums; }
.luz-estado::after { content: attr(data-estado); }
.luz.on .luz-estado { color: var(--text); }
.luz-raya { position: absolute; left: 0; bottom: 0; height: 4px; width: var(--nivel, 0%); background: var(--accent); transition: width .12s ease; }
.luz.arrastrando .luz-raya { transition: none; }
.luz.on { background: var(--accent-tint); border-color: var(--accent-tint-border); }
.luz.on .zone-marca { background: var(--accent); }
.luz:not(.on) .luz-raya { display: none; }
/* La que no contesta, o la casa en el corte: en gris, sin relleno ni brasa. Tocarla guarda la orden (falla.js). */
.luz.corte { background: var(--card); border-color: var(--card-border); }
.luz.corte .zone-marca { background: var(--track); }
.luces-bloque { display: flex; align-items: center; gap: 12px; margin: 32px 0 10px; }
.luces-bloque[hidden] { display: none; }
.luces-bloque h3 { margin: 0; font: 500 12px/1 var(--fuente-tecnica); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.luces-bloque button { margin-left: auto; min-height: 44px; font: 500 12px/1 var(--fuente-tecnica); letter-spacing: .1em; text-transform: uppercase; }
#luces-apagar:disabled { color: var(--muted); cursor: default; transform: none; }
@media (prefers-reduced-motion: reduce) { .luz, .luz-raya, .luz .zone-marca { transition: none; } }

/* ── la banda de la ficha, al pie ────────────────────────────────────── */
.ficha-banda {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--text); color: var(--bg); border-radius: var(--radius-btn);
  padding: 9px 14px; margin-top: 26px;
  font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
}

/* ── teléfono ────────────────────────────────────────────────────────── */
@media (max-width: 600px) {
  /* El gap de 6 sostiene el toque de las pestañas (.tab::before): las zonas de las dos filas ocupan 2 + 2 px
     y quedan 2 libres. Si baja de 4, se pisan, y un toque en la costura va a la pestaña equivocada sin que
     nada avise (Design system). */
  .tabnav { flex-wrap: wrap; gap: 6px; }
  .tabnav .tabs-auto { flex: 1 1 calc(50% - 3px); }
  .tabnav > .tabs:not(.tabs-auto) { flex: 1 1 100%; order: 3; }
  .tabnav > .tabs-auto:first-child { order: 1; }
  .tabnav > .tabs-auto:last-child { order: 2; }
  /* Las dos barras con la misma letra y el mismo margen: con TELES, Automatizaciones tiene cuatro y ASPIRADORA
     no entraba (Ux/Ui, rutinas-a-la-vista.md, sección 6). */
  .tab, .seg button { font-size: 12.5px; padding: 8px 4px; }
  .auto-cols, .zcols { grid-template-columns: 1fr; }
  .ficha-banda { font-size: 10px; letter-spacing: 0.08em; }
}

/* ── Cocina: la lista de compras y el recetario (cocina.js) ─────────────────────────────────
   El diseño es de Ux/Ui (docs/planes/2026-09-23-cocina.md). Todo lo que se toca mide 44 o más. */
.hoy-cocina { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 14px;
  text-align: left; color: var(--text); font: inherit; cursor: pointer; }
.hoy-cocina:hover { border-color: var(--accent); }
.hoy-cocina .zone-marca { background: var(--track); }
.hoy-cocina-txt { font-size: 15px; }
/* «Aparatos», al final de Inicio (Ux/Ui, docs/planes/2026-09-24-alta-de-aparatos.md): el renglón como el de LISTA, y
   al tocarlo, la tarjeta con los aparatos, el código y SUMAR UN APARATO. */
.aparatos { margin-top: 14px; }
.aparatos-fila { width: 100%; }
.aparatos-tarjeta { margin-top: 8px; padding: 6px 14px 14px; }
.aparato { display: flex; align-items: center; gap: 10px; min-height: 56px; border-bottom: 1px solid var(--card-border); }
.aparato-textos { flex: 1; min-width: 0; }
.aparato-nombre { font-size: 16px; }
.aparato-desde { font-size: 13px; color: var(--muted); margin-top: 2px; }
.aparato-listo { margin: 12px 0 0; font-size: 15px; }
.aparato-codigo { margin-top: 14px; }
.aparato-cifras { font-family: var(--fuente-tecnica); font-weight: 600; font-size: 48px; line-height: 1; letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums; }
.aparato-codigo.vencido .aparato-cifras { color: var(--muted); text-decoration: line-through; }
.aparato-ayuda, .aparato-vence { margin: 8px 0 0; font-size: 15px; }
.aparato-vence { color: var(--muted); font-variant-numeric: tabular-nums; }
.aparatos-sumar { width: 100%; min-height: 44px; margin-top: 14px; background: transparent; color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius-btn); font-family: var(--fuente-tecnica); font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; cursor: pointer; }
.hoy-cocina .lbl { margin: 0; }
/* El detalle de Aires y de Teles, un aparato por renglón (Ux/Ui): cada uno entero en el suyo. */
.hoy-detalle.lista { display: block; }
.hoy-renglon { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.cocina { display: flex; flex-direction: column; gap: 12px; }
@media (min-width: 1000px) {
  /* En la pantalla grande, la lista a la izquierda y la receta a la derecha. */
  .cocina { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
}
.cocina-lista, .cocina-recetario { padding: 12px 14px 14px; }
.cocina-cab { display: flex; align-items: center; gap: 8px; min-height: 28px; margin-bottom: 10px; }
.cocina-titulo { font-family: var(--fuente-nombre); font-size: 20px; line-height: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cocina-cuenta { margin-left: auto; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.12em; color: var(--muted); }

.cocina-sumar { display: flex; gap: 8px; align-items: center; }
.cocina-input {
  flex: 1; min-width: 0; height: 44px; padding: 0 12px; font: inherit; font-size: 16px; color: var(--text);
  background: var(--zone); border: 1px solid var(--border); border-radius: 6px;
}
.cocina-input::placeholder { color: var(--muted); }
.cocina-input:focus { outline: none; border-color: var(--accent); }
.cocina-mic {
  flex: none; width: 44px; height: 44px; border-radius: 50%; border: none; padding: 0; cursor: pointer;
  background: var(--accent); color: var(--on-accent); display: inline-flex; align-items: center; justify-content: center;
}
.cocina-dijo { margin: 8px 0 0; font-size: 14px; color: var(--muted); }
.cocina-vacia { margin: 14px 0 4px; font-size: 15px; color: var(--muted); }

.cocina-grupo { margin-top: 14px; }
.cocina-rotulo { font-family: var(--fuente-tecnica); font-weight: 500; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--muted); margin: 14px 0 4px; }
.cocina-grupo .cocina-rotulo { margin-top: 0; }
.cocina-rotulo-doble { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.cocina-rotulo-nota { color: var(--muted); }
.cocina-cosa {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 44px; padding: 0 2px; cursor: pointer;
  background: none; border: none; border-top: 1px solid var(--card-border); color: var(--text); font: inherit; text-align: left;
}
.cocina-caja {
  flex: none; width: 22px; height: 22px; border: 1px solid var(--border); border-radius: 4px;
  display: inline-flex; align-items: center; justify-content: center; color: var(--text);
}
.cocina-texto { font-size: 15px; line-height: 1.3; }
/* Tachado: todo a --muted y sin acento, porque en el súper la mirada va a lo que falta (Design system). */
.cocina-cosa.tachada .cocina-caja { color: var(--muted); }
.cocina-cosa.tachada .cocina-texto { color: var(--muted); text-decoration: line-through; }
/* La que se está sumando (cocina.js): se ve enseguida, tal cual se escribió; solo la caja espera, apagada,
   hasta que el Worker la guarda y se puede tachar. El color, explícito: un botón deshabilitado sale gris. */
.cocina-cosa.sumando { cursor: default; color: var(--text); }
.cocina-cosa.sumando .cocina-caja { opacity: .4; }

.cocina-pie { display: flex; gap: 10px; margin-top: 16px; }
.cocina-boton {
  flex: 1; min-height: 48px; padding: 0 12px; border-radius: var(--radius-btn); cursor: pointer; font: inherit;
  font-family: var(--fuente-tecnica); font-weight: 500; font-size: 12.5px; letter-spacing: 0.1em; text-transform: uppercase;
  background: none; border: 1px solid var(--border); color: var(--text);
}
.cocina-boton:disabled { opacity: .45; cursor: default; }
.cocina-mandar { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.cocina-mandar.mandada { background: none; color: var(--accent); cursor: default; }
.cocina-aquien { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.cocina-aquien-q { font-size: 15px; color: var(--muted); }

.cocina-receta {
  display: flex; align-items: center; width: 100%; min-height: 44px; padding: 0 2px; cursor: pointer; font: inherit; font-size: 15px;
  background: none; border: none; border-top: 1px solid var(--card-border); color: var(--text); text-align: left;
}
/* Las favoritas de Lucas, primero y con la estrella (el gerente, 24/09/2026). */
.cocina-receta.favorita::before { content: '★'; flex: none; margin-right: 8px; font-size: 13px; color: var(--accent); }
.cocina-volver {
  flex: none; margin-left: auto; min-height: 44px; padding: 0 12px; cursor: pointer; background: none; border: 1px solid var(--border);
  border-radius: var(--radius-btn); color: var(--text); font-family: var(--fuente-tecnica); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase;
}
.cocina-ingrediente.marcado .cocina-caja { border-color: var(--text); }
.cocina-faltantes { width: 100%; margin-top: 10px; flex: none; }
/* El número de cada paso, en la letra técnica, en --muted y en una columna de 22, como en la tarjeta del atajo
   (.tj-num en tarjeta.css): un número que ordena va en la letra técnica (Design system, 24/09/2026). */
.cocina-pasos { margin: 0; padding: 0; list-style: none; counter-reset: paso; }
.cocina-pasos li { display: flex; align-items: baseline; font-size: 16px; line-height: 1.45; padding: 6px 0; border-top: 1px solid var(--card-border);
  counter-increment: paso; }
.cocina-pasos li::before {
  content: counter(paso); flex: none; width: 22px; font-family: var(--fuente-tecnica); font-weight: 600; font-size: 15px;
  color: var(--muted); font-variant-numeric: tabular-nums;
}
/* El consejo (Ux/Ui, docs/planes/2026-09-23-cocina.md): fuera de la lista, con el texto de un paso, sin número, y
   alineado con el texto de los pasos. La raya, entera como la de los pasos. */
.cocina-consejos p { margin: 0; font-size: 16px; line-height: 1.45; padding: 6px 0 6px 22px; border-top: 1px solid var(--card-border); }

/* El aviso de un renglón con «Deshacer»: el mismo lugar y la misma forma que la franja de fallas,
   con el borde de siempre en vez del rojo. */
.franja-deshacer { border-color: var(--border); padding-right: 6px; }
.ff-deshacer {
  flex: none; min-height: 44px; padding: 0 12px; background: none; border: none; cursor: pointer; color: var(--accent);
  font-family: var(--fuente-tecnica); font-weight: 500; font-size: 12.5px; letter-spacing: 0.1em; text-transform: uppercase;
}

/* ── RanchoBot (robot.js): la pestaña (Ux/Ui, docs/planes/2026-10-04-ranchobot-revision-pestana.md) ──
   En el celu, una columna: la cámara y el estado arriba; abajo, la palanca a la izquierda y Parar (o Liberar) a la derecha, todo
   a la vista sin bajar. En la compu (700 px o más), dos columnas: la cámara a la izquierda (2/3) y los controles a la derecha. */
.rbot { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.rb-falla, .rb-aviso-fila { grid-column: 1 / -1; margin: 0; }
.rb-falla-sub { display: block; color: var(--muted); font-size: 13px; margin-top: 2px; }
.rb-izq { min-width: 0; }
.rb-chips { display: flex; gap: 6px; margin-bottom: 8px; }
.rb-chip { font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
  border: 1px solid var(--border); border-radius: var(--radius-btn); padding: 4px 9px; }
.rb-chip.roja { color: var(--danger); border-color: var(--danger); }
/* La cámara: siempre 16:9, con foto o sin ella, así lo que llega tarde no empuja nada. */
.rb-camara { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-btn); border: 1px solid var(--border);
  overflow: hidden; background: var(--card); }
.rb-camara-img { display: none; width: 100%; height: 100%; object-fit: cover; }
.rb-camara.con-foto .rb-camara-img { display: block; }
.rb-camara.vieja .rb-camara-img { opacity: 0.45; }
.rb-camara-capa { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  padding: 10px; text-align: center; color: var(--muted); pointer-events: none; }
.rb-capa-valor { color: var(--text); font-size: 17px; }
.rb-capa-detalle { font-size: 13px; }
.rb-camara-chip { position: absolute; top: 8px; right: 8px; font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text); background: rgba(0, 0, 0, 0.55); border-radius: var(--radius-btn); padding: 3px 8px; }
.rb-camara-chip:empty { display: none; }
.rb-camara.vieja .rb-camara-chip { color: var(--muted); }
/* El renglón de estado, en la letra técnica: la palabra en luz, el detalle en gris, lo que sí se puede a la derecha. */
.rb-estado { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; margin-top: 10px; font-family: var(--fuente-tecnica); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; }
.rb-valor { color: var(--text); }
.rb-detalle, .rb-puede { color: var(--muted); }
.rb-puede { margin-left: auto; }
/* Los controles: al lado uno del otro en el celu. */
.rb-der { display: flex; align-items: flex-start; gap: 14px; min-width: 0; }
.rb-palanca-caja { flex: none; text-align: center; }
.rb-palanca { position: relative; width: 168px; height: 168px; border-radius: 50%; border: 1px solid var(--border); background: var(--card);
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.rb-palanca.apagada { opacity: 0.4; pointer-events: none; }
/* La perilla es lo que se toca: sólida, en luz (Design system). */
.rb-perilla { position: absolute; left: 50%; top: 50%; width: 64px; height: 64px; margin: -32px 0 0 -32px; border-radius: 50%;
  background: var(--text); transition: transform 150ms ease-out; pointer-events: none; }
.rb-sub { margin-top: 6px; color: var(--muted); font-family: var(--fuente-tecnica); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }
.rb-botones { flex: 1 1 0; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.rb-grande { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; width: 100%; min-height: 98px; border-radius: var(--radius-btn); cursor: pointer;
  font-family: var(--fuente-tecnica); font-size: 14px; letter-spacing: 0.12em; text-transform: uppercase; }
/* Parar va lleno en luz solo mientras el robot se mueve; quieto, como una tarjeta (Design system, 30/09). */
.rb-parar { background: var(--card); border: 1px solid var(--border); color: var(--text); }
.rb-parar.andando { background: var(--text); border-color: var(--text); color: var(--bg); }
.rb-parar-sub { font-size: 11px; letter-spacing: 0.08em; opacity: 0.7; }
/* Liberar ocupa el lugar de Parar: lo único que hay que apretar, en brasa. */
.rb-liberar-boton { background: var(--accent); border: 1px solid var(--accent); color: var(--on-accent); }
.rb-nm { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 4px; }
.rb-nm-txt { color: var(--muted); font-size: 13px; }
.rb-nm-boton { min-height: 44px; padding: 8px 16px; border-radius: var(--radius-btn); border: 1px solid var(--border); background: transparent; color: var(--text);
  font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; cursor: pointer; }
.rb-aviso { grid-column: 1 / -1; min-height: 20px; color: var(--muted); font-size: 14px; }
/* La hoja de la clave: sube desde abajo, encima del teclado. */
.rb-hoja { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; display: flex; flex-direction: column; gap: 10px; padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
  background: var(--card); border-top: 1px solid var(--border); box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.4); }
.rb-clave { min-height: 44px; padding: 8px 12px; border-radius: var(--radius-btn); border: 1px solid var(--border); background: transparent; color: var(--text); font-size: 16px; }
.rb-hoja-aviso { min-height: 18px; color: var(--danger); font-size: 14px; }
.rb-hoja-botones { display: flex; gap: 8px; }
.rb-hoja-botones button { flex: 1 1 0; min-height: 44px; border-radius: var(--radius-btn); cursor: pointer; font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; }
.rb-hoja-cancelar { background: transparent; border: 1px solid var(--border); color: var(--text); }
.rb-hoja-liberar { background: var(--accent); border: 1px solid var(--accent); color: var(--on-accent); }
@media (min-width: 700px) {
  .rbot { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; }
  .rb-der { flex-direction: column; align-items: stretch; }
  .rb-palanca-caja { align-self: center; }
}
@media (prefers-reduced-motion: reduce) { .rb-perilla { transition: none; } }
/* Tocar el piso: la marca sobre la foto (rellena con el tinte de brasa mientras va; en contorno al llegar; un aro con cruz si no va). */
.rb-camara { cursor: default; }
.rb-camara.con-foto { cursor: crosshair; }
.rb-marca { position: absolute; width: 26px; height: 26px; border-radius: 50%; transform: translate(-50%, -50%); pointer-events: none; display: none;
  border: 2px solid var(--accent); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6); }
.rb-marca.yendo { display: block; background: rgba(224, 138, 36, 0.45); }
.rb-marca.llego, .rb-marca.no_llego { display: block; background: transparent; }
.rb-marca.no { display: block; background: transparent; border-color: var(--text); }
.rb-marca.no::before, .rb-marca.no::after { content: ''; position: absolute; left: 50%; top: 50%; width: 14px; height: 2px; background: var(--text); transform: translate(-50%, -50%) rotate(45deg); }
.rb-marca.no::after { transform: translate(-50%, -50%) rotate(-45deg); }
.rb-marca-aviso { position: absolute; left: 8px; bottom: 8px; right: 8px; text-align: center; font-size: 13px; color: var(--text); background: rgba(0, 0, 0, 0.6); border-left: 3px solid var(--accent);
  border-radius: var(--radius-btn); padding: 4px 8px; pointer-events: none; }
.rb-marca-aviso:empty { display: none; }
.rb-consigna { position: absolute; left: 0; right: 0; bottom: 8px; text-align: center; font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text); text-shadow: 0 1px 3px #000; pointer-events: none; }
.hoy-robot-acciones { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; }
.hoy-robot-parar { min-height: 44px; padding: 8px 18px; border-radius: var(--radius-btn); border: 1px solid var(--border); background: transparent; color: var(--text);
  font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; cursor: pointer; }
.hoy-robot-abrir { color: var(--muted); font-family: var(--fuente-tecnica); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none; padding: 12px 4px; }
.rb-camara-chip.atrasada { color: var(--accent); }
.rb-camara-video { display: none; width: 100%; height: 100%; object-fit: cover; background: #000; }
.rb-camara.con-video .rb-camara-video { display: block; }
.rb-camara.con-video .rb-camara-img { display: none; }
